前言
公司的项目因为要视频加密,所以要把播放器替换为阿里云播放器。然后到官网一看,集成和使用都挺简单的,结果一下手,集成的播放器库居然是只有单单播放功能的,界面控制什么的都没有,那如果花点时间自定义当然也可以,但觉得并不是那么友好,而且接口也比较乱。后面一看,官方的demo自己又封装了一个播放器类,操作界面什么的就都有了,那么就直接导入模块了。
导入demo的模块就会顺带相关的一起导入。导入完,想着也应该步入轨道了吧,没想到,布局的时候根本加载不了AliyunVodPlayerView类,也就是官方封装的播放器类。又是一通挣扎之后发现,导入的资源包应该是AliyunPlayer-4.7.4-full.aar包,而不是part包。(这里官方是说,如果只要播放就用full包,如果要播放还要小视频功能就用part包,为什么我总感觉哪里怪怪的?excuse me?)
其实到这里另外一个项目替换的时候又发现了一个问题,就是阿里云这个播放器是只支持v7的,也就是说ndk得配置为v7。build.gradle(:app)下android{}块内设置:
ndk {
abiFilters "armeabi-v7a"
}
然后相关的库比如讯飞语音什么的so包就也得替换为v7版本的,真的把我心态完全搞崩了...而且官方文档是没有说明的,再次吐槽一下!!
总算是步入正轨了...
接着就是播放的问题了。那么问题又来了,官网文档一通操作,都是什么Vid,sts,本地Url播放,那么我加密要怎么播放,难道不是亲生的?再经过了一番挣扎,终于发现官方隐藏文档(感觉官方是怕我们知道怎么播放阿里云加密视频?),加密视频要用鉴权播放方式,也就是要先用Vid(VideoId)去获取鉴权(Auth),然后再创建一个VidAuth传给播放器类进行播放。
String response = responseBody.string();
if (!TextUtils.isEmpty(response)) {
VidAuth auth = new VidAuth();
auth.setVid(vid);
auth.setPlayAuth(response);
playerView.setAuthInfo(auth);
playerView.start();
}
然后,官方的隐藏文档也给了方法怎么去获取这个Auth,嗯,还挺直接的。Copy过来一看,我哪来的这个类??(这里具体方法官网有)于是,又经过一番洗礼,我知道了用到的类是哪个库给的了...
嗯,还挺秃然的...这还没完,还有几给类这个包也没有。又找了一番,还有一个叫什么vod什么的库,再maven上找就有了。好了,再引入,总该美滋滋的结束了吧。结果,疯狂报包重复了,我****。
最后,实在不行了,我们主管让PHP写了个接口给我用...
那就Retrofit走一波了:
public interface VidAuthService {
@POST("index.php?....")
Observable<ResponseBody> getAuth(@Body RequestBody requestBody);
}
public class VidAuthClient {
static String HOST_NAME = "https://*****.cn/";
private static Retrofit singleton;
public static <T> T createApi(Context context, Class<T> clazz) {
if (singleton == null) {
synchronized (VidAuthClient.class) {
if (singleton == null) {
Retrofit.Builder builder = new Retrofit.Builder();
builder.baseUrl(HOST_NAME)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
singleton = builder.build();
}
}
}
return singleton.create(clazz);
}
}
这里有个要注意的就是HOST也就是baseUrl要以"/"结尾,也就是要把后半段拆到POST里去,这里用POST是因为要传递参数(Json)过去。这样就可以请求了:
JSONObject object = new JSONObject();
object.put("videoId", vid);
String jsonString = object.toJSONString();
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), jsonString);
这边把参数传到RequestBody里,并设置类型("application/json")就行了。参考:https://blog.csdn.net/weixin_42261405/article/details/105724130
VidAuthService vidAuthService = VidAuthClient.createApi(this, VidAuthService.class);
vidAuthService.getAuth(requestBody)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<ResponseBody>() {
@Override
public void accept(ResponseBody responseBody) throws Exception {
String response = responseBody.string();
if (!TextUtils.isEmpty(response)) {
VidAuth auth = new VidAuth();
auth.setVid(vid);
auth.setPlayAuth(response);
playerView.setAuthInfo(auth);
playerView.start();
}
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Logger.d(throwable.getMessage());
ToastUtils.showShortToast(CoursePlayActivity.this, "回调失败");
}
});
这样一来,基本也就大功告成了。不过还遇到了个小插曲,就是基类Activity用到ImmersionBar的时候,视频横屏全屏播放的时候状态栏是去不掉的,可能是调用冲突了,搞了一通还是没办法解决,还好最后想到了重写个方法在当前界面的时候禁用它就好了。一整个流程下来,虽然是个简单的替换,着实不容易。