Skip to content

Commit

Permalink
Merge pull request #256 from videogular/feat/media-sync
Browse files Browse the repository at this point in the history
feat(sync): Add media sync
  • Loading branch information
Elecash authored Oct 23, 2016
2 parents c8abc38 + 9525eca commit 68b2b6b
Show file tree
Hide file tree
Showing 17 changed files with 281 additions and 164 deletions.
14 changes: 8 additions & 6 deletions examples/master-player/src/app.module.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/master-player/src/app.module.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 10 additions & 8 deletions examples/master-player/src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {VgCore} from 'videogular2/core';
import {VgControlsModule} from 'videogular2/controls';
import {MasterMedia} from './master-media';
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { VgCore } from "videogular2/core";
import { VgControlsModule } from "videogular2/controls";
import { MasterMedia } from "./master-media";
import { VgBufferingModule } from "videogular2/buffering";

@NgModule({
imports: [
BrowserModule,
VgCore,
VgControlsModule
VgControlsModule,
VgBufferingModule
],
declarations: [MasterMedia],
bootstrap: [MasterMedia]
declarations: [ MasterMedia ],
bootstrap: [ MasterMedia ]
})
export class AppModule {
}
14 changes: 6 additions & 8 deletions examples/master-player/src/master-media.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<vg-player>
<vg-buffering></vg-buffering>

<vg-controls>
<vg-play-pause></vg-play-pause>

Expand All @@ -18,15 +20,11 @@
</vg-controls>


<video vg-media id="pipVideo" preload="auto" style="width: 30%;">
<source *ngFor="let video of sources" [src]="video.src" [type]="video.type">
<video vg-media vg-master="true" id="masterVideo" preload="auto" style="width: 50%;">
<source *ngFor="let video of master" [src]="video.src" [type]="video.type">
</video>

<video vg-media vg-master="true" id="masterVideo" preload="auto" style="width: 40%;">
<source *ngFor="let video of sources" [src]="video.src" [type]="video.type">
</video>

<video vg-media id="pipVideo2" preload="auto" style="width: 30%;">
<source *ngFor="let video of sources" [src]="video.src" [type]="video.type">
<video vg-media id="pipVideo" preload="auto" style="width: 50%;">
<source *ngFor="let video of slave" [src]="video.src" [type]="video.type">
</video>
</vg-player>
12 changes: 11 additions & 1 deletion examples/master-player/src/master-media.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/master-player/src/master-media.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 14 additions & 2 deletions examples/master-player/src/master-media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,22 @@ import {Component} from "@angular/core";
templateUrl: 'src/master-media.html'
})
export class MasterMedia {
sources:Array<Object>;
master:Array<Object>;
slave:Array<Object>;

constructor() {
this.sources = [
this.master = [
{
src: "http://static.videogular.com/assets/videos/big_buck_bunny_720p_h264.mov",
type: "video/mp4"
},
{
src: "http://static.videogular.com/assets/videos/big_buck_bunny_720p_stereo.ogg",
type: "video/ogg"
}
];

this.slave = [
{
src: "http://static.videogular.com/assets/videos/videogular.mp4",
type: "video/mp4"
Expand Down
10 changes: 4 additions & 6 deletions src/vg-buffering/vg-buffering.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,14 @@ export declare class VgBuffering {
vgFor: string;
target: IPlayable;
checkBufferInterval: number;
displayState: string;
constructor(ref: ElementRef, API: VgAPI);
onPlayerReady(): void;
checkInterval: number;
currentPlayPos: number;
lastPlayPos: number;
bufferingDetected: boolean;
bufferCheck(): void;
startBufferCheck(): void;
stopBufferCheck(): void;
displayState: string;
constructor(ref: ElementRef, API: VgAPI);
onPlayerReady(): void;
onUpdateBuffer(isBuffering: any): void;
show(): void;
hide(): void;
}
68 changes: 11 additions & 57 deletions src/vg-buffering/vg-buffering.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,45 +22,26 @@ describe('Volume control', () => {
});

describe('onPlayerReady', ()=>{
it('should subscribe to play and pause media events', ()=>{
it('should subscribe to bufferDetected media events', ()=>{
spyOn(api, 'getMediaById').and.returnValue({
subscriptions: {
play: {subscribe: jasmine.createSpy('play') },
pause: {subscribe: jasmine.createSpy('pause') }
bufferDetected: {subscribe: jasmine.createSpy('bufferDetected') }
}
});
vgBuffering.onPlayerReady();
expect(vgBuffering.target.subscriptions.play.subscribe).toHaveBeenCalled();
expect(vgBuffering.target.subscriptions.pause.subscribe).toHaveBeenCalled();
expect(vgBuffering.target.subscriptions.bufferDetected.subscribe).toHaveBeenCalled();
});
});

describe('startBufferCheck', ()=>{
it('should register bufferCheck in a setInterval', () => {
spyOn(window, 'setInterval').and.returnValue(100);
vgBuffering.checkInterval = 77;
vgBuffering.startBufferCheck();
expect(window.setInterval).toHaveBeenCalledWith(
vgBuffering.bufferCheck,
77
);
expect(vgBuffering.checkBufferInterval).toBe(100);
});
});

describe('stopBufferCheck', ()=>{
it('should unregister bufferCheck from setInterval', () => {
spyOn(window, 'clearInterval');
vgBuffering.stopBufferCheck();
expect(window.clearInterval).toHaveBeenCalledWith(
vgBuffering.checkBufferInterval
);

describe('isBuffering', ()=>{
it('should show if buffer is detected', () => {
spyOn(vgBuffering, 'show');
vgBuffering.onUpdateBuffer(true);
expect(vgBuffering.show).toHaveBeenCalled();
});
it('should set props to hide buffering indicator', () => {
vgBuffering.bufferingDetected = true;
it('should hide if buffer is not detected', () => {
spyOn(vgBuffering, 'hide');
vgBuffering.stopBufferCheck();
expect(vgBuffering.bufferingDetected).toBe(false);
vgBuffering.onUpdateBuffer(false);
expect(vgBuffering.hide).toHaveBeenCalled();
});
});
Expand All @@ -80,31 +61,4 @@ describe('Volume control', () => {
expect(vgBuffering.displayState).toBe('none');
});
});

describe('bufferCheck', ()=>{
beforeEach(()=>{
vgBuffering.target = <IPlayable>{currentTime:0};
});
it('should set bufferingDetected to true', () => {
spyOn(vgBuffering, 'show');
vgBuffering.bufferingDetected = false;
vgBuffering.target.currentTime = 10;
vgBuffering.lastPlayPos = 10;
vgBuffering.bufferCheck();
expect(vgBuffering.bufferingDetected).toBe(true);
expect(vgBuffering.lastPlayPos).toBe(10);
expect(vgBuffering.show).toHaveBeenCalled();
});

it('should set bufferingDetected to false', () => {
spyOn(vgBuffering, 'hide');
vgBuffering.bufferingDetected = true;
vgBuffering.target.currentTime = 20;
vgBuffering.lastPlayPos = 10;
vgBuffering.bufferCheck();
expect(vgBuffering.bufferingDetected).toBe(false);
expect(vgBuffering.lastPlayPos).toBe(20);
expect(vgBuffering.hide).toHaveBeenCalled();
});
});
});
37 changes: 10 additions & 27 deletions src/vg-buffering/vg-buffering.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,51 +103,34 @@ export class VgBuffering {
vgFor: string;
target: IPlayable;
checkBufferInterval: number;
checkInterval: number = 50;
currentPlayPos: number = 0;
lastPlayPos: number = 0;
bufferingDetected: boolean;

@HostBinding('style.display') displayState: string = 'none';

constructor(ref:ElementRef, public API: VgAPI) {
this.elem = ref.nativeElement;
API.playerReadyEvent.subscribe((api:VgAPI) => this.onPlayerReady());
this.bufferCheck = this.bufferCheck.bind(this);
}

onPlayerReady() {
this.vgFor = this.elem.getAttribute('vg-for');
this.target = this.API.getMediaById(this.vgFor);

this.target.subscriptions.play.subscribe(this.startBufferCheck.bind(this));
this.target.subscriptions.pause.subscribe(this.stopBufferCheck.bind(this));
this.target.subscriptions.bufferDetected.subscribe(
isBuffering => this.onUpdateBuffer(isBuffering)
);
}

checkInterval: number = 50;
currentPlayPos: number = 0;
lastPlayPos: number = 0;
bufferingDetected: boolean;

// http://stackoverflow.com/a/23828241/779529
bufferCheck() {
this.currentPlayPos = this.target.currentTime
const offset = 1 / this.checkInterval
if (!this.bufferingDetected && this.currentPlayPos < (this.lastPlayPos + offset)) {
this.bufferingDetected = true;
onUpdateBuffer(isBuffering) {
if (isBuffering) {
this.show();
}
if (this.bufferingDetected && this.currentPlayPos > (this.lastPlayPos + offset)) {
this.bufferingDetected = false;
else {
this.hide();
}
this.lastPlayPos = this.currentPlayPos
}

startBufferCheck() {
this.checkBufferInterval = window.setInterval( this.bufferCheck, this.checkInterval);
}

stopBufferCheck() {
window.clearInterval(this.checkBufferInterval);
this.bufferingDetected = false;
this.hide();
}

show() {
Expand Down
4 changes: 2 additions & 2 deletions src/vg-controls/vg-fullscreen/vg-fullscreen.d.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { ElementRef } from '@angular/core';
import { VgAPI } from '../../services/vg-api';
import { VgFullscreenAPI } from "../../services/vg-fullscreen-api";
import { VgAbstractControl } from '../vg-abstract-control';
export declare class VgFullscreen extends VgAbstractControl {
API: VgAPI;
elem: HTMLElement;
vgFor: string;
target: Object;
fsAPI: VgFullscreenAPI;
isFullscreen: boolean;
constructor(ref: ElementRef, API: VgAPI);
onChangeFullscreen(fsState: boolean): void;
onPlayerReady(): void;
onClick(): void;
}
1 change: 1 addition & 0 deletions src/vg-media/i-playable.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface IPlayable {
dispatchEvent?: Function;
}
export interface IMediaSubscriptions {
bufferDetected: Observable<any>;
canPlay: Observable<any>;
canPlayThrough: Observable<any>;
loadedMetadata: Observable<any>;
Expand Down
1 change: 1 addition & 0 deletions src/vg-media/i-playable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface IPlayable {
}

export interface IMediaSubscriptions {
bufferDetected: Observable<any>;
canPlay: Observable<any>;
canPlayThrough: Observable<any>;
loadedMetadata: Observable<any>;
Expand Down
23 changes: 21 additions & 2 deletions src/vg-media/vg-media.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { ElementRef, OnInit } from '@angular/core';
import { ElementRef, OnInit } from "@angular/core";
import { IPlayable, IMediaSubscriptions } from "./i-playable";
import { VgAPI } from "../services/vg-api";
import { Observer } from "rxjs";
export declare class VgMedia implements OnInit, IPlayable {
private api;
elem: any;
private _vgMaster;
isMaster: boolean;
Expand All @@ -10,11 +13,23 @@ export declare class VgMedia implements OnInit, IPlayable {
subscriptions: IMediaSubscriptions | any;
canPlay: boolean;
canPlayThrough: boolean;
isBufferDetected: boolean;
isMetadataLoaded: boolean;
isReadyToPlay: boolean;
isWaiting: boolean;
isCompleted: boolean;
constructor(ref: ElementRef);
checkInterval: number;
currentPlayPos: number;
lastPlayPos: number;
bufferObserver: Observer<any>;
checkBufferSubscription: any;
syncSubscription: any;
canPlayAllSubscription: any;
playAtferSync: boolean;
constructor(ref: ElementRef, api: VgAPI);
ngOnInit(): void;
prepareSync(): void;
startSync(): void;
onMutation(mutations: any): void;
play(): void;
pause(): void;
Expand All @@ -36,4 +51,8 @@ export declare class VgMedia implements OnInit, IPlayable {
onProgress(event: any): void;
onVolumeChange(event: any): void;
onError(event: any): void;
bufferCheck(): void;
startBufferCheck(): void;
stopBufferCheck(): void;
onBufferDetected(): void;
}
2 changes: 1 addition & 1 deletion src/vg-media/vg-media.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe('Videogular Media', () => {
};

api = new VgAPI();
media = new VgMedia(ref);
media = new VgMedia(ref, api);
});

it('Should load a new media if a change on dom have been happened', () => {
Expand Down
Loading

0 comments on commit 68b2b6b

Please sign in to comment.