Skip navigation
Currently Being Moderated

How to send authenticate token in OSMF player

Jul 20, 2011 12:55 AM

Hi everyone


I'm new to Flash Access and trying to setup a basic player with OSMF (1.5). I read "Understanding the protected content workflow" and find it is for flv & flv.metadata. From that document, I can only send authenticate token after the DRMContentData is created. So this is the recommend workflow:

 

  1. Load .metadata file
  2. new DRMContentData with the loaded data
  3. set authenticate token by drmManager.setAuthenticationToken
  4. load voucher


But when I try F4M file with OSMF player, things are changed. After the .f4m file is loaded by mediaFactory.createMediaElement(new URLResource(URL)), OSMF starts to do the authenticate by itself without give me a chance to set my token. The first event from DRMEvent.DRM_STATE_CHANGE I received is DRMState.AUTHENTICATION_ERROR, and there is no DRMContentData anywhere I can use to send my token.


I can see one request has been sent out to license server from Fiddler but the return value has limited readle words, some of them are:

 

en_US�=0;  com.adobe.flashaccess.errors  e�   Cannot decrypt request�� �0� �0� ��      k�օ����:cs�N��0

 

The code to create a simple OSMF player is realy simple:

     [SWF(backgroundColor="0x000000", frameRate="25", width="640", height="380")]
     public class ASWebPlayer extends Sprite
     {
          private var mediaPlayer:MediaPlayer;
          private var mediaContainer:MediaContainer;
          private var mediaFactory:DefaultMediaFactory;
          private var drmManager:DRMManager;
          
          public function ASWebPlayer()
          {
               mediaPlayer = new MediaPlayer;
               mediaPlayer.autoPlay = true;
               mediaPlayer.autoDynamicStreamSwitch = true;
               mediaPlayer.addEventListener(DRMEvent.DRM_STATE_CHANGE, onDRMChange, false, 0, true);
               
               mediaFactory = new DefaultMediaFactory;
               mediaContainer = new MediaContainer;
               addChild(mediaContainer);
               
               var mediaElement:MediaElement = mediaFactory.createMediaElement(new URLResource(F4M_URL));
               mediaContainer.addMediaElement(mediaElement);
               mediaPlayer.media = mediaElement;
          }
          
          protected function onDRMChange(event:DRMEvent):void
          {
               trace(event.drmState);
          }
     }

 
Replies
  • Currently Being Moderated
    Jul 20, 2011 11:24 AM   in reply to larryzzl

    Hi,

     

    Are you attempting to set a custom authentication token?    "drmManager.setAuthenticationToken()" is only used if you want to manually set your own custom token, or if you want to change the authentication token that is issued to a client.

     

    Normally, here is the workflow:

    1. Create DRMContentData from metadata

    2. Set your user credentials with drmManager.authenticate()

    3. Flash Access will talk to the server, and then retrieve an authentication token. 

    4. Now, every time the client talks to the server (like during drmManager.loadVoucher()), the authentication token from step #4 will automatically be attached to the license request.  You do not have to ever call .setAuthenticationToken() unless you want to override this token.

     

     

    cheers,

    /Eric.

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 21, 2011 10:58 AM   in reply to larryzzl

    Hi,

     

    The .f4m file is actually a manifest file.  Within that file (if you open it in a web browser), you'll see that it actually references a DRM Metadata.  OSMF automatically parses this manifest and extracts the metadata present in the <drmAdditionalHeader> tag.  If you need access to that metadata, it is available via:

     

    • resource.drmContentData (for single bitrate scenarios)
    • In the resource DRM metadata namespace (for multi-bitrate scenarios)

     

    Here is a helper function that'll return the extracted content metadata for a specified resource.  When the media element is ready, you have access to the drmContentData and can start any custom authorization/authentication workflow. Otherwise once the playback has been started, OSMF will follow the default workflow.

     

    /**
     * @private
     * 
     * Checks for DMR metadata both in SBR and MBR cases. In SBR case, the DRM metadata is 
     * saved in drmContentData property. In MBR case, the DRM metadata can  
     * also be present as stream-based metadata in DRM namespace. In this case, we will 
     * return the medatata for the specified stream.
     */
    private function getDRMContentData(resource:MediaResourceBase, streamName:String):ByteArray
    {
         if (streamName == null)
         {
              return null;
         }
         
         var streamingResource:StreamingURLResource = resource as StreamingURLResource;
         if (streamingResource != null)
         {
              // [CASE 1] We are in SBR or MBR case where the DRM metadata is
              // present in drmContentData property so we just return it.
              if (streamingResource.drmContentData != null)
              {
                   return streamingResource.drmContentData;
              }
              
              // [CASE 2] We have a DRM namespace associated with this resource
              // which may contain the actual drmData. 
              var drmMetadata:Metadata = resource.getMetadataValue(MetadataNamespaces.DRM_METADATA) as Metadata;
              if (drmMetadata != null && drmMetadata.keys.length > 0)
              {
                   return drmMetadata.getValue(streamName) as ByteArray;
              }
         }
         
         return null;
    }
     
     
     
    

     

    But, if you would like access to the DRM metadata before starting playback, below is sample code which will wait for the READY state in the player before trying to get the metadata.

     

    package
    {
         import flash.display.Sprite;
         import flash.utils.ByteArray;
         
         import org.osmf.elements.ProxyElement;
         import org.osmf.events.MediaPlayerStateChangeEvent;
         import org.osmf.media.DefaultMediaFactory;
         import org.osmf.media.MediaElement;
         import org.osmf.media.MediaPlayer;
         import org.osmf.media.MediaPlayerState;
         import org.osmf.media.MediaResourceBase;
         import org.osmf.media.URLResource;
         import org.osmf.metadata.Metadata;
         import org.osmf.metadata.MetadataNamespaces;
         import org.osmf.net.StreamingURLResource;
         import org.osmf.traits.DRMTrait;
         import org.osmf.traits.MediaTraitType;
     
         public class HelloWorld10 extends Sprite
         {
              public function HelloWorld10()
              {
                   var protectedF4M:String = "http://10.131.237.107/vod/mbr/drm/sample1_drm_700kbps.f4m";
                   
                   var factory:DefaultMediaFactory = new DefaultMediaFactory();
                   var mediaElement:MediaElement = factory.createMediaElement(new URLResource(protectedF4M));
                   
                   player = new MediaPlayer();
                   player.addEventListener(MediaPlayerStateChangeEvent.MEDIA_PLAYER_STATE_CHANGE, onMediaPlayerState);
                   player.autoPlay = false;
                   player.media = mediaElement;
              }
              
              /**
               * @private
               * 
               * Event handler for MediaPlayer state change. On READY/PLAYING state 
               * we should have access both to the DRMTrait or to the real resource.
               */
              protected function onMediaPlayerState(event:MediaPlayerStateChangeEvent):void
              {
                   if (event.state == MediaPlayerState.READY)
                   {
                        var actualMediaElement:MediaElement = getActualMediaElement(player.media as ProxyElement);
                        var resource:StreamingURLResource = actualMediaElement.resource as StreamingURLResource;
                        
                        // this the actual DRM content metadata 
                        var drmProtectedContent:ByteArray = getDRMContentData(resource, null);
                        
                        var drmTrait:DRMTrait = player.media.getTrait(MediaTraitType.DRM) as DRMTrait;
                        if (drmTrait != null)
                        {
                             // create the token or do some other custom workfows
                             var token:Object = null;
                             
                             // do something with the drm content metadata
                             // and with the drm trait
                             drmTrait.authenticateWithToken(token);
                        }
                   }
              }
              
              /**
               * @private
               * 
               * Gets the actual media element. When working with F4M files, the OSMF will
               * usually create a proxy element containing the actual video element.
               */
              private function getActualMediaElement(media:MediaElement):MediaElement
              {
                   var iterator:MediaElement = media;
                   while (iterator != null && iterator is ProxyElement)
                   {
                        iterator = ProxyElement(iterator).proxiedElement;
                   }
                   
                   return iterator;
              }
              
              /**
               * @private
               * 
               * Checks for DMR metadata both in SBR and MBR cases. In SBR case, the DRM metadata is 
               * saved in <code>drmContentData</code> property. In MBR case, the DRM metadata can  
               * also be present as stream-based metadata in DRM namespace. In this case, we will 
               * return the medatata for the specified stream.
               */
              private function getDRMContentData(resource:MediaResourceBase, streamName:String):ByteArray
              {
                   var streamingResource:StreamingURLResource = resource as StreamingURLResource;
                   if (streamingResource != null)
                   {
                        // [CASE 1] We are in SBR or MBR case where the DRM metadata is
                        // present in drmContentData property so we just return it.
                        if (streamingResource.drmContentData != null)
                        {
                             return streamingResource.drmContentData;
                        }
                        
                        // [CASE 2] We have a DRM namespace associated with this resource
                        // which may contain the actual drmData. 
                        var drmMetadata:Metadata = resource.getMetadataValue(MetadataNamespaces.DRM_METADATA) as Metadata;
                        if (drmMetadata != null && drmMetadata.keys.length > 0)
                        {
                             if (streamName == null)
                             {
                                  // maybe we should look for the first child
                                  // and return that value
                                  return null;
                             }
     
                             return drmMetadata.getValue(streamName) as ByteArray;
                        }
                   }
                   
                   return null;
              }
              
              private var player:MediaPlayer = null;
         }
    }
    

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 26, 2011 2:51 PM   in reply to larryzzl

    Usually this kind of error indicates that the player is linking with the wrong version of the OSMF.swc ( probably version 1.0 which is delivered with the Flex SDK).  The recommended way is to update the project setting to link with a specific version of OSMF.swc and not with version 1.0

     

    If you are using Flash Builder then:

    1. go to project properties page of the player

    2. go to "ActionScript Build Path" section

    3. make sure that "Library path" tab is selected

    4. in the "Build path libraries" tree expand "Flex SDK" node

    5. it should list a bunch of swc which will be linked with your project

    6. select the osmf.swc and click "Remove"

    7a. if you want to use the compile SWC, then press "Add SWC..." and select the OSMF.swc version 1.5 or version 1.6 downloaded on your system

    7b. if you want to use the project, the press "Add Project..." and select the OSMF project imported from the sources in your workspace.

    8. press "OK" to save the changes

     

    Clean and compile. It should work.

     

    You may also copy the osmf.swc vversion 1.5 or 1.6 over the osmf.swc in the Flex SDK directory.

     

    Hope it helps,

    Kimi

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 28, 2011 1:41 AM   in reply to larryzzl

    The MetadataNamespaces class is only excluded from ASDoc generation process through [ExcludeClass] metadata ( kind of ironic i know ) but it should be available for using if imported directly. The code provided above should compile without warning or errors related to MetadataNamespaces class.

     
    |
    Mark as:
  • Currently Being Moderated
    Aug 10, 2011 11:59 AM   in reply to larryzzl

    If you need to authenticate using a token, then the following workflow should work:

     

    var video:MediaElement = osmf.factory.createMediaElement(resource);
    osmf.player.media = video;
    player.addEventListener(DRMEvent.DRM_STATE_CHANGE, onDRMStateChange);
    osmf.container.addMediaElement(video);
     
    protected function onDRMStateChange(event:DRMEvent):void
    {
         if (event.drmState == DRMState.AUTHENTICATING)
         {
              // here we can call authenticateWithToken method as drmTrait is fully initialized
              // we don't need to manually load the drmContentData because it was already loaded 
                    // and it will be associated automatically with our token
              var drmTrait:DRMTrait = event.target as DRMTrait;
              drmTrait.authenticateWithToken("token");
         }
    }
    
     
    

     

    A similar workflow can be implemented using traits, but in that case you'll need to take in consideration the following:

    - traits are transient so they can be added and removed at any time, it is not recommended to keep a reference to a trait

    - when a DRMTrait is added to an existing media element, is not necessary initialized

    - you'll also need to listen for DRMEvent.DRM_STATE_CHANGE event on that trait and when the drmState == DRMState.AUTHENTICATING, then it is a good time to authenticateWithToken

     

    Hope it helps,

    Kimi

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points