/***************************************************** * * Copyright 2009 Adobe Systems Incorporated. All Rights Reserved. * ***************************************************** * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * * The Initial Developer of the Original Code is Adobe Systems Incorporated. * Portions created by Adobe Systems Incorporated are Copyright (C) 2009 Adobe Systems * Incorporated. All Rights Reserved. * *****************************************************/ package org.osmf.net { import flash.events.NetStatusEvent; import flash.net.NetStream; import org.osmf.media.MediaResourceBase; import org.osmf.traits.TimeTrait; [ExcludeClass] /** * @private * * The NetStreamTimeTrait class extends TimeTrait to expose NetStream's time properties. * * @see flash.net.NetStream */ public class NetStreamTimeTrait extends TimeTrait { /** * Constructor. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ public function NetStreamTimeTrait(netStream:NetStream, resource:MediaResourceBase, defaultDuration:Number=NaN) { super(); this.netStream = netStream; NetClient(netStream.client).addHandler(NetStreamCodes.ON_META_DATA, onMetaData); NetClient(netStream.client).addHandler(NetStreamCodes.ON_PLAY_STATUS, onPlayStatus); netStream.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus, false, 0, true); this.resource = resource; if (isNaN(defaultDuration) == false) { setDuration(defaultDuration); } } /** * @private */ override public function get currentTime():Number { // If at the end of the video, make sure the duration matches the currentTime. // Work around for FP-3724. Only apply duration offset at the end - or else the seek(0) doesn't goto 0. if (durationOffset == (duration - (netStream.time - audioDelay))) { return netStream.time - audioDelay + durationOffset; } else { return netStream.time - audioDelay; } } private function onMetaData(value:Object):void { // Determine the start time and duration for the // resource. var playArgs:Object = NetStreamUtils.getPlayArgsForResource(resource); //Audio delay is sometimes passed along with the metadata. The audio delay affects //all netsTream.time related calculations, including seek(). audioDelay = value.hasOwnProperty("audiodelay") ? value.audiodelay : 0; // Ensure our start time is non-negative, we only use it for // calculating the offset. var subclipStartTime:Number = Math.max(0, playArgs.start); // Ensure our duration is non-negative. var subclipDuration:Number = playArgs.len; if (subclipDuration == NetStreamUtils.PLAY_LEN_ARG_ALL) { subclipDuration = Number.MAX_VALUE; } // If startTime is unspecified, our duration is everything // up to the end of the subclip (or the entire duration, if // no subclip end is specified). Take into account audio delay. setDuration(Math.min((value.duration - audioDelay) - subclipStartTime, subclipDuration)); } private function onPlayStatus(event:Object):void { switch(event.code) { case NetStreamCodes.NETSTREAM_PLAY_COMPLETE: // For streaming, NetStream.Play.Complete means playback // has completed. But this isn't fired for progressive. signalComplete(); } } private function onNetStatus(event:NetStatusEvent):void { switch (event.info.code) { case NetStreamCodes.NETSTREAM_PLAY_STOP: // For progressive, NetStream.Play.Stop means playback // has completed. But this isn't fired for streaming. if (NetStreamUtils.isStreamingResource(resource) == false) { signalComplete(); } break; case NetStreamCodes.NETSTREAM_PLAY_UNPUBLISH_NOTIFY: // When a live stream is unpublished, we should signal that // the stream has stopped. signalComplete(); break; } } /** * We have to change the duration , given that audioDelay isn't enough to * fix that netStream.time has from the detected duration. This isn't * pre computable, since PLAY_STOP is fired at * non-deterministic intervals when the video is near ending. **/ override protected function signalComplete():void { if ((netStream.time - audioDelay) != duration) { durationOffset = duration - (netStream.time - audioDelay); } super.signalComplete(); } private var durationOffset:Number = 0; private var audioDelay:Number = 0; private var netStream:NetStream; private var resource:MediaResourceBase; } }