2 Replies Latest reply on May 28, 2012 1:49 AM by Silviu Vergoti

    Clearing a Media Element While Buffering Crashes iOS App

    The Almighty Egg Level 1

      I have an OSMF-based player in an iOS app that plays a variety of MP4s via http. The user can close the player and navigate around the app at will. However, if they close the player while it is in the buffering state, the app crashes. I have isolated this as follows:

       

      Setting 'MediaPlayer.media' to null, or calling 'unload()' on the media's LoadTrait will crash the app if the player state is BUFFERING.

       

      This only seems to affect AIR for iOS, and it happens if the media file is packaged in the IPA. My current test uses OSMF 2, AIR 3.2. I am putting together a simpler test class to post now, but in the meantime, is there a different way to dispose of a media element? Should I be doing something else to clear the player?

        • 1. Re: Clearing a Media Element While Buffering Crashes iOS App
          The Almighty Egg Level 1

          Here is a class that demonstrates the issue. It uses a couple of buttons (fl.controls.Button), and requires a media file. I've been using an MP4 packaged in the IPA, but this error should manifest with the media file at an external URL. Build this to an iPad, and see what it does. Here is the code:

           

          package
          {
              import fl.controls.Button;
              import org.osmf.events.MediaPlayerStateChangeEvent;
              import org.osmf.media.MediaPlayerState;
              import org.osmf.media.MediaFactory;
              import flash.display.MovieClip;
              import org.osmf.media.MediaPlayer;
              import org.osmf.containers.MediaContainer;
              import org.osmf.media.URLResource;
              import org.osmf.utils.OSMFSettings;
              import org.osmf.media.DefaultMediaFactory;
              import org.osmf.media.MediaElement;
              import org.osmf.traits.MediaTraitType;
              import org.osmf.traits.LoadTrait;
              import flash.events.MouseEvent;
              import org.osmf.events.MediaElementEvent;
              import flash.events.TimerEvent;
              import flash.utils.Timer;
          
              public class BufferCrashTest extends MovieClip
              {
                  protected const MEDIA_URL :String = "build/03_18.mp4";
                  
                  public var
                      autoPlay_timer :Timer,
                      media_factory :DefaultMediaFactory,
                      container :MediaContainer,
                      stop_playback :Boolean,
                      player :MediaPlayer;
                  
                  public function BufferCrashTest():void
                  {
                      // Autoplay has problems in AIR for iOS with StageVideo and progressive MP4s.
                      // This timer is a workaround.
                      autoPlay_timer = new Timer( 250, 1 );
                      autoPlay_timer.addEventListener( TimerEvent.TIMER, OnAutoPlayTimer );
                      
                      
                      var b1:Button = new Button();
                      b1.label = "Play Normally";
                      b1.addEventListener( MouseEvent.CLICK, OnPlay );
                      this.addChild(b1);
                      
                      var b2:Button = new Button();
                      b2.label = "Play, Clear";
                      b2.addEventListener( MouseEvent.CLICK, OnPlayClear );
                      b2.y = b1.height;
                      this.addChild(b2);
                      
                      
                      OSMFSettings.enableStageVideo = true;
                      
                      media_factory = new DefaultMediaFactory();
          
                      container = new MediaContainer();
                      
                      container.y = b2.y + b2.height;
                      this.addChild( container );
          
                      player = new MediaPlayer();
                      player.autoPlay = false;
                      player.addEventListener( MediaPlayerStateChangeEvent.MEDIA_PLAYER_STATE_CHANGE, OnPlayerStateChange );
                  }
                  
                  protected function OnPlay( _e:MouseEvent ):void
                  {
                      stop_playback = false;
                      StartPlayback();
                      
                  }
                  protected function OnPlayClear( _e:MouseEvent ):void
                  {
                      stop_playback = true;
                      StartPlayback();
                      
                  }
                  
                  protected function StartPlayback():void
                  {
                      var ur:URLResource;
                      ur = new URLResource( MEDIA_URL );
                      
                      var element:MediaElement = media_factory.createMediaElement( ur );
                      element.addEventListener( MediaElementEvent.TRAIT_ADD, OnTraitAdd, false, 0, true );
                      
                      container.addMediaElement( element );
                      
                      player.media = element;
                  }
                  
                  
                  
          
                  
                          
                  protected function ClearPlayer():void
                  {
                      if ( player.media )
                      {
                          
                          if ( player.media.hasTrait( MediaTraitType.PLAY ) )
                              player.stop();
                          
                          /************
                          
                          Either the 'unload()' call or setting 'player.media' to null will crash the app.
                          
                          ************/
                          
                          if ( player.media.hasTrait( MediaTraitType.LOAD ) )
                          {
                              var lt:LoadTrait = player.media.getTrait( MediaTraitType.LOAD ) as LoadTrait;
                              lt.unload();
                          }
                          
                          /*
                          player.media = null;
                          */
                      }
                      
                  }
                  
                  protected function OnPlayerStateChange( _e:MediaPlayerStateChangeEvent ):void
                  {
                      trace("OnPlayerStateChange", _e.state);
                      if ( stop_playback && ( _e.state == MediaPlayerState.BUFFERING ) )
                      {
                          ClearPlayer();
                      }
                  }
                  
                  
                  protected function OnTraitAdd( _e:MediaElementEvent ):void
                  {
                      if (_e.traitType == MediaTraitType.PLAY )
                      {
                          autoPlay_timer.reset();
                          autoPlay_timer.start();
                      }
                  }
                  
          
                  protected function OnAutoPlayTimer( _e:TimerEvent ):void
                  {
                      autoPlay_timer.reset();
                      
                      player.play();
                  }
          
                  
                  
              }
          }
          
          • 2. Re: Clearing a Media Element While Buffering Crashes iOS App
            Silviu Vergoti Adobe Employee

            Hi,

             

            It could be similar to http://bugs.adobe.com/jira/browse/FM-1250 .

             

            Please raise a bug so we'll better track the issue.

             

            My recommendation for a workaround would be to wait the item to load, then stop it and only then to unload it.

             

            S.