1 Reply Latest reply on Aug 10, 2011 7:51 AM by Kimi (Catalin Dobre)

    How to access drmTrait.drmMetadata in OSMF 1.5

    larryzzl

      Hi

       

      I'm working on playing DRM protected (Flash Access) content with OSMF 1.5 in a web app. Our business logic requirs sending custom data to server together with the license requirement. So the app logic I think could be something like this:

       

      (The content is MBR, .f4m file)

      1. Create videoElement and pass in the .f4m file url
      2. Send videoElement to MediaPlayer
      3. Listen DRMEvent.DRM_STATE_CHANGE on MediaPlayer
      4. Send custom data by using drmTrait.authenticateWithToken() when drmTrait.drmMetadata is available

       

      In OSMF 1.6 sprint 5, there is a DRMState.AUTHENTICATING state during the authentication. And I can access drmTrait.drmMetadata there and send custom data. Unfortunately, OSMF 1.6 is not an option b/c it's not released yet.

       

      But in OSMF 1.5, there is no such state, the only 2 states I get are DRMState.UNINITIALIZED & DRMState.AUTHENTICATION_ERROR. I tried to see if the drmTrait.drmMetadata will be available in AUTHENTICATION_ERROR state but failed. So basically, there is no place I can access drmMetadata and do my business logic.

       

      I'd appreciate if any help can be provided.

      Thanks.

        • 1. Re: How to access drmTrait.drmMetadata in OSMF 1.5
          Kimi (Catalin Dobre) Level 1

          Hi,

           

          This is was fixed in OSMF 1.6 as it was a bug in the DRM workflow.

          Now a little peak behind the curtain:

           

          * OSMF receives a f4m containing media information (including protected content metadata)

          * Based on that F4M file, OSMF will create a resource representation of that F4M (usually a StreamingURLResource for SBR and a DynamicStreamingResource for MBR)

          * While creating the actual video element, it will check for protected content metadata and activate the FAXS workflows (like downloading the

          library, making the authorization request, etc)

          * The issue is present only for MBR case because the side-car metadata was not used to initialize the FAXS workflow

          * The issue was two fold

               * First: the OSMF did have the side car protected metadata in MBR case, but was stored differently than the SBR case  ( into a DRM namespace

          and not in a drmContentData property)

               * Second: an update of the FAXS library requires recreation of the media element and this was happening after the playback has started

           

          What the current fix does:

           

          * it supports content protected metadata both in properties and DRM namespace

          * It tries to mimic the SBR behavior by initializing FAXS library with a most-likely candidate for playback ( the stream which is set as initial index) before the playback is actually started

           

          I have pasted below the patch for LightweightVideoElement.as

           

          Index: LightweightVideoElement.as
          ===================================================================
          --- LightweightVideoElement.as     (revision 2108)
          +++ LightweightVideoElement.as     (working copy)
          @@ -38,6 +38,8 @@
                import org.osmf.media.MediaResourceBase;
                import org.osmf.media.URLResource;
                import org.osmf.metadata.CuePoint;
          +     import org.osmf.metadata.Metadata;
          +     import org.osmf.metadata.MetadataNamespaces;
                import org.osmf.metadata.TimelineMetadata;
                import org.osmf.net.DynamicStreamingResource;
                import org.osmf.net.ModifiableTimeTrait;
          @@ -336,14 +338,13 @@
                              // Listen for all errors
                              stream.addEventListener(DRMErrorEvent.DRM_ERROR, onDRMErrorEvent);
                                                                                
          -                    // Check for DRMContentData
          -                   var streamingResource:StreamingURLResource = resource as StreamingURLResource;
          -                   if (streamingResource != null 
          -                         && streamingResource.drmContentData)
          -                   {
          -                        var metadata:ByteArray = streamingResource.drmContentData;
          -                        setupDRMTrait(metadata);                                                                 
          -                   }
          +                    // Check for DRMContentData
          +                    var metadata:ByteArray = getDRMContentData(resource);
          +                    if (metadata != null && metadata.bytesAvailable > 0)
          +                    {
          +                         // Side-case case, metadata present in F4M or loaded direclty
          +                         setupDRMTrait(metadata);                                                                 
          +                    }
                               else
                               {
                                    // Non sidecar, we need to play before getting access to the DRMTrait.
          @@ -357,6 +358,77 @@
                     // DRM APIs
                     CONFIG::FLASH_10_1
                    {
          +               /**
          +                * @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 initial index.
          +                */
          +               private function getDRMContentData(resource:MediaResourceBase):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. We are going to look into it
          +                         // and return our best guess hopefully the DRM for the initial stream.
          +                         var drmMetadata:Metadata = resource.getMetadataValue(MetadataNamespaces.DRM_METADATA) as Metadata;
          +                         if (drmMetadata != null && drmMetadata.keys.length > 0)
          +                         {
          +                              // do we have a initial index for this resource?
          +                              // if yes, then its DRM metadata is our best candidate 
          +                              var streamName:String = null;
          +                              var dynamicStreamingResource:DynamicStreamingResource = resource as DynamicStreamingResource;
          +                              if (   dynamicStreamingResource != null 
          +                                   && dynamicStreamingResource.initialIndex > -1 
          +                                   && dynamicStreamingResource.initialIndex < dynamicStreamingResource.streamItems.length)
          +                              {
          +                                   
          +                                   streamName = dynamicStreamingResource.streamItems[dynamicStreamingResource.initialIndex].streamName;
          +                              }
          +                              
          +                              var drmContentData:ByteArray = null;
          +                              
          +                              // if we know the initial stream name then try to use its DRM metadata
          +                              if (streamName != null)
          +                              {
          +                                   drmContentData = drmMetadata.getValue(streamName) as ByteArray;
          +                              }
          +                              
          +                              // if we still haven't find one, then get any available one
          +                              if (drmContentData == null)
          +                              {
          +                                   var keys:Vector.<String> = drmMetadata.keys;
          +                                   var index:int = 0;
          +                                   
          +                                   do 
          +                                   {
          +                                        var drmKey:String = keys[index];
          +                                        if (drmKey.indexOf(MetadataNamespaces.DRM_ADDITIONAL_HEADER_KEY) != 0)
          +                                        {
          +                                             drmContentData = drmMetadata.getValue(drmKey);
          +                                        }
          +                                        index++;     
          +                                   } while (drmContentData == null && index < keys.length)
          +                              }
          +                              
          +                              return drmContentData;
          +                         }
          +                    }
          +                    
          +                    
          +                    return null;
          +               }
          +
                            private function onStatus(event:StatusEvent):void
                          {
                               if (event.code == DRM_STATUS_CODE 
          
           
          

           

          Hope it helps

          1 person found this helpful