Encryption 在ExoPlayer中脱机播放AES加密视频
我正在尝试使用ExoPlayer从本地存储播放加密视频。 用于使用FFMPEG加密视频的命令如下:Encryption 在ExoPlayer中脱机播放AES加密视频,encryption,aes,exoplayer,Encryption,Aes,Exoplayer,我正在尝试使用ExoPlayer从本地存储播放加密视频。 用于使用FFMPEG加密视频的命令如下: -i/storage/emulated/0/Download/20210125_193031.mp4-vcodec copy-acodec copy-c:v libx264-encryption\u scheme cenc aes ctr-encryption\u key b42ca3172ee4e69bf51848a59db9cd13-encryption\u kid 09e3672028f33
-i/storage/emulated/0/Download/20210125_193031.mp4-vcodec copy-acodec copy-c:v libx264-encryption\u scheme cenc aes ctr-encryption\u key b42ca3172ee4e69bf51848a59db9cd13-encryption\u kid 09e3672028f3346ca5dd60ff6671e70/storage/emulated/0/Download/out\u enc.mp4
这是我的播放器的源代码:
public class PlayerActivity extends AppCompatActivity {
private SimpleExoPlayer player;
private DefaultDrmSessionManager drmSessionManager;
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
// Build the media item.
PlayerView playerView = findViewById(R.id.video_view);
player = new SimpleExoPlayer.Builder(this).build();
playerView.setPlayer(player);
//player.prepare();
//FFMPEG command: -i /storage/emulated/0/Download/20210125_193031.mp4 -vf scale=-1:720 -c:v libx264 -encryption_scheme cenc-aes-ctr -encryption_key b42ca3172ee4e69bf51848a59db9cd13 -encryption_kid 09e367028f33436ca5dd60ffe6671e70 /storage/emulated/0/Download/out_enc.mp4
//base 64 keys generated from: https://www.base64encode.org/
//playVideo("/storage/emulated/0/Download/out_enc.mp4", "MDllMzY3MDI4ZjMzNDM2Y2E1ZGQ2MGZmZTY2NzFlNzA=", "YjQyY2EzMTcyZWU0ZTY5YmY1MTg0OGE1OWRiOWNkMTM=");
playVideo("/storage/emulated/0/Download/out_enc.mp4", "CeNnAo8zQ2yl3WD/5mcecA", "tCyjFy7k5pv1GEilnbnNEw");
}
private void playVideo(String url, String keyID, String keyValue) {
try {
drmSessionManager = buildDrmSessionManager(Util.getDrmUuid(C.CLEARKEY_UUID.toString()), true, keyID, keyValue
);
} catch (Exception e) {
e.printStackTrace();
}
player.setMediaSource(buildDashMediaSource(Uri.parse(url)));
player.prepare();
player.setPlayWhenReady(true);
}
private MediaSource buildDashMediaSource(Uri uri) {
DefaultDataSourceFactory dashChunkSourceFactory = new DefaultDataSourceFactory(this, "agent");
return new ProgressiveMediaSource.Factory(dashChunkSourceFactory)
.setDrmSessionManager(drmSessionManager)
.createMediaSource(uri);
}
private DefaultDrmSessionManager buildDrmSessionManager(UUID uuid, Boolean multiSession, String id, String value) {
/* String base64Id = Base64.encodeToString(id.getBytes(), Base64.DEFAULT);
String base64Value = Base64.encodeToString(value.getBytes(), Base64.DEFAULT);*/
String keyString = "{\"keys\":[{\"kty\":\"oct\",\"k\":\""+value+"\",\"kid\":\""+id+"\"}],\"type\":\"temporary\"}";;
LocalMediaDrmCallback drmCallback = new LocalMediaDrmCallback(keyString.getBytes());
FrameworkMediaDrm mediaDrm = null;
try {
mediaDrm = FrameworkMediaDrm.newInstance(uuid);
} catch (UnsupportedDrmException e) {
e.printStackTrace();
}
return new DefaultDrmSessionManager(uuid, mediaDrm, drmCallback, null, multiSession);
}
@Override
protected void onDestroy() {
player.release();
super.onDestroy();
}
它是加密视频的链接。
主要问题:视频正在播放,但未解密。我遗漏了什么?查看logcat输出,那里似乎没有任何DRM、AES或clearkey错误 然后查看视频文件本身,它似乎报告了一些问题: 但是,通过检查使用相同ffmpeg方法加密的其他示例文件,它们显示了类似的问题,因此这似乎是ffprobe以这种方式加密的文件的典型输出 然后用MP4解析器查看视频文件结构本身,以查看单个原子或头块,似乎没有PSSH框 PSSH框是包含ISOBMFF mp4文件加密相关数据的标题区域-这实际上是CENC规范中的可选字段,因此即使没有该字段,视频也有效 那么,一个显而易见的问题是,玩家如何知道视频是经过编码的?根据CENC规范,答案是:
- (Duna在评论中强调,看起来非常好)