Update video source in Videogular2
I am trying to update a video source and then play it back. I am using Videogular2 in an Ionic 2 (Angular 2) app.
Expected behavior
I would expect the video source to be changed and after loading it will start playing.
Actual behavior
The video source with success changes (I can see it in the developer tools / DOM for Chrome) and poster image changes. However, the video does not play. I am using vg-overlay-play
which, when clicked / tapped, does not play the video. If I change my code to include native controls
on video
, then I can force the video to play manually using these controls.
Html
<ion-header>
<ion-navbar>
<ion-title>{{ selectedClass.name }}</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<vg-player vg-responsive="true" vg-plays-inline="true" (onPlayerReady)="onPlayerReady($event)">
<vg-overlay-play [vgFor]="singleVideo"></vg-overlay-play>
<vg-buffering></vg-buffering>
<vg-controls>
<vg-time-display [vgFor]="singleVideo" [vgProperty]="'left'" [vgFormat]="'mm:ss'"></vg-time-display>
<vg-scrub-bar [vgFor]="singleVideo">
<!-- more components here -->
</vg-scrub-bar>
</vg-controls>
<video [vgMedia]="media" #media
id="singleVideo"
preload="auto"
type="video/mp4"
webkit-playsinline
playsinline>
<source *ngFor="let video of sources" [src]="video.src" [type]="video.type">
</video>
</vg-player>
</ion-content>
Typescript
import { Component } from '@angular/core';
import { Content, NavController, NavParams } from 'ionic-angular';
import { VgAPI } from 'videogular2/core';
import { VgCoreModule } from 'videogular2/core';
import { VgControlsModule } from 'videogular2/controls';
import { VgOverlayPlayModule } from 'videogular2/overlay-play';
import { VgBufferingModule } from 'videogular2/buffering';
@Component({
selector: 'page-class-video',
templateUrl: 'class_video.html'
})
export class ClassVideoPage {
selectedClass: any;
playlist: any;
currentVideo: any = 0;
currentVideoURL: any;
totalVideos: any;
classEnded: boolean = false;
api: any;
sources : Array<Object>;
constructor() {
this.selectedClass = navParams.get('class');
this.playlist = this.selectedClass.videos;
this.totalVideos = this.selectedClass.videos.length;
this.sources = new Array<Object>();
this.sources.push({
src: this.selectedClass.videos[0].video_s3,
type: "video/mp4"
});
}
// Load API when video is ready
onPlayerReady(api: VgAPI) {
this.api = api;
// Listen for end of video
this.api.getDefaultMedia().subscriptions.ended.subscribe(() => {
this.currentVideo++;
if(this.currentVideo == this.totalVideos) {
this.classEnded = true;
} else {
this.setCurrentVideo(this.playlist[this.currentVideo].video_s3);
this.onPlayerReady(this.api);
this.api.play(); // Rarely works as it fires before video has loaded
}
});
// Play video automatically
this.api.getDefaultMedia().subscriptions.canPlayThrough.subscribe(() => {
this.api.play();
});
this.api.getDefaultMedia().subscriptions.loadedData.subscribe(() => {
this.api.play();
});
}
setCurrentVideo(source: string){
this.sources = new Array<Object>();
this.sources.push({
src: source,
type: "video/mp4"
});
this.api.getDefaultMedia().currentTime = 0;
this.api.play();
}
}
this.selectedClass.videos
is an array of video objects.
I tried binding to src
in a tag video
instead of using it sources
, but I get the same behavior.
source to share
I fixed this by not using the Replay API at all. Instead, I use a custom tag autoplay
that the video game has immediately after it loads, meaning I don't have to start the game myself.
With this, the function vg-overlay-play
works as expected.
I'm not sure why api.play()
the video is causing such pain. It is almost as if it is constantly being called, so any press is vg-overlay-play
instantly canceled on api.play()
.
autoplay
fixed this:
<video [vgMedia]="media" #media
id="singleVideo"
preload="auto"
type="video/mp4"
webkit-playsinline
playsinline
autoplay>
<source *ngFor="let video of sources" [src]="video.src" [type]="video.type">
</video>
source to share