1. 工具说明
1.1 ExoPlayer
ExoPlayer是google开源的应用级媒体播放器项目,构建在Android的底层多媒体API之上。该开源项目包含ExoPlayer库和演示demo。
github地址:https://github.com/google/ExoPlayer
1.2 shaka-packager
Shaka Packager是用于DASH和HLS打包和加密的工具和媒体打包SDK。 它可以准备和打包媒体内容以进行在线流式传输,支持Widevine和其他DRM系统的通用加密。
当前支持的加密系统有:widevine, playready, fairPlay, Marlin
github地址:https://github.com/google/shaka-packager
2. 加密视频
2.1 下载shaka-packager
在github上可以下载源码进行自行编译,也可以只下载上面的release版本的工具。
建议下载linux版本的。当前版本是v2.3.0
这里提供一个本人下载好的版本
链接
2.2 使用ffmpeg生成不同规格的片源
由于在线流会根据不同的网络状况播放不同的分辨率的视频,所以一般都会把一个高清片源转成多种规格的片源以适应不同的网络环境。
在这里可以使用ffmpeg工具来转换。这个工具的使用说明网上有许多说明,在此就不再累述。
当然,此步骤可以省略。
下载好ffmpeg工具后,可以参考shaka-packager的使用文档里的Media Encoding来转换不同规格:
- 360p:
$ ffmpeg -i original.mp4 -c:a copy \
-vf "scale=-2:360" \
-c:v libx264 -profile:v baseline -level:v 3.0 \
-x264-params scenecut=0:open_gop=0:min-keyint=72:keyint=72 \
-minrate 600k -maxrate 600k -bufsize 600k -b:v 600k \
-y h264_baseline_360p_600.mp4
- 480p:
$ ffmpeg -i original.mp4 -c:a copy \
-vf "scale=-2:480" \
-c:v libx264 -profile:v main -level:v 3.1 \
-x264-params scenecut=0:open_gop=0:min-keyint=72:keyint=72 \
-minrate 1000k -maxrate 1000k -bufsize 1000k -b:v 1000k \
-y h264_main_480p_1000.mp4
- 720p:
$ ffmpeg -i original.mp4 -c:a copy \
-vf "scale=-2:720" \
-c:v libx264 -profile:v main -level:v 4.0 \
-x264-params scenecut=0:open_gop=0:min-keyint=72:keyint=72 \
-minrate 3000k -maxrate 3000k -bufsize 3000k -b:v 3000k \
-y h264_main_720p_3000.mp4
博文为ganqiuye原创,转载请附上原文出处链接和本声明。
2.3 加密
注意:shaka-packager工具在使用的时候一般需要联网(架梯子)。
根据shaka packager的使用手册可知,DRM的加密方式可以有Using key server
和using raw key
两种。
- using key server
需要联网。使用的key是来源服务器
- using raw key
不需要联网。使用的key是本地生成
在这里我们使用的是第一种方式。参考tutorials的examples
将2.2
步骤里转换的片源和shaka-packager工具放到同一个文件夹里,然后输入命令:
$ ./packager-linux \
in=h264_baseline_360p_600.mp4,stream=audio,output=audio.mp4 \
in=h264_baseline_360p_600.mp4,stream=video,output=h264_360p.mp4 \
in=h264_main_480p_1000.mp4,stream=video,output=h264_480p.mp4 \
in=h264_main_720p_3000.mp4,stream=video,output=h264_720p.mp4 \
in=h264_high_1080p_6000.mp4,stream=video,output=h264_1080p.mp4 \
--enable_widevine_encryption \
--key_server_url https://license.uat.widevine.com/cenc/getcontentkey/widevine_test \
--content_id 7465737420636f6e74656e74206964 \
--signer widevine_test \
--aes_signing_key 1ae8ccd0e7985cc0b6203a55855a1034afc252980e970ca90e5202689f947ab9 \
--aes_signing_iv d58ce954203b7c9a9a9d467f59839249 \
--mpd_output h264.mpd
这样在文件夹里就会有:
.
├── audio.mp4
├── h264_1080p.mp4
├── h264_360p.mp4
├── h264_480p.mp4
├── h264_720p.mp4
├── h264_baseline_360p_600.mp4
├── h264_high_1080p_6000.mp4
├── h264_main_480p_1000.mp4
├── h264_main_720p_3000.mp4
├── h264.mpd
└── packager-linux
0 directories, 11 files
当然,上面命令可以根据实际情况增加或减少输入的源。
其中输出分别有:
加密的音频audio.mp4
,
加密的视频:h264_1080p.mp4
, h264_360p.mp4
, 264_480p.mp4
, h264_720p.mp4
加密的配置说明:h264.mpd
3. 播放加密视频
3.1 下载Exoplayer源码
下载exoplayer源码,当前release版本是r2.11.0, release-v2
分支
导入到Android Studio中,切换到demo工程
3.2 修改配置文件,添加播放视频
修改demos/main/src/main/assets/media.exolist.json
文件
diff --git a/demos/main/src/main/assets/media.exolist.json b/demos/main/src/main/assets/media.exolist.json
index 01980c2..9ba77f6 100644
--- a/demos/main/src/main/assets/media.exolist.json
+++ b/demos/main/src/main/assets/media.exolist.json
@@ -1,5 +1,48 @@
[
{
+ "name": "TEST LOCAL",
+ "samples": [
+ {
+ "name": "local: 480",
+ "uri": "sdcard/Movies/h264_main_480p_1000.mp4"
+ },
+ {
+ "name": "wv,avc,1080@24fps",
+ "uri": "/sdcard/Movies/h264.mpd",
+ "drm_scheme": "widevine",
+ "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
+ },
+ {
+ "name": "wv,avc, 4k@30fps",
+ "uri": "/sdcard/Movies/h264_4k_30fps.mpd",
+ "drm_scheme": "widevine",
+ "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
+ },
+ {
+ "name": "wv,hevc, 4k@60fps",
+ "uri": "/sdcard/Movies/h265_4k_60fps.mpd",
+ "drm_scheme": "widevine",
+ "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
+ },
+ {
+ "name": "wv,vp9, 4k@30fps",
+ "uri": "/sdcard/Movies/vp9_4k_30fps.mpd",
+ "drm_scheme": "widevine",
+ "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
+ },
+ {
+ "name": "test server: 480",
+ "uri": "http://192.168.1.123/h264_main_480p_1000.mp4"
+ },
+ {
+ "name": "test server wv: avc@1080",
+ "uri": "http://192.168.1.123/h264.mpd",
+ "drm_scheme": "widevine",
+ "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
+ }
+ ]
+ },
+ {
"name": "YouTube DASH",
"samples": [
{
注意:
drm_license_url
的路径是https://proxy.uat.widevine.com/proxy?provider=widevine_test
而不是加密视频的时候用的key_server_url
。
wv,avc,1080@24fps
里的uri
中/sdcard/Movies/h264.mpd
是有/
3.3 放置片源
由上可知,根据不同配置,将片源放到不同的地方,一是放进Android设备中的sdcard/Movies
目录中,二是放到本地服务器中,另外需要注意的是mpd
文件中配置了多少个源,那么就需要放置同样的音频源或视频源进去。
在实际应用中,需要把mpd
文件和加密源放到一个网络服务器当中去,然后在media.exolist.json
中添加相应的网络路径。
对于本地服务器的搭建,可以使用appache(安装步骤略)。之后将片源放到其默认目录下,如/var/www/html
。
3.4 编译安装播放
1、在res文件夹下创建一个xml文件夹,然后创建一个network_security_config.xml文件,文件内容如下:
diff --git a/demos/main/src/main/res/xml/network_security_config.xml b/demos/main/src/main/res/xml/network_security_config.xml
new file mode 100644
index 0000000..83a6d61
--- /dev/null
+++ b/demos/main/src/main/res/xml/network_security_config.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config xmlns:android="http://schemas.android.com/apk/res/android">
+ <base-config cleartextTrafficPermitted="true" />
+</network-security-config>
\ No newline at end of file
2、在AndroidManifest.xml文件下的application标签增加以下属性:
diff --git a/demos/main/src/main/AndroidManifest.xml b/demos/main/src/main/AndroidManifest.xml
index 0240a37..24be293 100644
--- a/demos/main/src/main/AndroidManifest.xml
+++ b/demos/main/src/main/AndroidManifest.xml
@@ -36,6 +36,7 @@
android:allowBackup="false"
android:requestLegacyExternalStorage="true"
android:name="com.google.android.exoplayer2.demo.DemoApplication"
+ android:networkSecurityConfig="@xml/network_security_config"
tools:ignore="UnusedAttribute">
<activity android:name="com.google.android.exoplayer2.demo.SampleChooserActivity"
在Android studio中编译安装apk到设备上,然后联网播放就可以播放本地的加密视频了。联网是为了获得license。
4. 遗留问题
在局域网中构建的服务器不能播放。在电脑端使用apache安装了一个服务端,在浏览器上是可以打开非加密视频源的,但在ExoPlayer中打不开。这是因为,使用的板子是基于AndroidQ的,从AndroidP开始,就默认要求网络要安全链接,不支持http
。此问题通过修改Exoplayer的配置项可解,解决方法如3.4的配置。- 使用
using raw key
的方法生成加密视频,但在ExoPlayer中不知道配置什么参数来播放。对于使用using raw key
进行非drm加密,请看我的文章《hls加密流生成之sample-aes加密》和《HLS/m3u8之sample-aes解密及软件开发》