Skip to content
Snippets Groups Projects
Commit f5d1d86b authored by jojohoch's avatar jojohoch
Browse files

[player] Use service to prevent simultaneous media playback

parent 6164ad2b
No related branches found
No related tags found
No related merge requests found
...@@ -8,11 +8,14 @@ import { MediaPlayerElementComponent } from '../media-player-element-component.d ...@@ -8,11 +8,14 @@ import { MediaPlayerElementComponent } from '../media-player-element-component.d
<div [style.width.%]="100" <div [style.width.%]="100"
[style.height.%]="100"> [style.height.%]="100">
<audio #player <audio #player
(playing)="mediaPlay.emit(this.elementModel.id)"
(pause)="mediaPause.emit(this.elementModel.id)"
[style.width.%]="100" [style.width.%]="100"
[src]="elementModel.src | safeResourceUrl"> [src]="elementModel.src | safeResourceUrl">
</audio> </audio>
<app-control-bar [player]="player" <app-control-bar [player]="player"
[elementModel]="elementModel" [elementModel]="elementModel"
[active]="active"
(playbackTimeChanged)="playbackTimeChanged.emit($event)"> (playbackTimeChanged)="playbackTimeChanged.emit($event)">
</app-control-bar> </app-control-bar>
</div> </div>
......
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
<button *ngIf="!playing || !elementModel.pauseControl" <button *ngIf="!playing || !elementModel.pauseControl"
mat-button mat-button
class="control-button" class="control-button"
[class.enabled-control]="!disabled" [class.enabled-control]="!disabled && active"
[class.active-control]="playing" [class.active-control]="playing"
[disabled]="disabled" [disabled]="disabled || !active"
(click)="play($event)"> (click)="play($event)">
<mat-icon>play_arrow</mat-icon> <mat-icon>play_arrow</mat-icon>
</button> </button>
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
<button *ngIf="playing" <button *ngIf="playing"
mat-button mat-button
class="control-button" class="control-button"
[class.enabled-control]="!disabled" [class.enabled-control]="!disabled && active"
[class.active-control]="pausing" [class.active-control]="pausing"
[disabled]="disabled" [disabled]="disabled || !active"
(click)="pause($event)"> (click)="pause($event)">
<mat-icon>pause</mat-icon> <mat-icon>pause</mat-icon>
</button> </button>
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
step="1" step="1"
[max]="player.duration" [max]="player.duration"
[value]="player.currentTime" [value]="player.currentTime"
[disabled]="disabled || !elementModel.interactiveProgressbar" [disabled]="disabled || !elementModel.interactiveProgressbar || !active"
(input)="onTimeChange($event)"> (input)="onTimeChange($event)">
</mat-slider> </mat-slider>
</ng-container> </ng-container>
......
...@@ -14,6 +14,7 @@ import { ValueChangeElement } from '../../models/uI-element'; ...@@ -14,6 +14,7 @@ import { ValueChangeElement } from '../../models/uI-element';
export class ControlBarComponent implements OnInit, AfterContentInit, OnDestroy { export class ControlBarComponent implements OnInit, AfterContentInit, OnDestroy {
@Input() player!: HTMLVideoElement | HTMLAudioElement; @Input() player!: HTMLVideoElement | HTMLAudioElement;
@Input() elementModel!: AudioElement | VideoElement; @Input() elementModel!: AudioElement | VideoElement;
@Input() active!: boolean;
@Output() playbackTimeChanged = new EventEmitter<ValueChangeElement>(); @Output() playbackTimeChanged = new EventEmitter<ValueChangeElement>();
duration!: number; duration!: number;
currentTime!: number; currentTime!: number;
...@@ -141,7 +142,7 @@ export class ControlBarComponent implements OnInit, AfterContentInit, OnDestroy ...@@ -141,7 +142,7 @@ export class ControlBarComponent implements OnInit, AfterContentInit, OnDestroy
private _play(): void { private _play(): void {
this.player.play().then(() => {}, this.player.play().then(() => {},
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
() => console.error('error')); () => console.error('player: cannot play this media file'));
} }
private sendPlaybackTimeChanged() { private sendPlaybackTimeChanged() {
......
...@@ -5,4 +5,12 @@ import { ElementComponent } from './element-component.directive'; ...@@ -5,4 +5,12 @@ import { ElementComponent } from './element-component.directive';
@Directive() @Directive()
export abstract class MediaPlayerElementComponent extends ElementComponent { export abstract class MediaPlayerElementComponent extends ElementComponent {
@Output() playbackTimeChanged = new EventEmitter<ValueChangeElement>(); @Output() playbackTimeChanged = new EventEmitter<ValueChangeElement>();
@Output() mediaPlay = new EventEmitter<string>();
@Output() mediaPause = new EventEmitter<string>();
active: boolean = true;
setActualPlayingMediaId(id: string | null): void {
this.active = !id || id === this.elementModel.id;
}
} }
...@@ -28,6 +28,8 @@ import { VideoElement } from '../../../../../common/models/video-element'; ...@@ -28,6 +28,8 @@ import { VideoElement } from '../../../../../common/models/video-element';
import { AudioElement } from '../../../../../common/models/audio-element'; import { AudioElement } from '../../../../../common/models/audio-element';
import { ImageElement } from '../../../../../common/models/image-element'; import { ImageElement } from '../../../../../common/models/image-element';
import { VeronaPostService } from '../../services/verona-post.service'; import { VeronaPostService } from '../../services/verona-post.service';
import { MediaPlayerElementComponent } from '../../../../../common/media-player-element-component.directive';
import { MediaPlayerService } from '../../services/media-player.service';
@Component({ @Component({
selector: 'app-element-container', selector: 'app-element-container',
...@@ -54,6 +56,7 @@ export class ElementContainerComponent implements OnInit { ...@@ -54,6 +56,7 @@ export class ElementContainerComponent implements OnInit {
private unitStateService: UnitStateService, private unitStateService: UnitStateService,
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
private veronaPostService: VeronaPostService, private veronaPostService: VeronaPostService,
private mediaPlayerService: MediaPlayerService,
private markingService: MarkingService) { private markingService: MarkingService) {
} }
...@@ -98,6 +101,22 @@ export class ElementContainerComponent implements OnInit { ...@@ -98,6 +101,22 @@ export class ElementContainerComponent implements OnInit {
}); });
} }
if (elementComponent.mediaPause) {
elementComponent.mediaPause
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe(() => {
this.mediaPlayerService.broadCastPlayChanges(null);
});
}
if (elementComponent.mediaPlay) {
elementComponent.mediaPlay
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe((playId: string) => {
this.mediaPlayerService.broadCastPlayChanges(playId);
});
}
if (elementComponent.applySelection) { if (elementComponent.applySelection) {
elementComponent.applySelection elementComponent.applySelection
.pipe(takeUntil(this.ngUnsubscribe)) .pipe(takeUntil(this.ngUnsubscribe))
...@@ -181,6 +200,8 @@ export class ElementContainerComponent implements OnInit { ...@@ -181,6 +200,8 @@ export class ElementContainerComponent implements OnInit {
formGroup: elementForm formGroup: elementForm
}); });
}); });
} else if (elementComponent instanceof MediaPlayerElementComponent) {
this.mediaPlayerService.registerMediaElement(elementComponent);
} }
} }
......
import { Injectable } from '@angular/core';
import { MediaPlayerElementComponent } from '../../../../common/media-player-element-component.directive';
@Injectable({
providedIn: 'root'
})
export class MediaPlayerService {
mediaElements: MediaPlayerElementComponent[] = [];
registerMediaElement(mediaElement: MediaPlayerElementComponent): void {
this.mediaElements.push(mediaElement);
}
broadCastPlayChanges(actualId: string | null): void {
this.mediaElements.forEach(mediaElement => mediaElement.setActualPlayingMediaId(actualId));
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment