FFmpeg CENC加密mp4文件
一、什么是CENC加密?
CENC(Common Encryption Scheme)是一种通用的视频加密方案,它允许使用不同的数字版权管理(DRM)系统来保护和播放同一个加密后的视频文件。CENC加密遵循ISO/IEC 23001-7标准,它在mp4文件中增加了一些特殊的box来存储加密相关的信息,如:
pssh
box:存储DRM系统特定的数据,如许可证服务器地址、内容ID等。senc
box:存储每个样本(sample)的初始化向量(IV)和子样本(subsample)的明文和密文长度。saiz
box:存储每个样本的辅助信息大小,即senc
box中对应样本数据的长度。saio
box:存储每个样本辅助信息在senc
box中的偏移量。
CENC加密支持两种模式:完全加密(Full Encryption)和子样本加密(Subsample Encryption)。完全加密模式下,每个样本都被完整地加密;子样本加密模式下,每个样本被分成若干个子样本,其中只有部分子样本被加密,其他子样本保持明文。子样本加密模式可以提高兼容性和性能,因为一些视频格式需要保留部分明文数据才能正常解析。
二、如何使用FFmpeg CENC加密mp4文件?
FFmpeg是一个强大的多媒体处理工具,它提供了cenc方式来对mp4文件进行加解密操作。我们可以使用以下命令来对一个mp4文件进行cenc完全或者子
样本加密:
完全加密:
ffmpeg -i input.mp4 -vcodec copy -acodec copy -encryption_scheme cenc-aes-ctr -encryption_key 76a6c65c5ea762046bd749a2e632ccbb -encryption_kid a7e61c373e219033c21091fa607bf3b8 output.mp4
子样本加密:
ffmpeg -i input.mp4 -vcodec copy -acodec copy -encryption_scheme cenc-aes-ctr -encryption_key 76a6c65c5ea762046bd749a2e632ccbb -encryption_kid a7e61c373e219033c21091fa607bf3b8 -clear_lead 10 output.mp4
其中,-encryption_scheme
指定了加密方案,-encryption_key
指定了加密密钥,-encryption_kid
指定了内容ID,-clear_lead
指定了每个样本的前多少字节保持明文(仅用于子样本加密)。
注意:这里的加密密钥和内容ID都是16字节的十六进制字符串,可以使用任意的值,但是必须和DRM系统保持一致。
三、如何查看CENC加密后的mp4文件结构和播放效果?
我们可以使用mp4box或者mp4dump等工具来查看CENC加密后的mp4文件结构,例如:
mp4dump output.mp4
输出结果如下(部分省略):
[ftyp] size=8+20
major_brand = iso6
minor_version = 1
compatible_brand = avc1
compatible_brand = mp41
[moov] size=8+5299
[mvhd] size=12+96, version=0, flags=0x000000
timescale = 1000
duration = 28000 (media timescale units)
duration(ms) = 28000 (milliseconds)
playback rate = 1.000000
volume = 1.000000
next track id = 3
...
[trak] size=8+2389, track id=1, type='vide'
[tkhd] size=12+80, version=0, flags=0x000007
...
[senc] size=12+1600, version=0, flags=0x000001
auxiliary info type: cenc
auxiliary info type parameter: default
sample count: 100
sample #1:
initialization vector: a7e61c373e219033
sample #2:
initialization vector: c21091fa607bf3b8
...
[saiz] size=12+104
auxiliary info type: cenc
auxiliary info type parameter: default
default sample info size: 16
sample count: 100
[saio] size=12+16
auxiliary info type: cenc
auxiliary info type parameter: default
entry count:
...
我们可以看到,CENC加密后的mp4文件中包含了pssh、senc、saiz、saio等box,并且每个样本都有一个初始化向量(IV)。
为了播放CENC加密后的mp4文件,我们需要使用支持DRM系统的播放器,并且从许可证服务器获取解密所需的信息。例如,我们可以使用Shaka Player来播放CENC加密后的mp4文件,只需要提供以下配置:
var manifestUri =
'output.mp4';
function initApp() {
shaka.polyfill.installAll();
if (shaka.Player.isBrowserSupported()) {
initPlayer();
} else {
console.error('Browser not supported!');
}
}
function initPlayer() {
var video = document.getElementById('video');
var player = new shaka.Player(video);
player.addEventListener('error', onErrorEvent);
player.configure({
drm: {
servers: {
'org.w3.clearkey': 'https://license-server-url'
},
clearKeys:{
'a7e61c373e219033c210
91fa607bf3b8': '76a6c65c5ea762046bd749a2e632ccbb'
}
}
});
player.load(manifestUri).then(function() {
console.log('The video has now been loaded!');
}).catch(onError);
}
function onErrorEvent(event) {
onError(event.detail);
}
function onError(error) {
console.error('Error code', error.code, 'object', error);
}
document.addEventListener('DOMContentLoaded', initApp);
这里,我们使用了ClearKey DRM系统,它是一种简单的DRM系统,它使用明文的密钥和内容ID来进行解密。我们需要提供一个许可证服务器的地址,或者直接在配置中指定密钥和内容ID的映射关系。当然,实际应用中,我们应该使用更安全的DRM系统,如Widevine、PlayReady、FairPlay等。
运行上述代码后,我们就可以在浏览器中播放CENC加密后的mp4文件了。
四、总结
本文介绍了CENC加密的基本概念和流程,并且使用FFmpeg来对mp4文件进行CENC加密,并且展示了CENC加密后的mp4文件结构和播放效果。希望本文对你有所帮助。
参考资料:
https://ffmpeg.org/ffmpeg-formats.html#Options-34
https://www.bento4.com/documentation/mp4-dash/#common-encryption
https://shaka-player-demo.appspot.com/docs/api/tutorial-drm-config.html