OSMF искать с Amazon Cloudfront - PullRequest
2 голосов
/ 07 июня 2011

Я написал небольшой проигрыватель OSMF, который транслируется через RTMP из Amazon Cloudfront.Существует известная проблема: длительность mp3 неправильно считывается из метаданных, и поэтому функция поиска не работает.Я знаю, что есть обходной путь, подразумевающий использование функции getStreamLength в NetConnection, которую я успешно реализовал в предыдущем проигрывателе, не являющемся OSMF, но теперь я не знаю, как и когда его вызывать, с точки зрения событий и черт OSMF.Этот код не работает:

  protected function initApp():void
  {
    //the pointer to the media
    var resource:URLResource = new URLResource( STREAMING_PATH );

    // Create a mediafactory instance
    mediaFactory = new DefaultMediaFactory();

    //creates and sets the MediaElement (generic) with a resource and path
    element = mediaFactory.createMediaElement( resource );

    var loadTrait:NetStreamLoadTrait = element.getTrait(MediaTraitType.LOAD) as NetStreamLoadTrait;
    loadTrait.addEventListener(LoaderEvent.LOAD_STATE_CHANGE, _onLoaded);
    player = new MediaPlayer( element );

    //Marker 5: Add MediaPlayer listeners for media size and current time change
    player.addEventListener( DisplayObjectEvent.MEDIA_SIZE_CHANGE, _onSizeChange );
    player.addEventListener( TimeEvent.CURRENT_TIME_CHANGE, _onProgress );

    initControlBar();
  }
  private function onGetStreamLength(result:Object):void {
    Alert.show("The stream length is " + result + " seconds"); 
    duration = Number(result);
  }

  private function _onLoaded(e:LoaderEvent):void
  {
    if (e.newState == LoadState.READY)
    {
      var loadTrait:NetStreamLoadTrait = player.media.getTrait(MediaTraitType.LOAD) as NetStreamLoadTrait;

      if (loadTrait && loadTrait.netStream)

      {
      var responder:Responder = new Responder(onGetStreamLength);
      loadTrait.connection.call("getStreamLength", responder, STREAMING_PATH);
      }
    }
  }

1 Ответ

2 голосов
/ 24 июня 2011

Простой ответ

Вы не можете передать полный поток URL STREAMING_PATH этому методу: loadTrait.connection.call ("getStreamLength", респондент, STREAMING_PATH);

Вам нужно использовать только имя потока, который указывает путь справа от экземпляра FMS

Так что, если URL (или connection.uri): RTMP: //example.com: 80 / _myfms / mp3: / поток / имя / Foo

Вы хотите передать только имя потока, а не экземпляр сервера: 'Mp3: / поток / имя / Foo'

Сложный ответ (Расширить класс NetLoader):

package{
// You can extend the NetLoader class to have it automatically ask for duration 
// and dispatch an event when it is received. 

// This is a super simple, partial example, but the stub should get you going

// TODO: define imports here (omitted for example's sake)

class MyNetLoader extends NetLoader
{
  // useful for adding an event listener outside
  public static const GOT_STREAM_DURATION:String = "gotStreamDuration";

  // constructor
  public function MyNetLoader(factory:NetConnectionFactoryBase = null)
  {
     super( factory );
  }

  // override the parent method that creates the actual NetStream 
  override protected function createNetStream( connection:NetConnection, resource:URLResource) : NetStream
  {
     // usually you pass just the stream name, not the full uri 
     // there is likely a cleaner way to extract the stream name...
     var streamName:String = resource.url.replace('rtmp://example.com:80/_myfms/', '');

     // request duration from FMS
     connection.call('getStreamLength', new Responder( this.onResult ), streamName);

     return super.createNetStream(connection, resource);
   }

   // receives the getStreamLength callback from FMS
   protected function onResult( info:Object ):void
   {
     _duration = Number(info) * 1000; // duration, in ms

     dispatchEvent( new Event(GOT_STREAM_DURATION) );

     trace('Duration is: ' + _duration);
   }
   // read-only getter for duration
   public function get duration():uint
   {
     return _duration as uint;
   }
 }
}

Тогда в другом вашем коде:

...
    // create the resource
    var resource:URLResource = new URLResource('rtmp://example.com:80/_something/the/stream/name/foo');

    // create your custom loader, adding a listener for the duration callback
    var loader:MyNetLoader = new MyNetLoader();

    // listen for the duration event
    loader.addEventListner(MyNetLoader.GOT_STREAM_DURATION, function(event:Event):void{
            trace('Got the duration outside: ' + (event.target as MyNetLoader).duration);
    });

    // I use an AudioElement here, but it could be any of the typed or generic elements
    // as long as the constructor accepts (resource, loader)
    // You dont want to use the factory to create the element, because (to my knowledge)
    // you cant pass a custom loader to the factory (unless you extended it)
    var myElement:AudioElement = new AudioElement( resource, loader );

    // pass the element to the player. I dont pass to the constructor in this example because
    // in most real-world cases, you would already have an instance of MediaPlayer
    player = new MediaPlayer();
    player.media = myElement;
...
...