1. 概述
CC视频Android SDK是基于Android API实现的类库,支持Android2.3及以上版本,开发者可通过此SDK对接CC视频云服务平台,进行播放、上传和下载操作。
1.1 功能特性
功能 | 描述 |
---|---|
视频播放 | 支持视频播放和本地播放 |
移动端广告 | 支持添加视频前贴广告和暂停广告 |
播放统计 | 支持用户自定义参数实现播放的统计 |
视频打点 | 支持用户自定义视频打点功能的回调 |
视频问答 | 支持用户自定义视频问答功能的回调 |
视频字幕 | 支持从服务器获取字幕资源并显示 |
视频上传 | 支持断点续传视频信息和视频文件 |
视频下载 | 支持断点续传下载视频 |
音频播放 | 支持音频在线播放和本地播放 |
音频下载 | 支持音频下载 |
授权验证 | 支持为视频配置授权码 |
1.2 阅读对象
本文档为技术文档,需要阅读者:
- 具备基本的Android开发能力
- 准备接入CC视频的点播SDK功能
- 对CC点播产品使用方法有基础的了解,使用帮助地址。
2. 开发准备
2.1 开发环境
- Android Studio : Android 开发IDE
- Android SDK : Android 官方SDK
2.2 混淆配置
CCSDK.jar已经过混淆处理,如果需要对应用进行混淆编译,请在混淆的配置文件中加入以下代码,以避免SDK被二次混淆编译:
-dontwarn com.bokecc.sdk.mobile.**
-keep public class com.bokecc.sdk.mobile.**{*;}
-keep public interface com.bokecc.sdk.mobile.**{*;}
3. 快速集成
首先,需要下载最新版本的SDK,下载地址为:CCVideo/VOD_Android_SDK
3.1 导入jar
将CCSDK.jar添加到Android项目中,并配置当前项目可正确的引用此类库
3.2 配置项目的网络权限和文件读写权限:
<!-- 用于网络通信 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 用于存储已下载文件 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
3.3 视频播放
SDK视频播放由DWMediaPlayer类实现,DWMediaPlayer继承了Android的媒体播放器MediaPlayer类,并重载其prepare()和prepareAsync()方法。使用DWMediaPlayer既可播放CC视频云服务平台下的视频(以下简称在线播放),也可播放本地视频。
3.3.1 在线播放
使用SDK的在线播放功能时,需设置视频ID、账户ID、API KEY、授权码verificationCode(注:开通授权验证功能需要配置授权码,没开通此功能授权码留空,Demo的verificationCode是从上个页面传值过来,实际使用时根据具体业务逻辑调整)及Context(上下文信息)即可播放云端视频。具体实现方式如下:
- 配置布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextureView
android:id="@+id/tv_paly_video"
android:layout_width="match_parent"
android:layout_height="200dp" />
</LinearLayout>
- 编写播放代码
public class MainActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener, DWMediaPlayer.OnPreparedListener {
private TextureView tv_paly_video;
private SurfaceTexture mTexture;
private Surface surface;
private DWMediaPlayer player;
private String USERID = "在此配置账户ID";
private String API_KEY = "在此配置API KEY";
private String videoId = "在此配置视频ID";
private String verificationCode= "在此配置授权码";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_paly_video = findViewById(R.id.tv_paly_video);
tv_paly_video.setSurfaceTextureListener(this);
player = new DWMediaPlayer();
Context context = getApplicationContext();
// 设置视频播放信息
player.setVideoPlayInfo(videoId, USERID, API_KEY,verificationCode, context);
mTexture = tv_paly_video.getSurfaceTexture();
}
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
if (mediaPlayer != null) {
mediaPlayer.start();
}
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
this.surface = new Surface(surfaceTexture);
player.reset();
player.prepareAsync();
player.setOnPreparedListener(this);
player.setSurface(surface);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
}
当播放器准备播放完成后,调用start()方法开始播放视频。同时,DWMediaPlayer提供了getVideoStatusInfo(获取视频状态),getVideoTitle(获取视频标题)等方法,开发者可根据需要在应用中展示相应的信息。
选择清晰度播放
DWMediaPlayer提供了getDefinitions()方法获取当前播放的视频清晰度列表。如果需要切换视频的清晰度,可根据当前视频的清晰度对DWMediaPlayer进行设置。具体实现方式如下,
// 获取清晰度列表
Map<String, Integer> definitions = player.getDefinitions();
// 获取某种清晰度对应的状态码
int definitionCode = definitions.get("definitionInfo");
// 设置播放清晰度
player.setDefinition(context, definitionCode);
设置OnDreamWinErrorListener
DWMediaPlayer获取播放地址产生的异常需要通过OnDreamWinErrorListener来获取异常,需要用户自行设置该监听。
// 获取清晰度列表
player.setOnDreamWinErrorListener(...)
3.3.2 本地播放
在使用DWMediaPlayer播放本地视频时,与使用Android默认媒体播放器MediaPlayer播放本地视频的方法相同,仅需设置视频文件地址。具体实现方式如下,
String path = "/123456.MP4";
DWMediaPlayer player = new DWMediaPlayer();
//设置视频文件地址
player.setDataSource(path);
player.prepare();
当播放器准备完成后,调用start()方法即可开始播放视频。
3.4 视频上传
SDK视频上传由Uploader类实现,Uploader通过HTTP协议与服务端进行通信,上传视频信息和视频文件。同时,SDK提供了上传回调接口UploadListener来监听视频上传流程,如果需要在应用中展示上传状态、上传进度等信息,可根据需要进行设置。
3.4.1 Uploader使用示例
使用Uploader上传前,请先了解Uploader的工作流程:
- 创建Uploader实例,初始化视频信息,此时Uploader进入等待状态(WAIT)。
- 当需要开始上传时,调用start()方法开始上传,此时Uploader进入上传状态(UPLOAD)。
- 当需要暂停上传时,调用pause()方法。另外,在上传过程中可能出现网络异常问题,当出现此问题时,Uploader默认会暂停当前上传操作,进入暂停状态(PAUSE)。
- 当需要恢复上传时,调用resume()方法,若无网络异常等问题,此时Uploader会重新上传视频文件。
- 当需要取消上作时,调用cancel()方法,此时Uploader会进入等待状态(WAIT)。
创建Uploader实例需提供VideoInfo(视频信息)和 API KEY,使用示例如下:
VideoInfo videoInfo = new VideoInfo();
videoInfo.setTitle("title");
videoInfo.setTags("tag");
videoInfo.setDescription("description");
// 设置视频文件地址
videoInfo.setFilePath("filePath");
// 设置账号信息
videoInfo.setUserId("USERID");
// 设置回调信息
videoInfo.setNotifyUrl(“NOTIFY_URL");
Uploader uploader = new Uploader(videoInfo,"API_KEY");
// 开始上传
uploader.start();
VideoInfo是用来记录上传过程与视频相关的信息,具体介绍请参考sdk_doc,在初始化视频信息时,服务端需根据视频的标题、标签、描述等来创建视频,所以在使用VideoInfo创建Uploader实例时,请确保视频信息非空。
v2.3.4新增:新增disconnectRequest()方法,可以立刻停止当前url请求,该方法需配合pause()和cancel()方法来使用。
3.4.2 设置上传回调
Uploader在执行上传操作时,默认会检查是否设置了UploadListener。若已设置UploadListener,Uploader会回调UploadListener已实现的方法;若未设置,则不回调任何信息。UploadListener具体使用方法如下:
UploadListener uploadListener = new UploadListener(){
@Override
public void handleProcess(long range, long size, String videoId) {
// TODO 处理上传进度
}
@Override
public void handleException(DreamwinException exception, int status) {
// TODO 处理上传过程中出现的异常
}
@Override
public void handleStatus(VideoInfo videoInfo, int status) {
// TODO 处理上传回调的视频信息及上传状态,status=100(等待上传)、200(正在上传)、300(暂停上传)、400(上传完成)、500(上传失败)
}
@Override
public void handleCancel(String videoId) {
// TODO 处理取消上传的后续操作
}
@Override
public void onVideoInfoUpdate(VideoInfo videoInfo) {
// TODO 上传信息更新回调,可以在这里保存最新的videoInfo状态
}
};
uploader.setUploadListener(uploadListenner);
3.5 视频下载
SDK视频下载由Downloader类实现的,Downloader通过HTTP协议与服务端进行通信,获取视频下载地址。同时,SDK提供了下载回调接口DownloadListener来监听视频下载流程,如果需要向用户展示下载状态、下载进度等信息,可根据需要进行设置。
3.5.1 Downloader使用示例
在使用Downloader前,请先了解Downloader的工作流程:
- 创建Downloader实例,初始化视频文件下载信息,此时Downloader进入等待状态(WAIT)。
- 当需要开始下载时,调用start()方法,此时Downloader进入下载状态(DOWNLOAD)。
- 当需要暂停下载时,调用pause()方法。另外,在下载过程中可能出现网络异常问题,当出现此问题时,Downloader默认会暂停下载操作,进入暂停状态(PAUSE)。
- 当需要恢复下载时,调用resume()方法。若无网络异常等问题,此时Downloader会重新下载视频文件。
- 当需要取消视频下载时,调用cancel()方法,此时Downloader会进入等待状态(WAIT)。
创建Downloader实例需提供视频存储文件,视频ID,账户ID和API KEY。示例如下:
File file = new File("/123456.MP4");
String videoId ="123456";
Downloader downloader = new Downloader(file, videoId,"USERID","API_KEY");
// 开始下载
downloader.start();
SDK视频下载需指定文件存储路径,所以在创建Downloader实例时,请提供正确的文件存储路径。
3.5.2 设置下载回调
Downloader在执行下载操作时,默认会检查是否设置了DownloadListener。若已设置DownloadListener,Downloader会回调DownloadListener接口已实现的方法;若未设置,则不回调任何信息。DownloadListener使用方法如下:
DownloadListener downloadListener = new DownloadListener(){
@Override
public void handleProcess(long start, long end, String videoId) {
// TODO 处理下载进度
}
@Override
public void handleException(DreamwinException exception, int status) {
// TODO 处理下载过程中发生的异常信息
}
@Override
public void handleStatus(String videoId, int status) {
// TODO 处理视频下载信息及相应状态
}
@Override
public void handleCancel(String videoId) {
// TODO 处理取消下载的后续操作
}
};
downloader.setDownloadListener(downloadListener);
3.5.3 选择清晰度下载
流程如下:
- 创建Downloader实例;
- 调用setOnProcessDefinitionListener()方式设置清晰度回调;
- 调用getDefinitionMap()方法获取清晰度;
- 根据获取的清晰度,调用setDownloadDefinition()方法设置想要的清晰度;
- 调用start()下载指定清晰度。
获取清晰度时需实现OnProcessDefinitionListener接口的onProcessDefinition()方法,并调用Downloader的setOnProcessDefinitionListener()方法设置获取清晰度回调,获取清晰度的示例如下:
class DownloadDemo{
private HashMap<Integer, String> dm;
private Downlaoder downloader;
private OnProcessDefinitionListener onProcessDefinitionListener = new OnProcessDefinitionListener(){
@Override
public void onProcessDefinition(HashMap<Integer, String> definitionMap) {
if(definitionMap != null){
dm = definitionMap;
} else {
Log.e("get definition error", "视频清晰度获取失败");
}
}
@Override
public void onProcessException(DreamwinException exception) {
Log.i("get definition exception", exception.getErrorCode().Value());
}
};
private getDefinition(){
downloader.setOnProcessDefinitionListener(onProcessDefinitionListener);
downloader.getDefinitionMap();
}
……
}
3.5.4 设置下载重试次数
//设置下载重试次数,默认为0,可设置区间[0, 100]
setReconnectLimit(int reconnectLimit)
3.5.5 设置超时时间
//设置网络请求的超时时间,区间[5000-30000],单位为ms,默认值为10000ms
setTimeOut(int timeOut)
3.6 音频支持
SDK音频播放由DWMediaPlayer类实现,DWMediaPlayer继承了Android的媒体播放器MediaPlayer类,并重载其prepare()和prepareAsync()方法。
3.6.1 音频在线播放
目前播放器默认支持的为视频播放,想要进行音频播放,在prepareAsync()之前则需要如下设置:
player.setDefaultPlayMode(MediaMode.AUDIO, onPlayModeListener);
player.setAudioPlay(true);
player.prepareAsync();
如果默认设置的为支持音视频模式,那么从视频切换到音频的方法为如下:
player.reset();
player.setAudioPlay(true)
player.prepareAsync();
注:onPlayModeListener的回调返回该视频节点信息支持的播放模式。如果没有节点信息,onPlayModeListener的回调返回为null。
3.6.2 音频本地播放
参考章节3.3.2
3.6.3 音频下载
参考3.5。
- 下载前需要调用setDownloadMode(MediaMode downloadMode)来设置下载的模式
- 音频的后缀存储为.mp3或者.m4a
4. 功能使用
4.1 移动端广告
- 本功能需要后台开通移动广告;
- 广告核心类DWMediaAD提供能了获取广告信息的方法,广告详细信息通过DWMediaADListener监听器回调来获取;
- 广告分为前贴和暂停,需要分别调用方法来获取。其中前贴目前提供了视频和图片广告,暂停只有图片广告。
……
DWMediaAD mDWMediaAD = new DWMediaAD(dwMediaADlistener, USERID, videoId);
mDWMediaAD.getFrontAD();
mDWMediaAD.getPauseAD();
……
// 广告监听器
private DWMediaADListener dwMediaADlistener = new DWMediaADListener({
@Override
public void onPauseAD(PauseADInfo info) { //回调暂停广告信息
……
}
@Override
public void onFrontAD(FrontADInfo info) { //回调片头广告信息
……
}
@Override
public void onFrontADError(DreamwinException e) {
……
}
@Override
public void onPauseADError(DreamwinException e) {
}
};
注:目前只提供获取广告信息的接口,广告界面需要用户自行实现,具体可参见普通版demo的ADMediaPlayActivity.java类文件。
4.2 用户自定义参数播放统计功能
支持用户自定义参数实现播放的统计,可以通过调用player的setCustomId(String customId)方法来实现,其中customId为用户自己定义的参数值。
注:需要在prepareAsync()方法前调用才可以生效。
4.3 视频打点功能
支持用户自定义视频打点功能的回调,可以通过调用player的setOnHotspotListener(OnHotspotListener onHotspotListener)方法,当视频有打点信息时,在该接口中回调打点信息。
4.4 视频问答功能
支持用户自定义视频问答功能的回调,可以通过调用player的setOnQAMsgListener(OnQAMsgListener qaMsgListener)方法,当视频有问答信息时,在该接口中回调问答信息。
问答信息回调的格式为JSONArray,单条问答信息的内容如下,请用户自行解析
{"id":99,"content":"内容","showTime":2,"explainInfo":"解释答案","jump":false,"backSecond":-1,
"answers":[{"id":1045,"content":"A、答案A","right":false},{"id":1046,"content":"B、答案B","right":true},{"id":1047,"content":"C、答案C","right":false},{"id":1048,"content":"D、答案D","right":false}]}
4.5 视频显示字幕功能
支持从服务器获取字幕资源并显示,可以通过调用player的setOnSubtitleMsgListener(OnSubtitleMsgListener onSubtitleMsgListener)方法,当有字幕资源时,在该接口中回调字幕信息。
player.setOnSubtitleMsgListener(new OnSubtitleMsgListener() {
@Override
public void onSubtitleMsg(String url, String font, int size, String color, String surroundColor, double bottom, String code) {
url:字幕资源地址; font:字体名称,需要在工程的assets(没有请自行创建)文件夹下有对应的字体文件; size:字体大小; color:字体颜色;surroundColor:字体环绕色;
bottom:距离底部的边距占手机屏幕宽度的百分比, code:字幕编码格式,如utf-8
注意:设置这些字幕样式需要在主线程操作
}
});
4.6 错误处理
DWMediaPlayer重载了MediaPlayer的setOnErrorListener()方法,如果需要在应用中提示错误信息,可调用此方法设置OnErrorListener。具体实现方式如下:
private OnErrorListener onErrorListener = new OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
//TODO 处理错误信息
return false;
}
};
player.setOnErrorListener(onErrorListener);
4.7 如何更好的使用SDK Demo
SDK Demo是使用SDK对接CC视频云服务的示例源码,目前支持Android4.0及以上版本。Demo的设计旨在展示SDK各项功能的使用方法,如果希望应用获得更好的使用体验,可根据需求自行更改。
4.7.1 准备
在编译安装Demo前,请按照以下操作进行配置:
- 设置帐户信息,在ConfigUtil类中配置USERID(帐户ID)和API KEY。
public final static String API_KEY = "API KEY";
public final static String USERID = "123456";
- 添加播放列表,在PlayFragment类中配置playVideoIds(可播放的视频ID)。
//TODO 待播放视频ID列表,可根据需求自定义
private String[] playVideoIds = new String[] {
"123456",
"234567",
"345678",
"111111"};
- 添加下载列表,在DownloadFragment类中配置downloadVideoIds(可下载的视频ID)。
//TODO 待下载视频ID,可根据需求自定义
private String[] downloadVideoIds = new String[] {
"123456",
"234567",
"345678",
"111111"};
4.7.2 功能模块简介
Demo包含播放、上传和下载三个功能模块:
-
播放模块,展示了在线播放,屏幕缩放,清晰度切换,字幕等功能,具体实现请参考PlayFragment及MediaPlayActivity类。
-
上传模块,展示了视频上传的处理流程,及如何使用SDK进行后台上传,具体实现请参考UploadFragment及UploadService类。
-
下载模块,展示了视频下载的处理流程,及如何使用SDK进行后台下载,具体实现请参考DownloadFragment及DownloadService类。
4.7.3 demo使用注意事项
- 音频相关请参考普通demo
- AccountInfoActivity.java里面增加了默认播放、下载的配置
- 下载部分数据表更新,老用户请卸载老demo在安装
4.7.4 使用Demo的视频压缩功能
Demo提供了视频压缩功能,可以选择高质量压缩、中质量压缩、低质量压缩,压缩质量越高,压缩出来的文件就相对较大 高质量压缩:
* @param filePath 源文件路径
* @param compressOutPut 输出文件路径
* @param VideoCompress.CompressListener 压缩过程监听
VideoCompress.compressVideoHigh(filePath, compressOutPut, new VideoCompress.CompressListener() {
@Override
public void onStart() {
}
@Override
public void onSuccess() {
}
@Override
public void onFail() {
}
@Override
public void onProgress(float percent) {
}
});
中质量压缩:
* @param filePath 源文件路径
* @param compressOutPut 输出文件路径
* @param VideoCompress.CompressListener 压缩过程监听
VideoCompress.compressVideoMedium(filePath, compressOutPut, new VideoCompress.CompressListener() {
@Override
public void onStart() {
}
@Override
public void onSuccess() {
}
@Override
public void onFail() {
}
@Override
public void onProgress(float percent) {
}
});
低质量压缩:
* @param filePath 源文件路径
* @param compressOutPut 输出文件路径
* @param VideoCompress.CompressListener 压缩过程监听
VideoCompress.compressVideoLow(filePath, compressOutPut, new VideoCompress.CompressListener() {
@Override
public void onStart() {
}
@Override
public void onSuccess() {
}
@Override
public void onFail() {
}
@Override
public void onProgress(float percent) {
}
});
4.8 倍速功能
倍速功能使用第三方库IjkMediaPlayer v0.8.4来实现。倍速播放功能需要使用DWIjkMediaPlayer类,该类继承自第三方库IjkMediaPlayer的IjkMediaPlayer类,该类的使用方法和DWMediaPlayer一样。
IjkMeidaPlayer的github地址如下:(请参考链接:https://github.com/Bilibili/ijkplayer)
设置倍速方法如下:
player.setSpeed();
ijkspeed文件夹为ijk所需要的so文件和jar,请放到自己的工程目录使用。
4.9 辅助调试工具
SDK提供HTTP通信日志调试功能。在使用SDK进行播放、上传、下载过程中,如果遇到与网络通信相关的问题,可通过设置HTTP日志的级别获取通信信息。使用示例如下:
// 设置HTTP通信日志级别
HttpUtil.LOG_LEVEL = HttpLogLevel.DETAIL;
默认日志级别为GENERAL(记录HTTP通信发生时间、响应状态码)。
4.10 问答统计功能
要统计问答的结果,只需在提交答案时调用下面这个方法:
* @param vid 加密的视频ID
* @param qid 问题ID
* @param answer 用户选择的选项ID,以逗号分隔多个选项ID。如1345是单选;2067,3092,4789是多选。
* @param status 用户答题的结果。1=正确;0=错误。
QaStatistics.reportQaResult(String vid, String qid, String answer, String status);
4.11 授权验证功能
从服务器获取授权验证信息,可以通过调用player的setOnAuthMsgListener(OnAuthMsgListener onAuthMsgListener)方法,在该接口中回调授权验证信息。
* @param enable 视频是否可以完整播放 0:不允许完整播放 1:允许完整播放
* @param freetime 视频试看时间,单位:秒
* @param messaage 不允许播放,或者试看结束时播放器显示的提示内容
player.setOnAuthMsgListener(new OnAuthMsgListener() {
@Override
public void onAuthMsg(int enable,int freetime, String messaage) {
}
});
5. API查询
https://github.com/CCVideo/VOD_Android_SDK/tree/master/doc/api
6. Q&A
6.1 无法播放视频
1.检查已配置的帐户是否开通移动端播放权限
2. 根据HTTP通信日志,排查网络问题
3. 检查视频状态是否正常
6.2 上传视频出现异常
1. 检查已配置的帐户是否开通了客户端上传权限
2. 根据HTTP通信日志,排查网络问题
6.3 下载视频出现异常
1. 检查已配置的帐户是否开通了移动端权限
2. 根据HTTP通信日志,排查网络问题
3. 检查视频状态是否正常
6.4 CC点播SDK和CC直播SDK同时引入时出现问题
在非加密的情况下,加上player.setHttpsPlay(false);