Merge pull request #5628 from tsiegleauq/vjs-404
catch and refresh unreachable video streams
This commit is contained in:
commit
d4b92a2b4e
@ -1,3 +1,14 @@
|
||||
<div class="video-wrapper">
|
||||
<div class="player-container" [ngClass]="{ hide: !isUrlOnline }">
|
||||
<video #videoPlayer class="video-js" controls preload="none"></video>
|
||||
</div>
|
||||
<div *ngIf="!isUrlOnline" class="is-offline-wrapper">
|
||||
<div>
|
||||
{{ 'No stream available' | translate }}
|
||||
</div>
|
||||
<button mat-raised-button (click)="checkVideoUrl()" color="primary">
|
||||
<span>{{ 'Refresh' | translate }}</span>
|
||||
<mat-icon>refresh</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,17 @@
|
||||
.video-wrapper {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 200px;
|
||||
|
||||
.is-offline-wrapper {
|
||||
width: 100%;
|
||||
margin: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.player-container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
.video-js {
|
||||
margin: auto;
|
||||
|
||||
@ -37,3 +48,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { E2EImportsModule } from 'e2e-imports.module';
|
||||
|
||||
import { VjsPlayerComponent } from './vjs-player.component';
|
||||
|
||||
describe('VjsPlayerComponent', () => {
|
||||
@ -8,7 +10,7 @@ describe('VjsPlayerComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [VjsPlayerComponent]
|
||||
imports: [E2EImportsModule]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -10,6 +10,9 @@ import {
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
|
||||
import { of } from 'rxjs';
|
||||
import { ajax, AjaxResponse } from 'rxjs/ajax';
|
||||
import { catchError, map } from 'rxjs/operators';
|
||||
import videojs from 'video.js';
|
||||
|
||||
import { ConfigService } from 'app/core/ui-services/config.service';
|
||||
@ -32,14 +35,17 @@ enum MimeType {
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class VjsPlayerComponent implements OnInit, OnDestroy {
|
||||
@ViewChild('videoPlayer', { static: true }) private videoPlayer: ElementRef;
|
||||
|
||||
@ViewChild('videoPlayer', { static: true })
|
||||
private videoPlayer: ElementRef;
|
||||
private _videoUrl: string;
|
||||
private posterUrl: string;
|
||||
public player: videojs.Player;
|
||||
public isUrlOnline: boolean;
|
||||
|
||||
@Input()
|
||||
public set videoUrl(value: string) {
|
||||
this._videoUrl = value;
|
||||
this.playVideo();
|
||||
this.checkVideoUrl();
|
||||
}
|
||||
|
||||
@Output()
|
||||
@ -49,8 +55,6 @@ export class VjsPlayerComponent implements OnInit, OnDestroy {
|
||||
return this._videoUrl;
|
||||
}
|
||||
|
||||
public player: videojs.Player;
|
||||
|
||||
private get videoSource(): VideoSource {
|
||||
return {
|
||||
src: this.videoUrl,
|
||||
@ -58,8 +62,6 @@ export class VjsPlayerComponent implements OnInit, OnDestroy {
|
||||
};
|
||||
}
|
||||
|
||||
private posterUrl: string;
|
||||
|
||||
public constructor(config: ConfigService) {
|
||||
config.get<string>('general_system_stream_poster').subscribe(posterUrl => {
|
||||
this.posterUrl = posterUrl;
|
||||
@ -67,14 +69,7 @@ export class VjsPlayerComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
public async ngOnInit(): Promise<void> {
|
||||
this.player = videojs(this.videoPlayer.nativeElement, {
|
||||
textTrackSettings: false,
|
||||
fluid: true,
|
||||
autoplay: 'any',
|
||||
liveui: true,
|
||||
poster: this.posterUrl
|
||||
});
|
||||
this.playVideo();
|
||||
this.initPlayer();
|
||||
}
|
||||
|
||||
public ngOnDestroy(): void {
|
||||
@ -83,12 +78,51 @@ export class VjsPlayerComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
private playVideo(): void {
|
||||
public async checkVideoUrl(): Promise<void> {
|
||||
/**
|
||||
* Using observable would not make sense, because without it would not automatically update
|
||||
* if a Ressource switches from online to offline
|
||||
*/
|
||||
const ajaxResponse: AjaxResponse = await ajax(this.videoUrl)
|
||||
.pipe(
|
||||
map(response => response),
|
||||
catchError(error => {
|
||||
return of(error);
|
||||
})
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
/**
|
||||
* there is no enum for http status codes in the whole Angular stack...
|
||||
*/
|
||||
if (ajaxResponse.status === 200) {
|
||||
this.isUrlOnline = true;
|
||||
this.playVideo();
|
||||
} else {
|
||||
this.isUrlOnline = false;
|
||||
if (this.player) {
|
||||
this.player.pause();
|
||||
}
|
||||
this.player.src('');
|
||||
}
|
||||
}
|
||||
|
||||
private initPlayer(): void {
|
||||
if (!this.player) {
|
||||
this.player = videojs(this.videoPlayer.nativeElement, {
|
||||
textTrackSettings: false,
|
||||
fluid: true,
|
||||
autoplay: 'any',
|
||||
liveui: true,
|
||||
poster: this.posterUrl
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private playVideo(): void {
|
||||
this.player.src(this.videoSource);
|
||||
this.started.next();
|
||||
}
|
||||
}
|
||||
|
||||
private determineContentTypeByUrl(url: string): MimeType {
|
||||
if (url) {
|
||||
|
@ -774,3 +774,10 @@ button.mat-menu-item.selected {
|
||||
height: 0px;
|
||||
width: 0px;
|
||||
}
|
||||
|
||||
/**
|
||||
* simply hide something
|
||||
*/
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user