diff --git a/src/VideoJS.as b/src/VideoJS.as index 90f4ffbf..5f34d88b 100644 --- a/src/VideoJS.as +++ b/src/VideoJS.as @@ -67,6 +67,7 @@ package{ try{ ExternalInterface.addCallback("vjs_appendBuffer", onAppendBufferCalled); ExternalInterface.addCallback("vjs_echo", onEchoCalled); + ExternalInterface.addCallback("vjs_endOfStream", onEndOfStreamCalled); ExternalInterface.addCallback("vjs_getProperty", onGetPropertyCalled); ExternalInterface.addCallback("vjs_setProperty", onSetPropertyCalled); ExternalInterface.addCallback("vjs_autoplay", onAutoplayCalled); @@ -183,6 +184,10 @@ package{ private function onEchoCalled(pResponse:* = null):*{ return pResponse; } + + private function onEndOfStreamCalled():*{ + _app.model.endOfStream(); + } private function onGetPropertyCalled(pPropertyName:String = ""):*{ diff --git a/src/com/videojs/VideoJSModel.as b/src/com/videojs/VideoJSModel.as index d608bf07..5b4ec2eb 100644 --- a/src/com/videojs/VideoJSModel.as +++ b/src/com/videojs/VideoJSModel.as @@ -106,6 +106,10 @@ package com.videojs{ public function appendBuffer(bytes:ByteArray):void { _provider.appendBuffer(bytes); } + + public function endOfStream():void { + _provider.endOfStream(); + } public function get backgroundColor():Number{ return _backgroundColor; diff --git a/src/com/videojs/providers/HTTPAudioProvider.as b/src/com/videojs/providers/HTTPAudioProvider.as index a825225f..ea7f2b22 100644 --- a/src/com/videojs/providers/HTTPAudioProvider.as +++ b/src/com/videojs/providers/HTTPAudioProvider.as @@ -114,6 +114,10 @@ package com.videojs.providers{ public function appendBuffer(bytes:ByteArray):void{ throw "HTTPAudioProvider does not support appendBuffer"; } + + public function endOfStream():void{ + throw "HTTPAudioProvider does not support endOfStream"; + } public function get buffered():Number{ if(duration > 0){ @@ -441,4 +445,4 @@ package com.videojs.providers{ _model.broadcastEventExternally(ExternalEventName.ON_METADATA, _metadata); } } -} \ No newline at end of file +} diff --git a/src/com/videojs/providers/HTTPVideoProvider.as b/src/com/videojs/providers/HTTPVideoProvider.as index c18506a1..3656bbe3 100644 --- a/src/com/videojs/providers/HTTPVideoProvider.as +++ b/src/com/videojs/providers/HTTPVideoProvider.as @@ -37,6 +37,12 @@ package com.videojs.providers{ * @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html#play() */ private var _startOffset:Number = 0; + /** + * If true, an empty NetStream buffer should be interpreted as the end of the video. This + * is probably the case because the video data is being fed to the NetStream dynamically + * through appendBuffer, not for traditional file download video. + */ + private var _ending:Boolean = false; private var _videoReference:Video; /** @@ -163,6 +169,10 @@ package com.videojs.providers{ public function appendBuffer(bytes:ByteArray):void{ _ns.appendBytes(bytes); } + + public function endOfStream():void{ + _ending = true; + } public function get buffered():Number{ // _src.path == null when in data generation mode @@ -518,33 +528,28 @@ package com.videojs.providers{ case "NetStream.Buffer.Empty": // should not fire if ended/paused. issue #38 if(!_isPlaying){ return; } - _isBuffering = true; - _model.broadcastEventExternally(ExternalEventName.ON_BUFFER_EMPTY); - if(_src.path === null) - { - if(_model.time >= _model.duration-.5) - { - if(!_loop) { - _isPlaying = false; - _isPaused = true; - _hasEnded = true; - _model.broadcastEvent(new VideoPlaybackEvent(VideoPlaybackEvent.ON_STREAM_CLOSE, {info:e.info})); - _model.broadcastEventExternally(ExternalEventName.ON_PAUSE); - _model.broadcastEventExternally(ExternalEventName.ON_PLAYBACK_COMPLETE); - } - else { + // reaching the end of the buffer after endOfStream has been called means we've + // hit the end of the video + if (_ending) { + _ending = false; + _isPlaying = false; + _isPaused = true; + _hasEnded = true; + _model.broadcastEvent(new VideoPlaybackEvent(VideoPlaybackEvent.ON_STREAM_CLOSE, {info:e.info})); + _model.broadcastEventExternally(ExternalEventName.ON_PAUSE); + _model.broadcastEventExternally(ExternalEventName.ON_PLAYBACK_COMPLETE); - } - _throughputTimer.stop(); - _throughputTimer.reset(); - } + _startOffset = 0; + _pausedSeekValue = 0; + break; } + _isBuffering = true; + _model.broadcastEventExternally(ExternalEventName.ON_BUFFER_EMPTY); break; case "NetStream.Play.Stop": - if(!_loop){ _isPlaying = false; _isPaused = true; diff --git a/src/com/videojs/providers/IProvider.as b/src/com/videojs/providers/IProvider.as index 0345e9c2..523c949f 100644 --- a/src/com/videojs/providers/IProvider.as +++ b/src/com/videojs/providers/IProvider.as @@ -30,6 +30,13 @@ package com.videojs.providers{ * @param bytes the ByteArray of data to append. */ function appendBuffer(bytes:ByteArray):void; + + /** + * Indicates that no further bytes will appended to the source + * buffer. After this method has been called, reaching the end + * of buffered input is equivalent to the end of the media. + */ + function endOfStream():void; /** * Should return an interger that reflects the closest parallel to @@ -168,4 +175,4 @@ package com.videojs.providers{ function die():void; } -} \ No newline at end of file +} diff --git a/src/com/videojs/providers/RTMPVideoProvider.as b/src/com/videojs/providers/RTMPVideoProvider.as index 8051d6c9..36b27cdd 100644 --- a/src/com/videojs/providers/RTMPVideoProvider.as +++ b/src/com/videojs/providers/RTMPVideoProvider.as @@ -137,6 +137,10 @@ package com.videojs.providers{ public function appendBuffer(bytes:ByteArray):void{ throw "RTMPVideoProvider does not support appendBuffer"; } + + public function endOfStream():void{ + throw "RTMPVideoProvider does not support endOfStream"; + } public function get buffered():Number{ if(duration > 0){ @@ -631,4 +635,4 @@ package com.videojs.providers{ */ public function streamInfo(pObj:Object):void {} } -} \ No newline at end of file +}