Merge pull request #2067 from yurydelendik/netevents

Bug 1130189 - Better NetStream events.
This commit is contained in:
Yury Delendik 2015-02-07 08:47:09 -06:00
Родитель 6087fe9c1c a84899b1a8
Коммит a82ac47af3
3 изменённых файлов: 75 добавлений и 28 удалений

Просмотреть файл

@ -116,14 +116,17 @@ module Shumway.Remoting {
export enum VideoPlaybackEvent {
Initialized = 0,
PlayStart = 1,
PlayStop = 2,
BufferFull = 3,
Progress = 4,
BufferEmpty = 5,
Error = 6,
Metadata = 7,
Seeking = 8
Metadata = 1,
PlayStart = 2,
PlayStop = 3,
BufferEmpty = 4,
BufferFull = 5,
Pause = 6,
Unpause = 7,
Seeking = 8,
Seeked = 9,
Progress = 10,
Error = 11,
}
export enum VideoControlEvent {
@ -134,7 +137,8 @@ module Shumway.Remoting {
GetBufferLength = 5,
SetSoundLevels = 6,
GetBytesLoaded = 7,
GetBytesTotal = 8
GetBytesTotal = 8,
EnsurePlaying = 9,
}
export enum StageScaleMode {

Просмотреть файл

@ -64,10 +64,7 @@ module Shumway.AVM2.AS.flash.net {
this._videoStream = new VideoStream();
this._videoStream._onEnsurePlay = function () {
this._notifyVideoControl(VideoControlEvent.Pause, {
paused: false,
time: NaN
});
this._notifyVideoControl(VideoControlEvent.EnsurePlaying, null);
}.bind(this);
this._resourceName = null;
@ -500,6 +497,8 @@ module Shumway.AVM2.AS.flash.net {
false, false, wrapJSObject({code: "NetStream.Play.Start", level: "status"})));
break;
case VideoPlaybackEvent.PlayStop:
this.dispatchEvent(new events.NetStatusEvent(events.NetStatusEvent.NET_STATUS,
false, false, wrapJSObject({code: "NetStream.Buffer.Flush", level: "status"})));
this.dispatchEvent(new events.NetStatusEvent(events.NetStatusEvent.NET_STATUS,
false, false, wrapJSObject({code: "NetStream.Play.Stop", level: "status"})));
@ -519,10 +518,22 @@ module Shumway.AVM2.AS.flash.net {
this.dispatchEvent(new events.NetStatusEvent(events.NetStatusEvent.NET_STATUS,
false, false, wrapJSObject({code: code, level: "error"})));
break;
case VideoPlaybackEvent.Pause:
this.dispatchEvent(new events.NetStatusEvent(events.NetStatusEvent.NET_STATUS,
false, false, wrapJSObject({code: "NetStream.Pause.Notify", level: "status"})));
break;
case VideoPlaybackEvent.Unpause:
this.dispatchEvent(new events.NetStatusEvent(events.NetStatusEvent.NET_STATUS,
false, false, wrapJSObject({code: "NetStream.Unpause.Notify", level: "status"})));
break;
case VideoPlaybackEvent.Seeking:
this.dispatchEvent(new events.NetStatusEvent(events.NetStatusEvent.NET_STATUS,
false, false, wrapJSObject({code: "NetStream.Seek.Notify", level: "status"})));
break;
case VideoPlaybackEvent.Seeked:
this.dispatchEvent(new events.NetStatusEvent(events.NetStatusEvent.NET_STATUS,
false, false, wrapJSObject({code: "NetStream.Seek.Complete", level: "status"})));
break;
case VideoPlaybackEvent.Metadata:
if (this._client) {
var metadata = {};

Просмотреть файл

@ -161,7 +161,8 @@ module Shumway.GFX {
export enum RenderableVideoState {
Idle = 1,
Playing,
Paused
Paused,
Ended
}
export class RenderableVideo extends Renderable {
@ -172,7 +173,8 @@ module Shumway.GFX {
private _eventSerializer: IVideoPlaybackEventSerializer;
private _lastTimeInvalidated: number = 0;
private _lastPausedTime: number = 0;
private _seekHappens: boolean = false;
private _seekHappening: boolean = false;
private _pauseHappening: boolean = false;
private _isDOMElement = true;
private _state: RenderableVideoState;
static _renderableVideos: RenderableVideo [] = [];
@ -188,15 +190,17 @@ module Shumway.GFX {
var element: HTMLVideoElement = document.createElement('video');
var elementEventHandler = this._handleVideoEvent.bind(this);
element.preload = 'metadata'; // for mobile devices
// element.loop = true;
element.addEventListener("play", elementEventHandler);
element.addEventListener("pause", elementEventHandler);
element.addEventListener("ended", elementEventHandler);
element.addEventListener("loadeddata", elementEventHandler);
element.addEventListener("progress", elementEventHandler);
element.addEventListener("waiting", elementEventHandler);
element.addEventListener("suspend", elementEventHandler);
element.addEventListener("loadedmetadata", elementEventHandler);
element.addEventListener("error", elementEventHandler);
element.addEventListener("seeking", elementEventHandler);
element.addEventListener("seeked", elementEventHandler);
element.addEventListener("canplay", elementEventHandler);
this._video = element;
this._videoEventHandler = elementEventHandler;
@ -234,20 +238,38 @@ module Shumway.GFX {
var element: HTMLVideoElement = this._video;
switch (evt.type) {
case "play":
type = VideoPlaybackEvent.PlayStart;
if (!this._pauseHappening) {
return;
}
type = VideoPlaybackEvent.Unpause;
break;
case "pause":
type = VideoPlaybackEvent.Pause;
this._pauseHappening = true;
break;
case "ended":
type = VideoPlaybackEvent.PlayStop;
this._state = RenderableVideoState.Ended;
this._notifyNetStream(VideoPlaybackEvent.PlayStop, data);
type = VideoPlaybackEvent.BufferEmpty;
break;
case "loadeddata":
this._pauseHappening = false;
this._notifyNetStream(VideoPlaybackEvent.PlayStart, data);
this.play();
return;
case "canplay":
if (this._pauseHappening) {
return;
}
type = VideoPlaybackEvent.BufferFull;
break;
case "progress":
type = VideoPlaybackEvent.Progress;
break;
case "waiting":
type = VideoPlaybackEvent.BufferEmpty;
break;
case "suspend":
// type = VideoPlaybackEvent.BufferEmpty;
// break;
return;
case "loadedmetadata":
type = VideoPlaybackEvent.Metadata;
data = {
@ -263,8 +285,17 @@ module Shumway.GFX {
};
break;
case "seeking":
if (!this._seekHappening) {
return;
}
type = VideoPlaybackEvent.Seeking;
this._seekHappens = true;
break;
case "seeked":
if (!this._seekHappening) {
return;
}
type = VideoPlaybackEvent.Seeked;
this._seekHappening = false;
break;
default:
return; // unhandled event
@ -287,6 +318,11 @@ module Shumway.GFX {
}
this._notifyNetStream(VideoPlaybackEvent.Initialized, null);
break;
case VideoControlEvent.EnsurePlaying:
if (videoElement.paused) {
videoElement.play();
}
break;
case VideoControlEvent.Pause:
if (videoElement) {
if (data.paused && !videoElement.paused) {
@ -304,16 +340,12 @@ module Shumway.GFX {
if (!isNaN(data.time) && this._lastPausedTime !== data.time && videoElement.seekable.length !== 0) {
videoElement.currentTime = data.time;
}
if (this._seekHappens) {
this._seekHappens = false;
this._notifyNetStream(VideoPlaybackEvent.BufferFull, null);
}
}
}
return;
case VideoControlEvent.Seek:
if (videoElement && videoElement.seekable.length !== 0) {
this._seekHappening = true;
videoElement.currentTime = data.time;
}
return;