Skip to main content
Inspiring
September 29, 2014
Question

AIR for Android video issue

  • September 29, 2014
  • 1 reply
  • 2289 views

On Android, in an app that I’ve developed successfully for iOS, I’m seeing this problem:

There are 5 videos built-into the app. On Samsung phones (S3 and S4), running Android 4.4.2, at the first attempt to play a video there’s sound but no picture. After returning to the video menu and attempting again, video and sound play normally. If a video is stopped and another one is started, initially a frame of the previous video is displayed (for a fraction of a second), then play resumes normally with the chosen video.

The sound-but-no-video problem does NOT show up on a Nexus 7 running 4.4.3, although the flash-frame problem does.

I’m publishing with AIR SDK 15 packaging both with and without captive runtime to try to isolate the source of the problem. I’m using <contains video> true </contains video> in the descriptor.

This feels like AIR-for-Android buggishness. Any confirmation out there? Similar problems? Workarounds?

I’ve read somewhere that AIR runtime  v.3.3 may solve some video problems on Android, but not sure where to find an archived Android version of AIR that old.

This topic has been closed for replies.

1 reply

Colin Holgate
Inspiring
September 29, 2014

How are you playing the videos?

UmanoffAuthor
Inspiring
September 29, 2014

Not sure that I understand your question, Colin. I'm playing them within the app using StageVideo, which is the class that my app selects with GPU rendering. Is that what you mean?

UmanoffAuthor
Inspiring
October 2, 2014

I mentioned that I didn't try the playing of a black video as a work around to the video buffer issue. It doesn't happen on iOS, and also doesn't happen on some Android devices. People are only likely to watch the videos once, it might be more annoying if the video played every session.


Well, as it sometimes happens with me, I have spoken too soon. The answer that I marked as ‘correct’ the other day (Colin, are you there?), seems to be not quite the right answer. At least, it doesn’t solve the video problem that I’m having with some, but not all, Android devices.

After trying Colin’s suggestion – using  if (stage.stageVideos.length != 0) to make sure that a stageVideoAvailabilityEvent hasn’t already fired when I try to play my first StageVideo instance – and getting perfect results in 10 consecutive tries on my Samsung S4 and S3 phones, I figured that was IT.

Next day, same devices and same code, it DIDN’T work! I pulled hair, issued profanities, hammered on the table. It didn’t matter—I still got a ‘mis-fire’ on the first play of a video whenever (almost whenever) I opened the app. After the first play everything was good – which is the exact problem that I started with many days ago. When I played Colin’s Sesame Street ‘Let’s Get Ready’ app again – the same first-play-of-video problem shows up there too.

This problem does not show up on Nexus 7  and the Samsung Galaxy 5 Tab. It is a royal p.i.t.a. on Samsung phones, where I need my app to work.

I created a bare-bones app to reproduce the problem, code below. Just a single class to play a single video with no controls. A few parameters (path to the video, and viewport stuff) are passed in from the document Class. I run it 10 times on my S4. It fails 7 times and plays well 3 times. The 'initialize2()' function never fires, proving that the stageVideos array already exists by the the time the 'initialize1()' function is called.

I'm pretty sure that this is not a coding problem (because it works well on some Androids and in iOS), but WHAT is it??

package vidTestSource

{

  import flash.desktop.NativeApplication;

  import flash.desktop.SystemIdleMode;

  import flash.display.MovieClip;

  import flash.display.Sprite;

  import flash.display.StageAlign;

  import flash.display.StageScaleMode;

  import flash.events.Event;

  import flash.events.NetStatusEvent;

  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;

  public class MobileVideosolo extends MovieClip

    {

      public var stream:NetStream ;

      public var video:StageVideo;

      var xx:Number;

      var yy:Number;

      var ww:Number;

      var hh:Number;

      var mymoov:String;

  public function MobileVideosolo(mymoov,xx,yy,ww,hh)

  {

      this.xx = xx;

      this.yy = yy;

      this.ww = ww;

      this.hh = hh;

      this.mymoov = mymoov;

     addEventListener(Event.ADDED_TO_STAGE, onstage);

  }

function onstage(e)

  {

    if (stage.stageVideos.length != 0)

     {

       initialize1();

      }

     else

     {

      stage.addEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, stageVideoState );

     }

function stageVideoState(e)

     {

       initialize2();

       stage.removeEventListener (StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, stageVideoState);

     }

function initialize1()

    {

      var nc:NetConnection = new NetConnection() ;

      nc.connect(null) ;

      stream = new NetStream(nc) ;

      stream.client = this ;

      video = stage.stageVideos[0] ;

      video.viewPort = new Rectangle(xx,yy,ww,hh) ;

      video.attachNetStream(stream) ;

      stream.play (mymoov) ;

      MovieClip(parent).sVtext.text = "Init 1";

      stream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);

   }

 

function initialize2()

   {

    var nc:NetConnection = new NetConnection() ;

     nc.connect(null) ;

     stream = new NetStream(nc) ;

     stream.client = this ;

     video = stage.stageVideos[0] ;

     video.viewPort = new Rectangle(xx,yy,ww,hh) ;

     video.attachNetStream(stream) ;


     stream.play (mymoov) ;

     MovieClip(parent).sVtext.text = "Init 2";

     stream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);

   }