1. ForwardLock
ForwardLock 是DRM1.0中最简单的一种传输方式。请参考DRM标准学习笔记1
2. ForwardLock工作流程
用特定工具,或者是手动编写,将一个普通的视频文件(例如mp4) 生成一个符合标准的DRM文件,放到服务器上;用户付费后,用下载工具将此DRM文件下载到本地;下载工具必须支持这种DRM文件,下载的时候,其内部实际上是把此DRM文件进行了加密,加密算法可以采用AES等算法。密钥应该是每台机器生成一个唯一的密钥,加密和解密密钥是相同的。这样,在本地端就有了一个加密的媒体文件,用户可以在本机上进行播放,但如果COPY到另外的机器上,由于密钥不同,所以不以成功解密,这样就达到了ForwardLock的目的。
3. 符合ForwardLocak标准的DRM文件格式
如下所示的格式: --boundary12345\r\n
Content-type: video/mp4\r\n
Content-Transfer-Encoding: binary\r\n
\r\n
.
.
.\r\n
--boundary12345--\r\n
说明:
DRM文件格式其实就是在原始的媒体文件加了一个头和一个尾。如上所示。头一共增加了四行,在这里我把隐藏字符也用转义字写出来,目的就是为了看清楚。第一行是以--开头,后跟一个随机的字符串,但结尾时也必须是这个字符串。然后是回车换行。第二行是说明此文件的mime type是什么第三行说的是编码格式,是二进制,还是64 base。第四行是一个空行。然后是原始的媒体文件,这里用三个点的三行来进行表示。最后,在原始文件的末尾先来一个回车换行最后一行是以--开头和结尾,中间放上跟头一样的字符串,回车换行。
4. Android中如何实现ForwardLocak?
最后,目前的Android代码(Android4.1JB)是支持此功能的,即通过Browser下载的时候,如果是FrowardLocak文件则会进行文件的加密。如果想自己写一个来玩玩,可以用以下的代码实现: mDrmManagerClient = new DrmManagerClient();
mConvertSessionID = mDrmManagerClient->openConvertSession(s_imetype);
...
DrmBuffer buffer((char *)data, (int)size);
DrmConvertedStatus *convertedStatus =
mDrmManagerClient->convertData(mConvertSessionID, &buffer);
int write_len = writeConvertedStatusToFile(convertedStatus, mDrmOffset + offset);
...
// close drm session and write drm file size.
convertedStatus = mDrmManagerClient->closeConvertSession(mConvertSessionID);
writeConvertedStatusToFile(convertedStatus);
// delete the instance.
delete mDrmManagerClient;
mDrmManagerClient=NULL;
说明:
writeConvertedStatusToFile是我写的一个处理转换结果的私有函数,主要是把结果convertedStatus中的数据进行保存。在最后,关闭ConvertSession后,还会返回一个convertedStatus,这里边也包含数据,并且多包含了一个offset,位置正好位于头部,这里存的是整个文件的大小,因为大小只有在整个转换完成,关闭时才会知道。另外,如果想对一个普通的媒体文件进行加密,则需要自己加上DRM的头和尾然后用此类的实例进行转换。
5. Android中DRM代码结构分析
代码位置
frameworks/base/drm/ (DRM的Java和JNI代码)
java/jni/ frameworks/av/drm/ (DRM的Native层代码,包括引擎和服务)
common/drmserver/libdrmframework/
DrmManagerClient.cppinclude/plugins/ frameworks/base/media/ (此路径中有关DRM的代码可能是遗留代码,目前还不知道有什么用)
libdrm/mobile1/java/drm/