7 Replies Latest reply on Jun 25, 2012 9:13 AM by louminsk

    How to: NetStream close/play

    Nicolas Siver Level 1

      I want close stream, when MediaPlayer.pause triggers and again play stream on MediaPlayer.play

       

      NetStreamPlayTrait handles  all operations around NetStream with resume, play and so on. Should I create my own Trait based on PlayTrait and custom VideoElement to inject my own PlayTrait in processReadyState phase. Please advice if any another options.

      P.S. Don't want go far from default OSMF.

        • 1. Re: How to: NetStream close/play
          serpent213 Level 1

          Similar problem here.

           

          I'm using

           

          var loadTrait:LoadTrait = mediaPlayer.media.getTrait(MediaTraitType.LOAD)
              as LoadTrait;
          loadTrait.unload();
          

           

          to close the connection. But the display component clears the screen afterwards instead of keeping the last video frame.

           

          How can I prevent that?

          • 2. Re: How to: NetStream close/play
            Andrian Cucu Adobe Employee

            Hi all,

             

            There is a known issue related to pausing or resuming live streams served by the Wowza Media Server.

             

            Somehow, the pause or resume after pause behaves differently in FMS and in Wowza. In FMS you get the expected behaviour - the last frame remains on screen when pausing the playback.

             

            You can try and take a snapshot of the video before unloading the loadTrait and display that snapshot while the video is being paused. You can also try and ask about this on the Wawza forum as well, i'm sure there are other people that run into this as well: http://www.wowzamedia.com/forums/

             

            -Andrian

            • 3. Re: How to: NetStream close/play
              Mykola3296 Level 2

              I've done it the way Andrian says (screenshot).

              But here you should mind the following - to get a screenshot (Bitmap.draw()) you should:

              1) When using RTMP  - you should have VideoSampleAccess enabled for you in FMS application (do not know a key for Wowza)

              2) When using HTTP - crossdomain.xml should be preloaded if you are loading from different domain. So either NetStream.checkPolicyFile should be set to "true" for the NetStream or crossdomain should be preloaded separately. As I remember, unfortunately, there is no direct way to set NetStream.checkPolicyFile in NetLoader (opposite to ImageLoader) - so you will need to get the NetStream instance using various [Excluded] classes (NetStreamLoadTrait and more).

              • 4. Re: How to: NetStream close/play
                Nicolas Siver Level 1

                I did it by rectreating MediaElement. When user pause live stream and try to play stream again, I create new MediaElement using MediaPlayer.media interface.

                Its all about live streams and NetStream.resume on Wowza.

                • 5. Re: How to: NetStream close/play
                  Nicolas Siver Level 1

                  I also see another option, its custom PlayTrait, so you can rewrite play/pause/resume behaviors.

                   

                  P.S.

                  All custom Traits I provide through LoadTrait

                  • 6. Re: How to: NetStream close/play
                    serpent213 Level 1

                    The snapshot solution works fine, thanks.

                    • 7. Re: How to: NetStream close/play
                      louminsk

                      Hi

                       

                      I custom my first live playeur build with the nice Strobe Media Playeur.

                      (I finally success to build a nice watermark  in directly add Layout and image element in the main StrobeMediaPlayback.as it works nice (didnt success be happy with a watermark plug in for that (seems there is an incorrect z- index layout))

                      I have now to add a preroll , the dedicated plugin AdvertisementPlugin.swf in the StrobeMediaPlayeur works nice for that

                       

                      The problem is that i use Wowza as streaming service for this project and the fact that pause and resume need be replace by close and play action

                      Here my online sample

                      live rtmp where its impossible to pause and resume

                      http://www.venturistudio.fr/demo/atlasun/replay.html

                      live rtmp with ads plugin correctly load but buffering directly after the preroll

                      www.venturistudio.fr/demo/atlasun/replayads.html

                      live http(works until the next live chunk)

                      http://www.venturistudio.fr/demo/atlasun/replayads_http.html

                      I was looking hours in the Strobemedia Playeur source  to  fixe that (im beginner but already fixed this issue in OVP playeur just adding _ns.close();

                      In the SMB its seems more complexe for me (due to the number of as file i discover)

                      i found PauseButton.as

                      I done a try to change playable.pause(); to playable.stop(); but it doesnt work

                       

                      override protected function onMouseClick(event:MouseEvent):void

                              {

                                  var playable:PlayTrait = media.getTrait(MediaTraitType.PLAY) as PlayTrait;

                                  if ( playable.canPause)

                                  {

                                      playable.pause();

                                  }

                                  else

                                  {

                                      playable.stop();

                                  }

                                  event.stopImmediatePropagation();

                              }

                      The PlayButtons.as code bellow

                      override protected function onMouseClick(event:MouseEvent):void

                              {

                                  var playable:PlayTrait = media.getTrait(MediaTraitType.PLAY) as PlayTrait;

                                  playable.play();

                                  event.stopImmediatePropagation();

                              }

                      I really need help for stopping and play again in place of play and resume in conjunction with Wowza and hope that the AdvertisementPlugin.swf will still work after that (cant find the source code)

                      Thanks in advance :-)

                       

                      Concerning the Snapshot image problem in OMSF with Wowza  i will try fix that later

                      I was trying the previsous code but its make the pause button dissapear :-)

                      var loadTrait:LoadTrait = mediaPlayer.media.getTrait(MediaTraitType.LOAD)

                          as LoadTrait;

                      loadTrait.unload();

                      Below a source code of a working simple playeur OMSF build for live rtmp using Wowza

                       

                      package

                      {

                         

                          import flash.events.FullScreenEvent;

                          import flash.events.IOErrorEvent;

                          import flash.events.MouseEvent;

                          import flash.events.NetStatusEvent;

                          import flash.geom.Rectangle;

                          import flash.media.Video;

                          import flash.net.NetConnection;

                          import flash.net.Responder;

                          import flash.net.URLLoader;

                          import flash.net.URLRequest;

                          import flash.system.Capabilities;

                          import flash.system.Security;

                          import flash.utils.setTimeout;

                         

                          import mx.containers.Canvas;

                          import mx.controls.Button;

                          import mx.controls.Text;

                          import mx.controls.TextInput;

                          import mx.controls.sliderClasses.Slider;

                          import mx.events.FlexEvent;

                          import mx.events.SliderEvent;

                          import mx.states.State;

                          import mx.styles.CSSStyleDeclaration;

                          import mx.utils.LoaderUtil;

                         

                          import org.osmf.containers.MediaContainer;

                          import org.osmf.elements.VideoElement;

                          import org.osmf.events.MediaElementEvent;

                          import org.osmf.events.MediaErrorEvent;

                          import org.osmf.events.MediaPlayerCapabilityChangeEvent;

                          import org.osmf.events.TimeEvent;

                          import org.osmf.media.DefaultMediaFactory;

                          import org.osmf.media.MediaElement;

                          import org.osmf.media.MediaFactory;

                          import org.osmf.media.MediaPlayer;

                          import org.osmf.media.URLResource;

                          import org.osmf.net.DynamicStreamingItem;

                          import org.osmf.net.DynamicStreamingResource;

                          import org.osmf.samples.MediaContainerUIComponent;

                          import org.osmf.traits.MediaTraitBase;

                          import org.osmf.traits.MediaTraitType;

                          import org.osmf.utils.*;

                          import org.osmf.utils.Version;

                         

                          import spark.components.Application;

                         

                          public class Player extends Application

                          {

                              Security.LOCAL_TRUSTED;

                             

                              [Bindable]

                              public var isConnected:Boolean = false;

                             

                              private var mediaElement:MediaElement;

                              private var factory:DefaultMediaFactory = new DefaultMediaFactory();

                              private var player:MediaPlayer = new MediaPlayer();

                              private var isScrubbing:Boolean = false;

                              private var fullscreenCapable:Boolean = false;

                              private var hardwareScaleCapable:Boolean = false;

                              private var saveVideoObjX:Number;

                              private var saveVideoObjY:Number;

                              private var saveVideoObjW:Number;

                              private var saveVideoObjH:Number;

                              private var saveStageW:Number;

                              private var saveStageH:Number;

                              private var adjVideoObjW:Number;

                              private var adjVideoObjH:Number;

                              private var streamName:String;

                              private var netconnection:NetConnection;       

                              private var PlayVersionMin:Boolean;

                              private var streamNames:XML;

                              private var streamsVector:Vector.<DynamicStreamingItem> = new Vector.<DynamicStreamingItem>();           

                              private var dynResource:DynamicStreamingResource = null;

                              public var prompt:Text;

                              public var warn:Text;

                              public var connectStr:TextInput;

                              public var playerVersion:Text;

                              public var videoContainer:MediaContainerUIComponent;

                              public var connectButton:Button;

                              public var doPlay:Button;

                              public var seekBar:Slider;

                              public var volumeLevel:Slider;

                              public var doRewind:Button;

                              public var doFullscreen:Button;

                              public var backdrop:Canvas;

                             

                              public var app:Application;

                             

                              public function Player()

                              {

                                  super();

                                  this.addEventListener(FlexEvent.APPLICATION_COMPLETE,init);

                              }

                             

                              private function init(event:FlexEvent):void

                              {   

                                  stage.align="TL";

                                  stage.scaleMode="noScale";

                                 

                                  doFullscreen.addEventListener(MouseEvent.CLICK,enterFullscreen);   

                                  connectButton.addEventListener(MouseEvent.CLICK,connect);

                                  volumeLevel.addEventListener(SliderEvent.CHANGE,volumeChange);

                                 

                                  connectStr.text = "http://localhost:1935/live/myStream/manifest.f4m";

                                 

                                  // *********************** stream examples ******************//

                                  // http://localhost:1935/live/myStream/manifest.f4m

                                  // http://localhost:1935/live/smil:liveStreamNames.smil/manifest.f4m (server-side smil)

                                  // rtmp://localhost:1935/live/myStream

                                  // rtmp://localhost:1935/live/streamNames.xml (Dynamic Streams)

                                     

                                  videoContainer.container = new MediaContainer();

                                 

                                  checkVersion();

                             

                                  var osmfVersion:String = org.osmf.utils.Version.version;

                                     

                                  playerVersion.text = Capabilities.version + " (Flash-OSMF " + osmfVersion + ")";

                             

                              }

                                     

                              private function xmlIOErrorHandler(event:IOErrorEvent):void

                              {

                                  trace("XML IO Error: " + event.target);

                                  prompt.text = "XML IO Error: " + event.text;   

                              }

                             

                              private function stopAll():void

                              {       

                                  if (player.playing)

                                      player.stop();

                                 

                                  isConnected = false;

                                 

                                  if (mediaElement != null)

                                      videoContainer.container.removeMediaElement(mediaElement);

                                 

                                  mediaElement = null;

                                  netconnection = null;

                                  connectButton.label = "Play";

                                  dynResource = null;

                                  prompt.text = "";

                              }

                             

                              private function clear():void

                              {

                                  prompt.text = "";

                                  dynResource = null;

                              }

                             

                              private function connect(event:MouseEvent):void // Play button (connectButton)

                              {

                                  if (connectButton.label == "Stop")

                                  {

                                      stopAll();

                                      return;

                                  }

                                  var ok:Boolean = checkVersion();

                                  if (!ok)

                                  {

                                      stopAll();

                                      return;

                                  }

                                  clear();

                                  if (connectStr.text.toLowerCase().indexOf("rtmp://")>-1 && connectStr.text.toLowerCase().indexOf(".xml")>-1)

                                      streamName = connectStr.text.substring(connectStr.text.lastIndexOf("/")+1, connectStr.text.length);

                                 

                                  if (streamName == null)

                                  {

                                      loadStream();

                                  }

                                  else if (streamName.toLowerCase().indexOf(".xml") > 0)

                                  {   

                                      loadVector(streamName); // load Dynamic stream items first if stream name is a xml file

                                  }

                              }

                             

                              private function loadVector(streamName:String):void

                              {

                                  var url:String = connectStr.text;

                                             

                                  var loader:URLLoader=new URLLoader();

                                  loader.addEventListener(Event.COMPLETE,xmlHandler);

                                  loader.addEventListener(IOErrorEvent.IO_ERROR,xmlIOErrorHandler)           

                                 

                                  var request:URLRequest=new URLRequest();

                                  var requestURL:String = streamName;

                                  request.url = requestURL;

                                 

                                  loader.load(request)

                              }

                             

                              private function xmlHandler(event:Event):void

                              {

                                  var loader:URLLoader=URLLoader(event.target);

                                  streamNames = new XML(loader.data);

                                 

                                  var videos:XMLList = streamNames..video;

                                 

                                  for (var i:int=0; i<videos.length(); i++)

                                  {

                                      var video:XML = videos[i];

                                      var bitrate:String = video.attribute("system-bitrate");

                                      var item:DynamicStreamingItem = new DynamicStreamingItem(video.@src,Number(bitrate), video.@width, video.@height);

                                      streamsVector.push(item);

                                  }

                                  if (videos.length()>0)

                                  {

                                      dynResource = new DynamicStreamingResource(connectStr.text);               

                                      dynResource.streamItems = streamsVector;

                                  }

                                  loadStream();

                              }

                             

                              private function loadStream():void

                              {   

                                  mediaElement = factory.createMediaElement(new URLResource(connectStr.text));

                                 

                                  if (dynResource != null)

                                      mediaElement.resource=dynResource;

                                 

                                  player.media = mediaElement;   

                                  videoContainer.container.addMediaElement(mediaElement);   

                                 

                                  mediaElement.addEventListener(MediaErrorEvent.MEDIA_ERROR,function(event:MediaErrorEvent) :void

                                  {

                                      trace("event.error.message: " + event.error.message);

                                      stopAll();

                                      prompt.text = event.error.message + " " + event.error.detail;

                                      return;

                                  });

                                 

                                  player.addEventListener(MediaPlayerCapabilityChangeEvent.CAN_PLAY_CHANGE, function(event:MediaPlayerCapabilityChangeEvent):void

                                  {

                                      isConnected = event.enabled;

                                     

                                      if (isConnected)

                                      {

                                          stage.addEventListener(FullScreenEvent.FULL_SCREEN, enterLeaveFullscreen);

                                      }else

                                      {

                                          stage.removeEventListener(FullScreenEvent.FULL_SCREEN, enterLeaveFullscreen);

                                      }

                                  });

                                 

                                  player.autoPlay = true;

                                  connectButton.label  = "Stop";

                              }

                                 

                              private function volumeChange(event:SliderEvent):void

                              {

                                  player.volume = event.value;

                              }

                                 

                              private function enterLeaveFullscreen(event:FullScreenEvent):void

                              {

                                  trace("enterLeaveFullscreen: "+ event.fullScreen);

                                  if (!event.fullScreen)

                                  {       

                                      // reset back to original state

                                      stage.scaleMode = "noScale";

                                      videoContainer.width = 640;

                                      videoContainer.height = 360;

                                      videoContainer.x = saveVideoObjX;

                                      videoContainer.y = saveVideoObjY;

                                      adjVideoObjW = (saveVideoObjW = videoContainer.width);

                                      adjVideoObjH = (saveVideoObjH = videoContainer.height);

                                      backdrop.visible=true;

                                  }

                              }

                             

                              private function enterFullscreen(event:MouseEvent):void

                              {

                                  trace("enterFullscreen: "+hardwareScaleCapable);

                                                 

                                  saveVideoObjX = videoContainer.x;

                                  saveVideoObjY = videoContainer.y;

                                 

                                  backdrop.visible=false;

                                 

                                  if (hardwareScaleCapable)

                                  {

                                      //videoContainer.container;

                                      //videoObj.smoothing = false;

                                      //videoObj.deblocking = 0;

                                     

                                     

                                      // best settings for hardware scaling               

                                      // grab the portion of the stage that is just the video frame

                                      //stage["fullScreenSourceRect"] = videoContainer.getRect(null);

                                      stage["fullScreenSourceRect"] = new Rectangle(

                                      videoContainer.x, videoContainer.y,

                                      videoContainer.width, videoContainer.height);

                                  }

                                  else

                                  {

                                      stage.scaleMode = "noBorder";

                                     

                                      var videoAspectRatio:Number = videoContainer.width/videoContainer.height;

                                      var stageAspectRatio:Number = saveStageW/saveStageH;

                                      var screenAspectRatio:Number = Capabilities.screenResolutionX/Capabilities.screenResolutionY;

                                     

                                      // calculate the width and height of the scaled stage

                                      var stageObjW:Number = saveStageW;

                                      var stageObjH:Number = saveStageH;

                                      if (stageAspectRatio > screenAspectRatio)

                                          stageObjW = saveStageH*screenAspectRatio;

                                      else

                                          stageObjH = saveStageW/screenAspectRatio;

                                     

                                      // calculate the width and height of the video frame scaled against the new stage size

                                      var fsvideoContainerW:Number = stageObjW;

                                      var fsvideoContainerH:Number = stageObjH;

                                      if (videoAspectRatio > screenAspectRatio)

                                          fsvideoContainerH = stageObjW/videoAspectRatio;

                                      else

                                          fsvideoContainerW = stageObjH*videoAspectRatio;           

                                      // scale the video object

                                      videoContainer.width = fsvideoContainerW;

                                      videoContainer.height = fsvideoContainerH;

                                      videoContainer.x = (stageObjW-fsvideoContainerW)/2.0;

                                      videoContainer.y = (stageObjH-fsvideoContainerH)/2.0;

                                  }

                                  stage["displayState"] = "fullScreen";   

                              }

                              private function rewind(event:MouseEvent):void

                              {

                                  player.seek(0);

                                  seekBar.value = 0;

                              }

                             

                              private function checkVersion():Boolean

                              {

                                  PlayVersionMin = testVersion(10, 1, 0, 0);

                                  hardwareScaleCapable = testVersion(9, 0, 60, 0);

                                  if (!PlayVersionMin && connectStr.text.indexOf(".f4m") > 0)

                                  {

                                      warn.text = "Sanjose Streaming not support in this Flash version.";

                                      return false;

                                  }

                                  else

                                  {

                                      warn.text="";

                                      return true;

                                  }

                              }

                             

                              private function testVersion(v0:Number, v1:Number, v2:Number, v3:Number):Boolean

                              {

                                  var version:String = Capabilities.version;

                                  var index:Number = version.indexOf(" ");

                                  version = version.substr(index+1);

                                  var verParts:Array = version.split(",");

                                 

                                  var i:Number;

                                 

                                  var ret:Boolean = true;

                                  while(true)

                                  {

                                      if (Number(verParts[0]) < v0)

                                      {

                                          ret = false;

                                          break;

                                      }

                                      else if (Number(verParts[0]) > v0)

                                          break;

                                     

                                      if (Number(verParts[1]) < v1)

                                      {

                                          ret = false;

                                          break;

                                      }

                                      else if (Number(verParts[1]) > v1)

                                          break;

                                     

                                      if (Number(verParts[2]) < v2)

                                      {

                                          ret = false;

                                          break;

                                      }

                                      else if (Number(verParts[2]) > v2)

                                          break;

                                     

                                      if (Number(verParts[3]) < v3)

                                      {

                                          ret = false;

                                          break;

                                      }

                                      break;

                                  }

                                  trace("testVersion: "+Capabilities.version+">="+v0+","+v1+","+v2+","+v3+": "+ret);   

                                  return ret;

                              }

                          }

                      }