这里以Exoplayer 2.5.4为例。
源码里面我们主要关注这两个java文件:
SampleChooserActivity
PlayerActivity
SampleChooserActivity
界面我们可以选择流播放,PlayerActivity
界面播放流。
然而选择不同的流, 有不同的播放, 但是播放界面都共用一个activity
, 是因为每次点击播放的时候会传递不同的参数。
public Intent buildIntent(Context context) {
return super.buildIntent(context)
.setData(Uri.parse(uri))
.putExtra(PlayerActivity.EXTENSION_EXTRA, extension)
.putExtra(PlayerActivity.AD_TAG_URI_EXTRA, adTagUri)
.setAction(PlayerActivity.ACTION_VIEW);
}
通过这个, SampleChooserActivity
可以把流地址, 流后缀, 广告地址
等等添加到Intent
来传递到PlayerActivity
播放界面, 而后PlayerActivity
对数据接收。
例如对格式的接收:
public static final String DRM_SCHEME_UUID_EXTRA = "drm_scheme_uuid"
if (intent.getExtras().getString(DRM_SCHEME_UUID_EXTRA) != null) {
switch (intent.getExtras().getString(DRM_SCHEME_UUID_EXTRA)) {
case "widevine":
drmSchemeUuid = UUID.fromString(String.valueOf(C.WIDEVINE_UUID));
break;
case "playready":
drmSchemeUuid = UUID.fromString(String.valueOf(C.PLAYREADY_UUID));
break;
case "cenc":
drmSchemeUuid = UUID.fromString(String.valueOf(C.PLAYREADY_UUID));
break;
default:
Log.w(TAG, "Unsupported drm style!!!");
}
参数的传递, 无论是通过app直接启动下一个activity, 还是通过am start
, 都是以键值对来传递的。
public static final String EXTENSION_EXTRA = "extension";
intent.putExtra(PlayerActivity.EXTENSION_EXTRA, extension);
am start -W -a com.google.android.exoplayer.demo.action.VIEW -c android.intent.category.DEFAULT \
...
-e extension "mpd" \
"com.google.android.exoplayer2.demo/com.google.android.exoplayer2.demo.PlayerActivity"
PlayerActivity
会对不同的参数进行解析, 实现流的播放。
从源码里面的AndroidManifest
看:
<activity android:name="com.google.android.exoplayer2.demo.PlayerActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
android:launchMode="singleTop"
android:label="@string/application_name"
android:theme="@style/PlayerTheme">
<intent-filter>
<action android:name="com.google.android.exoplayer.demo.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="http"/>
<data android:scheme="https"/>
<data android:scheme="content"/>
<data android:scheme="asset"/>
<data android:scheme="file"/>
</intent-filter>
<intent-filter>
<action android:name="com.google.android.exoplayer.demo.action.VIEW_LIST"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
PlayerActivity
会接受两种不同的intent
:
<action android:name="com.google.android.exoplayer.demo.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
和
<action android:name="com.google.android.exoplayer.demo.action.VIEW_LIST"/>
<category android:name="android.intent.category.DEFAULT"/>
可以简单的认为,前者是播放单个流的intent, 后者是播放多个混合流的intent。
如果我们以am start
在串口敲命令,可以有一下两种情况:
am start -W -a com.google.android.exoplayer.demo.action.VIEW -c android.intent.category.DEFAULT \
-e link "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd" \
-e drm_scheme_uuid "widevine" \
-e drm_license_url "https://proxy.uat.widevine.com/proxy?provider=widevine_test" \
-e extension "mpd" \
"com.google.android.exoplayer2.demo/com.google.android.exoplayer2.demo.PlayerActivity"
am start -W -a com.google.android.exoplayer.demo.action.VIEW_LIST -c android.intent.category.DEFAULT \
--esa link "https://html5demos.com/assets/dizzy.mp4"\,\
"https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_sd.mpd"\,\
"https://html5demos.com/assets/dizzy.mp4"\,\
"https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_sd.mpd"\,\
"https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_sd.mpd" \
-e drm_scheme_uuid "widevine" \
-e drm_license_url "https://proxy.uat.widevine.com/proxy?provider=widevine_test" \
"com.google.android.exoplayer2.demo/com.google.android.exoplayer2.demo.PlayerActivity"
其中, 在串口输入am
有以下提示:
<INTENT> specifications include these flags and arguments:
[-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]
[-c <CATEGORY> [-c <CATEGORY>] ...]
[-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]
[--efal <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]
(mutiple extras passed as List<Float>)
[--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]
(mutiple extras passed as String[]; to embed a comma into a string,
escape it using "\,")
[--esal <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]
(mutiple extras passed as List<String>; to embed a comma into a string,
escape it using "\,")
[<URI> | <PACKAGE> | <COMPONENT>]
其中键值都是以String
传入的, 要加上""
来识别。
流的相应信息,在此例中,都是保存在media.exolist.json
文件中, 例如:
{
"name": "WV: Secure SD (cbc1,MP4,H264)",
"uri": "https://storage.googleapis.com/wvmedia/cbc1/h264/tears/tears_aes_cbc1_sd.mpd",
"drm_scheme": "widevine",
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
}
但是局限也很多:
- 如果我们需要启动的
activity
不需要传入参数,那很简单,知道activity
的名字就行,找源码,或者串口输入
logcat | grep cmp
就可以找到相应的activity
.
- 如果我们需要启动的
activity
需要传入参数, 那我们就只能从源码入手了。
此例,代码中我加入了判断:
public static final String STREAM_URL = "link";
if (intent.getExtras().getString(STREAM_URL) != null
|| intent.getStringArrayExtra(STREAM_URL) != null) {
//Run exoplayer from command line
Log.i(TAG, "Run exoplayer from command line");
...
} else {
//Run exoplayer from internal app
Log.i(TAG, "Run exoplayer from internal app");
}
“link”
这个键名是串口输入指令时独有的, 在app内部启动这个PlayerActivity
不会输入这个参数。
这样的话,安装上此代码编译出的apk,无论是内部启动播放流,还是外部指令播放流,不会有冲突了。
网友评论