📄 netstreamcontrollingstreamprovider.as
字号:
/* * Copyright (c) 2008, 2009 Flowplayer Oy * * This file is part of Flowplayer. * * Flowplayer is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Flowplayer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Flowplayer. If not, see <http://www.gnu.org/licenses/>. */package org.flowplayer.controller { import org.flowplayer.config.Config; import org.flowplayer.controller.StreamProvider; import org.flowplayer.controller.VolumeController; import org.flowplayer.flow_internal; import org.flowplayer.model.Clip; import org.flowplayer.model.ClipError; import org.flowplayer.model.ClipEvent; import org.flowplayer.model.ClipEventType; import org.flowplayer.model.Playlist; import org.flowplayer.model.PluginModel; import org.flowplayer.util.Assert; import org.flowplayer.util.Log; import org.flowplayer.view.Flowplayer; import flash.display.DisplayObject; import flash.errors.IOError; import flash.events.NetStatusEvent; import flash.events.TimerEvent; import flash.media.Video; import flash.net.NetConnection; import flash.net.NetStream; import flash.utils.Timer;
/** * A StreamProvider that does it's job using the Flash's NetStream class. * Implements standard HTTP based progressive download. */ public class NetStreamControllingStreamProvider implements StreamProvider { protected var log:Log = new Log(this); private var _connection:NetConnection; private var _netStream:NetStream; private var _startedClip:Clip; private var _playlist:Playlist; private var _pauseAfterStart:Boolean; private var _volumeController:VolumeController; private var _seekTargetWaitTimer:Timer; private var _seekTarget:Number; // state variables private var _silentSeek:Boolean; private var _paused:Boolean; private var _stopping:Boolean;
private var _started:Boolean; private var _model:PluginModel; private var _config:Config; /** * Sets the plugin model. */ public function set config(model:PluginModel):void { _model = model; onConfig(model); } flow_internal function set playerConfig(config:Config):void { _config = config; } /** * Sets the player instance. */ public function set player(player:Flowplayer):void { _config = player.config; onLoad(player); } /* ---- implementation of StreamProvider: ---- */ /** * @inheritDoc */ public final function load(event:ClipEvent, clip:Clip, pauseAfterStart:Boolean = false):void { _paused = false; _stopping = false; Assert.notNull(clip, "load(clip): clip cannot be null"); if (pauseAfterStart) { log.info("this clip will pause after start"); } _pauseAfterStart = pauseAfterStart; clip.onMetaData(onMetaData, function(clip:Clip):Boolean { return clip.provider == (_model ? _model.name : 'http'); }); log.debug("previously started clip " + _startedClip); if (_startedClip && _startedClip == clip && _connection) { log.info("playing previous clip again, reusing existing connection and resuming"); _started = false; netStream.resume(); start(null, _startedClip, _pauseAfterStart); } else { log.debug("will create a new connection"); _startedClip = clip; connect(clip); } } /** * @inheritDoc */ public function get allowRandomSeek():Boolean { return false; } /** * @inheritDoc */ public function stopBuffering():void { if (! _netStream) return; log.debug("stopBuffering, closing netStream"); _netStream.close(); dispatchPlayEvent(ClipEventType.BUFFER_STOP); } /** * @inheritDoc */ public final function resume(event:ClipEvent):void { _paused = false; _stopping = false; doResume(_netStream, event); } /** * @inheritDoc */ public final function pause(event:ClipEvent):void { _paused = true; doPause(_netStream, event); } /** * @inheritDoc * @see #doSeek() */ public final function seek(event:ClipEvent, seconds:Number):void { silentSeek = event == null; log.debug("seekTo " + seconds); _seekTarget = seconds; doSeek(event, _netStream, seconds); } /** * @inheritDoc */ public final function stop(event:ClipEvent, closeStreamAndConnection:Boolean = false):void { log.debug("stop called"); if (! _netStream) return; doStop(event, _netStream, closeStreamAndConnection); } /** * @inheritDoc */ public function get time():Number { if (! _netStream) return 0; if (! currentClipStarted()) return 0; if (! _started) { return 0; } return getCurrentPlayheadTime(netStream); } /** * @inheritDoc */ public function get bufferStart():Number { return 0; } /** * @inheritDoc */ public function get bufferEnd():Number { if (! _netStream) return 0; if (! currentClipStarted()) return 0; return Math.min(_netStream.bytesLoaded / _netStream.bytesTotal * clip.durationFromMetadata, clip.duration); } /** * @inheritDoc */ public function get fileSize():Number { if (! _netStream) return 0; if (! currentClipStarted()) return 0; return _netStream.bytesTotal; } /** * @inheritDoc */ public function set volumeController(volumeController:VolumeController):void { _volumeController = volumeController; } /** * @inheritDoc */ public function get stopping():Boolean { return _stopping; } /** * @inheritDoc */ public function getVideo(clip:Clip):DisplayObject { var video:Video = new Video(); video.smoothing = clip.smoothing; return video; } /** * @inheritDoc */ public function attachStream(video:DisplayObject):void { Video(video).attachNetStream(_netStream); } /** * @inheritDoc */ public function get playlist():Playlist { return _playlist; } /** * @inheritDoc */ public function set playlist(playlist:Playlist):void { _playlist = playlist; } /* ---- Methods that can be overridden ----- */ /* ----------------------------------------- */ /** * Connects to the backend. The implementation creates a new NetConnection then calls * <code>addConnectionStatusListener(connection)</code> and <code>NetConnection.connect(getConnectUrl(clip))</code>. * * @see #getConnectUrl() */ protected function connect(clip:Clip, ... rest):void { if (_netStream) { _netStream.close(); _netStream = null; } if (_connection) { _connection.close(); _connection = null; } _connection = new NetConnection(); _connection.proxyType = "best"; _connection.client = this; addConnectionStatusListener(_connection); log.debug("Connecting to " + getConnectUrl(clip)); if (rest.length > 0) { _connection.connect(getConnectUrl(clip), rest); } else { _connection.connect(getConnectUrl(clip)); } } /** * Adds a connection status listener to the <code>NetConnection</code>. */ protected final function addConnectionStatusListener(connection:NetConnection):void { //connection.addEventListener(NetStatusEvent.NET_STATUS, onConnectionStatus); connection.addEventListener(NetStatusEvent.NET_STATUS, _onNetStatus); } /** * Gets the url used for <code>NetStream.connect(url)</code>. Meant to be overridden by providers that need special * NetConnection URLs. This implementation return's <code>null</code> as required when doing HTTP progressive * download. */ protected function getConnectUrl(clip:Clip):String { return null; } /** * Starts loading using the specified netStream and clip. Can be overridden in subclasses. * The implementation in this class calls <code>netStream.play(getClipUrl(clip))</code> with the clip's URL. * * @param event the event that is dispatched after the loading has been successfully * started * @param netStream * @param clip */ protected function doLoad(event:ClipEvent, netStream:NetStream, clip:Clip):void { netStream.client = new NetStreamClient(clip, _config); netStream.play(getClipUrl(clip)); } /** * Gets the url when calling <code>NetStream.play(url)</code>. Override this if you need to manipulate the clip's URL. */ protected function getClipUrl(clip:Clip):String { return clip.completeUrl; } /** * Pauses the specified netStream. This implementation calls <code>netStream.pause()</code>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -