Friday, August 22, 2008

Code Review Vol. 3.01 - WMEncode and DRM Walkthrough

Imports WMEncoderLib
Imports System.Windows.Forms
Imports System.IO

Module Module1
Dim WithEvents Encoder As WMEncoder
Dim glbQuitBool As Boolean = False
Dim baseURL As String
Dim DRMProfilePass As String = "XXX"
Dim DRMProfile As String = "ExportProfile.drm"

Sub Main()
End Sub

Sub Init()
Dim sr As StreamReader = New StreamReader("baseLoc.ini")
Dim line As String
line = sr.ReadLine()
baseURL = line
End Sub

Function DoEncode(ByVal sourceFile As String, ByVal outputFile As String, ByVal thisProfile As WMEncProfile2, ByVal fileType As String) As Boolean
Encoder = New WMEncoder
Dim SrcGrpColl As IWMEncSourceGroupCollection = Encoder.SourceGroupCollection
Dim SrcGrp As IWMEncSourceGroup = SrcGrpColl.Add("SG_1")
Dim newFile As IWMEncFile = Encoder.File

If fileType = "video" Then
Dim vidFile As IWMEncVideoSource = SrcGrp.AddSource(2)
End If

Dim audFile As IWMEncAudioSource = SrcGrp.AddSource(1)

Up until this point it's fairly standard WMEncoder SDK code - create a sourcegroup collection, create a sourcegroup, and add a video or audio source to the source group - but here we introduce the DRM element. It follows the same template

Dim DRM As IWMDRMContentAuthor
Dim DRMProColl As IWMDRMProfileCollection
Dim tempDRMPro As IWMDRMProfile

DRM = Encoder.EncoderDRMContentAuthor

' Retrieve the collection of DRM profiles.
DRMProColl = DRM.DRMProfileCollection

'First remove any DRM Profiles that may still linger
tempDRMPro = DRMProColl.Item(0)

' Import a DRM profile.
DRM.ImportDRMProfile(DRMProfilePass, DRMProfile)

DRMProColl = DRM.DRMProfileCollection
Dim DRMPro As IWMDRMProfile
DRMPro = DRMProColl.Item(0)

Essentially the DRM set up follows the same format as the Encoder, create a ProfileCollection, create a profile object which references the literal .drm profile file that I had exported from the DRM server. A DRMContentAuthor is pulled from the base WMEncoder object and everything is imported into that.

' Set the current DRM profile into the encoding session.
Dim vKeyID As Object = "XXXXX
DRM.SetSessionDRMProfile(DRMPro.ID, vKeyID)

Dim newProfile As WMEncProfile2 = New WMEncProfile2
newFile.LocalFileName = outputFile
newProfile = thisProfile

' newProfile.LoadFromFile(thisProfile)
SrcGrp.Profile = newProfile
Encoder.AutoStop = True
Encoder.RemoteAdmin = True

Dim x As Integer

For the longest time the code didn't work. Until I found out that I needed to put a slight wait before encoding. And even while its encoding down below inside the while loop it still needs a pause between each iteration to register events and change states when necessary.

'HACK - needs this to actually work, bug in WM SDK
For x = 0 To 30
x = x + 1

Dim temp = Encoder.RunState
Dim y As Integer
For y = 0 To 300
y = y + 1
End While

Return True

Catch ex As Exception
Dim errFile As String = outputFile + ".error"
Return False
End Try

Encoder = Nothing

End Function

Here I grab the .drm file from the filesystem and load it into the WMEncProfile2 object.

Function RetrieveProfile(ByVal nFile) As WMEncProfile2
Dim BasicEdit As WMEncBasicEdit
BasicEdit = New WMEncBasicEdit

' Specify the input, output, and configuration files.
BasicEdit.MediaFile = nFile

' Retrieve the duration of the input file, in seconds.
Dim lFileDur As Long
lFileDur = BasicEdit.Duration / 1000

' Retrieve the profile used by the input file.
Dim Pro As WMEncProfile2
Pro = BasicEdit.Profile

Return Pro
Catch ex As Exception
End Try

End Function

And here is the engine - I essentially read the directory that was set aside as the publishing directory, where all raw files to be encoded and distributed were deposited, and encode and drm them.

Sub SearchDir(ByVal dir)
Dim di As New DirectoryInfo(dir)
' Create an array representing the files in the current directory.
Dim fi As FileInfo() = di.GetFiles()
Dim tempFile As FileInfo
For Each tempFile In fi
Dim currentProfile As WMEncProfile2
Dim currentSourceFile As String = baseURL + "\" + tempFile.Name
Dim currentOutputFile As String = baseURL + "\DRMed\" + tempFile.Name
Dim currentFType As String
Dim currentFTypeArr = Split(tempFile.Name, ".")
If currentFTypeArr(1) = "wma" Then
currentFType = "audio"
ElseIf currentFTypeArr(1) = "wmv" Then
currentFType = "video"
End If

currentProfile = RetrieveProfile(currentSourceFile)
DoEncode(currentSourceFile, currentOutputFile, currentProfile, currentFType)
Next tempFile

End Sub

End Module

And that's it. Pretty straightforward, but by automating the encoding process and combining it with the DRMing process I was anble to integrate that into the automated workflow that I was building as the infrastructure to the overall Music Choice broadband product.

No comments: