煙臺網(wǎng)站建設(shè)搜狗推廣登錄入口
? ? ? ? 對于ffmpeg的AES-CTR加密有兩種方式,一個是普通的整個視頻做加密,另一個是對視頻做切片處理,然后進行加密。
? 一、對于普通的加密方式
直接使用下面的命令就行
ffmpeg -i animal.mp4 -vcodec copy -acodec copy -encryption_scheme cenc-aes-ctr -encryption_key c7e16c4403654b85847037383f0c2db3 -encryption_kid a7e61c373e219033c21091fa607bf3b8 -encryption_iv 1234567890abcdef1234567890abcdef encrypted_IV3.mp4
? ? ? ? 簡單解釋一下各種參數(shù)的作用,
-vcodec copy -acodec copy 只是將 animal.mp4的音視頻數(shù)據(jù)直接拷貝到encrypted_IV3.mp4中
-encryption_scheme cenc-aes-ctr 表示采用的加密算法是cenc-aes-ctr
-encryption_key c7e16c4403654b85847037383f0c2db3 表是encryption_key 的值是c7e16c4403654b85847037383f0c2db3,這個值就是解密用的key
-encryption_kid a7e61c373e219033c21091fa607bf3b8? 表示encryption_kid 的值是a7e61c373e219033c21091fa607bf3b8,加解密就是key和id的比對
-encryption_iv 1234567890abcdef1234567890abcdef 表示加密的初始向量IV為1234567890abcdef1234567890abcdef,這個參數(shù)可以不加,ffmpeg是有默認值的
encrypted_IV3.mp4 是加密后的MP4
? ? ? ? ?播放的話,采用的是ffplay,命令行如下
ffplay encrypted_IV.mp4 -dencryption_key c7e16c4403654b85847037383f0c2db3 -decryption_iv 1234567890abcdef1234567890abcdef
-dencryption_key 解密用的密鑰,就是加密的encryption_key的值
-decryption_iv? 如果加密的時候有設(shè)置加密初始向量的值,那么這里也需要加,對應(yīng)的是encryption_iv的值,如果加密的時候采用的是默認的,這里可以不加
對于代碼加密代碼,此處復(fù)制的別人的,項目并不需要這個,我就沒做驗證
AVDictionary *opts = NULL;
// 指定加密參數(shù)
av_dict_set(&format_opts, "encryption_scheme", "cenc-aes-ctr", 0);
av_dict_set(&format_opts, "encryption_key", "c7e16c4403654b85847037383f0c2db3", 0);
av_dict_set(&format_opts, "encryption_kid", "a7e61c373e219033c21091fa607bf3b8", 0);
ret = avformat_write_header(AVFormatContext, &format_opts);
?解密的代碼也是別人的,但我是經(jīng)過驗證的,確認可行
AVDictionary *format_opts = NULL;
// 指定解密key
av_dict_set(&format_opts, "decryption_key", "c7e16c4403654b85847037383f0c2db3", 0);
av_dict_set(&format_opts, "decryption_iv", "1234567890abcdef1234567890abcdef", 0);
err = avformat_open_input(&AVFormatContext, "path", AVInputFormat, &format_opts);
? 二、對于流式的加密方式
命令行如下
ffmpeg -i animal.mp4 -movflags frag_keyframe -encryption_scheme cenc-aes-ctr -encryption_key c7e16c4403654b85847037383f0c2db3 -encryption_kid a7e61c373e219033c21091fa607bf3b8 encrypted.mp4
重復(fù)的參數(shù)我就不贅述了,
-movflags?
選項用于設(shè)置MOV或MP4容器(文件格式)的特定標(biāo)志。這些標(biāo)志會改變輸出文件的結(jié)構(gòu)或行為。frag_keyframe?強制每個關(guān)鍵幀都開始一個新的片段,使文件適合于流式傳輸。這個參數(shù)就是區(qū)分流式還是普通的一個關(guān)鍵參數(shù)
?播放的話和普通的一致。
出現(xiàn)下面這三個字段,就是說明成功了。工具我用的是Bento4,Bento4有個命令mp4dump可以查看。
? 三、需要注意的是---moov
? ? ? ? ffmpeg有一個參數(shù),叫empty_moov 。當(dāng)你創(chuàng)建一個MP4文件時,通常它首先寫入一個moov
原子(也就是元數(shù)據(jù)),然后是mdat
原子(包含實際的音頻/視頻數(shù)據(jù))。但是,如果你想開始記錄并在之后添加元數(shù)據(jù),你需要首先寫入一個空的moov
原子,簡單理解就是:
普通的MP4 的格式(從上到下):? moov -> data?
加了empty_moov的MP4格式:? empty_moov -> data -> moov
如果你把moov移動到了MP4末尾的同時做了aes-ctr加密,就會出錯,因為ffmpeg在解密aes-ctr時要先知道加密的重要參數(shù),而這個參數(shù)就在moov中,然后才能進行解密,如果moov放在了末尾,那ffmpeg就不知道要怎么解密了。該情況下我遇到的錯誤有下面幾種
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x149204a10] Incorrect number of samples in encryption info
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x1426658b0] saio atom found without saiz
[h264 @ 0x7f93ba8a3e00] Invalid NAL unit size (217505651 > 1332).
[h264 @ 0x7f93ba8a3e00] Error splitting the input into NAL units.