patterntypescriptMinor
Audio player in Angular 2
Viewed 0 times
playeraudioangular
Problem
I just built an audio player in Angular 2 using a player component and a player service. It's all working fine, I just feel like there is a much better way to do this.
Should the audio object be in the service or the component? I'm skeptical because I'm using three different observables and I don't think that is the best way to do it.
player.component.ts:
player.service.ts:
```
export class PlayerService {
private audio: any;
public song: Subject = new Subject();
public currentTime: Subject = new Subject();
public fullTime: Subject = new Subject();
constructor(private _utilityService: UtilityService) {
this.audio = new Audio();
}
setPlayer(song: Song) {
this.song.next(song);
this.audio.src = song.audio;
this.audio.oncanplaythrough = () => {
this.audio.play();
this.fullTime.next(
this._utilityService.getFormatedTime(this.audio.duration)
);
};
this.audi
Should the audio object be in the service or the component? I'm skeptical because I'm using three different observables and I don't think that is the best way to do it.
player.component.ts:
export class PlayerComponent implements OnInit, OnDestroy {
// General variables
private song: Song;
private currentTime: string;
private fullTime: string;
private isPlaying: boolean;
// Subscription variables
private songSubscription: any;
private currentTimeSubscription: any;
private fullTimeSubscription: any;
constructor(private _playerService: PlayerService) {
}
ngOnInit() {
this.songSubscription = this._playerService.song.subscribe(data => this.song = data);
this.currentTimeSubscription = this._playerService.currentTime.subscribe(data => this.currentTime = data);
this.fullTimeSubscription = this._playerService.fullTime.subscribe(data => this.fullTime = data);
console.log("Player subscription initialized");
}
toggleAudio() {
this.isPlaying = this._playerService.toggleAudio();
}
ngOnDestroy() {
this.songSubscription.unsubscribe();
this.currentTimeSubscription.unsubscribe();
this.fullTimeSubscription.unsubscribe();
console.log("Player subscription destroyed");
}
}player.service.ts:
```
export class PlayerService {
private audio: any;
public song: Subject = new Subject();
public currentTime: Subject = new Subject();
public fullTime: Subject = new Subject();
constructor(private _utilityService: UtilityService) {
this.audio = new Audio();
}
setPlayer(song: Song) {
this.song.next(song);
this.audio.src = song.audio;
this.audio.oncanplaythrough = () => {
this.audio.play();
this.fullTime.next(
this._utilityService.getFormatedTime(this.audio.duration)
);
};
this.audi
Solution
There is one way I can think of improving this. In angular2, components should only handle view logic.
The problem isn't there at the moment but could be there when you add more functionalities. Let's say you want to add a recorder for the song that saves the song from time 0 to time 1.
You'd have to add that to this component and keep cluttering it.
I would treat this component as a "master" songPlayer. It operates on a song (i.e. Your song model) so that is okay. It could also operate on the "Player" model. Player has a state. It has its time, knows if it is playing and where the current time is.
Perhaps the best way to structure this would be to start with models:
PlayerModel(time, isPlaying, currentTime, song). Song is as it is. What this does is that it creates only one subscription on your playerComponent. To the Player.
I hope I'm not keeping it too abstract with this. It was just an idea.
The problem isn't there at the moment but could be there when you add more functionalities. Let's say you want to add a recorder for the song that saves the song from time 0 to time 1.
You'd have to add that to this component and keep cluttering it.
I would treat this component as a "master" songPlayer. It operates on a song (i.e. Your song model) so that is okay. It could also operate on the "Player" model. Player has a state. It has its time, knows if it is playing and where the current time is.
Perhaps the best way to structure this would be to start with models:
PlayerModel(time, isPlaying, currentTime, song). Song is as it is. What this does is that it creates only one subscription on your playerComponent. To the Player.
I hope I'm not keeping it too abstract with this. It was just an idea.
Context
StackExchange Code Review Q#144052, answer score: 3
Revisions (0)
No revisions yet.