• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Issue video scrubber for AIR

New Here ,
Mar 04, 2014 Mar 04, 2014

Copy link to clipboard

Copied

I have a code setup to play fullscreen video with play/pause, close, and a scrubber/seek bar. Howver, there are some irregularities when publishing for either AIR for Android or AIR for iOS.

Publish for Android gives me an inconsistent scrubber ( in portrait, sometimes it scrubs/seeks, most of the time it does not detect a drag and thus does not scrub). Landscape seems to do a better job of adjusting the scrubber.

Using the same file and codes, when publishing for iOS, the scrubber does not move forward. When I tap and drag the scrubber, the video either restarts or goes back a few frames, but never goes forward.

Is this a bug on Adobe/AIR or do I need to make adjustments to the code to implement for iOS? What is causing these inconsistencies?

Please see the code below and feel free to make suggestions. Any help is greatly appreciated.

From file AIRMobileVideo.as :

package

{
      import flash.display.MovieClip;
      import flash.desktop.NativeApplication;
      import flash.desktop.SystemIdleMode;
      import flash.display.Stage;
      import flash.display.StageAlign;
      import flash.display.StageScaleMode;
      import flash.events.Event;
      import flash.events.StageVideoAvailabilityEvent;
      import flash.geom.Rectangle;
      import flash.media.StageVideo;
      import flash.media.Video;
      import flash.media.StageVideoAvailability;
      import flash.net.NetConnection;
      import flash.net.NetStream;
      import flash.events.NetStatusEvent;
      import flash.events.MouseEvent;
      import flash.events.TouchEvent;
      import flash.geom.Point;
      import flash.utils.Timer;
      import flash.events.TimerEvent;

      public class AIRMobileVideo
      {
            protected var stream:NetStream;
            protected var stageVideo:StageVideo;
            protected var softwareVideo:Video;
 
            public var stageref:Stage;
            public var timelinetarget:MovieClip;
 
            public var playingBlank:Boolean;
 
            public var tmrDisplay:Timer;
            // object holds all meta data
            public var objInfo:Object;
            public var customClient:Object;
 
            public var bolProgressScrub:Boolean  = false;
            public var postime:Number;
 
            public function AIRMobileVideo(stage:Stage, X:int, Y:int, width:int, height:int, target:MovieClip)
            {
  
             stageref = stage;
             timelinetarget = target;
  

             playingBlank = false;
  
             var nc:NetConnection = new NetConnection();
             nc.connect(null);
  
             customClient = new Object();
             customClient.onMetaData = metaDataHandler;
             //stream.client = customClient;
             stream = new NetStream(nc);
             //stream.client = this ;
             stream.client = customClient;
  
             var vidWidth:int;// = stage.fullScreenWidth;//1028;
             var vidHeight:int;// = int((480*vidWidth)/640);//764;
             var Ycal;// = (stage.fullScreenHeight/2) - (vidHeight/2)
             var X;
             if(stageref.fullScreenWidth>stageref.fullScreenHeight){
              //landscape
              vidHeight = stageref.fullScreenHeight;//
              vidWidth  = int((640*vidHeight)/480);
              Ycal = 0;//
              X = (stageref.fullScreenWidth/2) - (vidWidth/2);
             } else {
              //portrait
              vidWidth  = stageref.fullScreenWidth;//1028;
              vidHeight = int((480*vidWidth)/640);//764;
              Ycal = (stageref.fullScreenHeight/2) - (vidHeight/2);
              X=0;
             }
  
             trace("width:"+vidWidth);
             trace("height:"+vidHeight);
  
  
             stream.addEventListener(NetStatusEvent.NET_STATUS, statusHandler);
  
             // software fallback
                   softwareVideo = new Video(vidWidth, vidHeight);
                   softwareVideo.x = X;
                   softwareVideo.y = Ycal;
                   timelinetarget.addChild(softwareVideo);
   
   
                   var pt:Point = new Point(timelinetarget.mcVideoControls.mcProgressScrubber.x,   timelinetarget.mcVideoControls.mcProgressScrubber.y);
                   pt = timelinetarget.mcVideoControls.mcProgressScrubber.parent.localToGlobal(pt);
                   timelinetarget.mcProgressShow.x = pt.x;
                   timelinetarget.mcProgressShow.y = pt.y;
   
                   timelinetarget.addcontrols();
   
   
                   timelinetarget.mcVideoControls.mcProgressScrubber.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
                   tmrDisplay = new Timer(10);
                   tmrDisplay.addEventListener(TimerEvent.TIMER, updateDisplay);
   
                   trace("AIRMobileVideo: using software fallback");
  
}

function onTouchBegin(event:TouchEvent) {
          // set progress scrub flag to true
          bolProgressScrub = true;
          //
          timelinetarget.killControlFadeout();

          //stream.pause();
          tmrDisplay.removeEventListener(TimerEvent.TIMER, updateDisplay);
          stageref.addEventListener(TouchEvent.TOUCH_END, onTouchEnd);
          stageref.addEventListener(TouchEvent.TOUCH_MOVE, onTouchMove);

          // start drag
          timelinetarget.mcVideoControls.mcProgressScrubber.startDrag(false, new Rectangle(0, 4, 400, 0));
}


function onTouchMove(event:TouchEvent) {
          stream.seek(Math.round(timelinetarget.mcVideoControls.mcProgressScrubber.x * objInfo.duration / 400));

          timelinetarget.mcVideoControls.mcProgressFill.mcFillRed.width = timelinetarget.mcVideoControls.mcProgressScrubber.x + 5;
          timelinetarget.mcVideoControls.mcProgressFill.mcFillGrey.width = stream.bytesLoaded * 406 / stream.bytesTotal;
  
 
        var pt:Point = new Point(timelinetarget.mcVideoControls.mcProgressScrubber.x, timelinetarget.mcVideoControls.mcProgressScrubber.y);
        pt = timelinetarget.mcVideoControls.mcProgressScrubber.parent.localToGlobal(pt);
        timelinetarget.mcProgressShow.x = pt.x;
        timelinetarget.mcProgressShow.y = pt.y;
}

function onTouchEnd(event:TouchEvent) {
          bolProgressScrub = false;
          //
          timelinetarget.mcVideoControls.mcProgressScrubber.stopDrag();
          // update progress/volume fill
          timelinetarget.mcVideoControls.mcProgressFill.mcFillRed.width = timelinetarget.mcVideoControls.mcProgressScrubber.x + 5;
          //timelinetarget.mcVideoControls.mcProgressScrubber.x = postime * 364 / objInfo.duration;


          //stream.seek(postime);
          //stream.resume();
          stageref.removeEventListener(TouchEvent.TOUCH_END, onTouchEnd);
          stageref.removeEventListener(TouchEvent.TOUCH_MOVE, onTouchMove);

          //tmrDisplay.addEventListener(TimerEvent.TIMER, updateDisplay);

          timelinetarget.addControlFadeout();
          // stop all dragging actions
          event.updateAfterEvent();

}

 
  public function updateDisplay(e:TimerEvent):void {
  
             // checks, if user is scrubbing. if so, seek in the video
             // if not, just update the position of the scrubber according
             // to the current time
             if(bolProgressScrub){
              //postime = Math.round(timelinetarget.mcVideoControls.mcProgressScrubber.x * objInfo.duration / 364);
              stream.seek(Math.round(timelinetarget.mcVideoControls.mcProgressScrubber.x * objInfo.duration / 400));
             } else {
              timelinetarget.mcVideoControls.mcProgressScrubber.x = stream.time * 400 / objInfo.duration;
   
             }

             //timelinetarget.mcVideoControls.mcProgressScrubber.scaleX = timelinetarget.mcVideoControls.scaleX;

  
             // update the width from the progress bar. the grey one displays
             // the loading progress
             timelinetarget.mcVideoControls.mcProgressFill.mcFillRed.width = timelinetarget.mcVideoControls.mcProgressScrubber.x + 5;
             timelinetarget.mcVideoControls.mcProgressFill.mcFillGrey.width = stream.bytesLoaded * 406 / stream.bytesTotal;
  
 
             var pt:Point = new Point(timelinetarget.mcVideoControls.mcProgressScrubber.x, timelinetarget.mcVideoControls.mcProgressScrubber.y);
             pt = timelinetarget.mcVideoControls.mcProgressScrubber.parent.localToGlobal(pt);
             timelinetarget.mcProgressShow.x = pt.x;
             timelinetarget.mcProgressShow.y = pt.y;
             //trace("loaded:"+stream.bytesLoaded + " total:"+stream.bytesTotal);
  }
 
  public function resizeVid ():void {
      
             var vidWidth:int;
             var vidHeight:int;
             var Ycal;
             var X;
  
   if(stageref.fullScreenWidth>stageref.fullScreenHeight){
              //landscape
              vidHeight = stageref.fullScreenHeight;//
              vidWidth  = int((640*vidHeight)/480);
              Ycal = 0;
              X = (stageref.fullScreenWidth/2) - (vidWidth/2);
   } else {
              //portrait
              vidWidth  = stageref.fullScreenWidth;//1028;
              vidHeight = int((480*vidWidth)/640);//764;
              Ycal = (stageref.fullScreenHeight/2) - (vidHeight/2);
              X=0;
   }
  
              // software fallback
              //softwareVideo = new Video(vidWidth, vidHeight);
              softwareVideo.x = X;
              softwareVideo.y = Ycal;
              softwareVideo.width = vidWidth;
              softwareVideo.height = vidHeight;
              timelinetarget.addcontrols();
              trace("AIRMobileVideo: using software fallback");

  }

public function playVideo(url:String):void
  {
             stream.close();
             softwareVideo.clear();

             softwareVideo.attachNetStream(stream);
             playingBlank = false;
             stream.play(url);
  }

public function pauseVideo():void
            {
             stream.pause();
            }
            public function resumeVideo():void
            {
             stream.resume();
            }


public function stopVideo():void
  {
             trace("stopVideo()");
             playingBlank = false;
  
             zeroVideo();
             stream.close();
             softwareVideo.clear();
             timelinetarget.removeChild(softwareVideo);
             timelinetarget.removeBlackBack();

  }


  public function playBlankVideo():void
  {
             trace("playBlankVideo()");
  
             playingBlank = true;
             timelinetarget.removeControls();
             stream.play("blank.mp4");
  }


  public function zeroVideo():void
  {
             stream.pause();
             stream.seek(0);
  }
 
public function metaDataHandler(infoObject:Object):void

{
             objInfo = infoObject;
             tmrDisplay.start();
  }

 
  private function handleActivate(event:Event):void
  {
             NativeApplication.nativeApplication.systemIdleMode = SystemIdleMode.KEEP_AWAKE;
  }
 
  private function handleDeactivate(event:Event):void
  {
             NativeApplication.nativeApplication.exit();
  }
 
  private function statusHandler(event:NetStatusEvent):void
  {
             trace(event.info.code)
             if(event.info.code=="NetStream.Play.Stop"){
              trace("Video stopped");
              if(playingBlank == true){
               trace("stopVideo()");
               stopVideo();
         } else {
               trace("playBlankVideo()");
               playBlankVideo();
              }
   
         }
  
   if(event.info.code=="NetStream.Play.Start"){
         trace("Remove loading");
   }
  

  }

}
}
 

TOPICS
ActionScript

Views

466

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Mar 04, 2014 Mar 04, 2014

Copy link to clipboard

Copied

LATEST

Have you checked if its a file specific problem?

With a 764 height resolution your video is non IOS-Standard (height+width should be divisible by 16)

Here are some limitations you should consider when encoding for IOS:

http://blog.zencoder.com/2012/01/24/encoding-settings-for-perfect-ipadiphone-video/

Try a standard video and report back.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines