#KSYMediaPlayer-Android-SDK
##SDK更新日志
2015-12-09
- 新增setRetryCount及setRetryAlways接口,用于设置hls切片播放失败时重试次数,setRetryAlways表示将一直重试,直到最后一片
- 增加提前显示第一帧策略
- 增加快速追赶,同时丢弃Video frame策略。主要是修改setLowDelayEnabled接口,第一个参数由原来boolean型开关改为Int型Mode,分别对应直播追赶策略为不丢帧、只丢音频、丢音频及视频这三种类型
- 修复锁屏视频卡死,audio播放正常的问题
- 修复Hls seek到最后一帧出现 block的问题
- Rtmp直播协议release时间超过2s,新版本release时间不超过1s
2015-11-23
- 修正多次seek出现崩溃问题
2015-11-19
- 修正可能重复创建实例情况
- 整理相关日志
2015-11-12
- 关闭打点日子
- 添加获取消耗总流量统计
2015-11-11
- 修正HLS协议出现Discontinuity,导致播放器进度条、seek、结束状态不对的Bug
- 修正上次修改后,点播视频到播放结束不能正常发送complete的消息的Bug
- 修正getCurrentPosition及getDuration反馈不准的Bug
- 修正播放器UI上,时间格式UI显示不完整问题
2015-10-19
- 修正了播放器卡顿后,延迟变大,通过丢弃cache视频帧解决延迟问题
- 修正了媒体文件只有单路音频,造成crash的问题
- 修正了播放器长时间播放,视频卡死问题
2015-09-06
- 支持播放视频时获取下载速率,在OnInfoListener里新增事件MEDIA_INFO_GET_SPEED,返回的extra参数表示当前下载速率,单位为Byte
- 支持setDataSource支持设置Header,新增接口:public void setDataSourceAndHeader(String url, Map<String, String> headers){};
- 支持获取网络视频的目标地址的IP:public Bundle getMediaMeta() {}中返回Bundle里,Key为"source_ip"
- 支持允许暂停后下载:public void setCacheInPause (boolean useCacheInPause) throws IOException
##SDK接口说明
- 开启低时延模式public void setLowDelayEnabled(boolean ennable),会启用播放器丢帧策略,目前仅用于直播模式,点播模式请用户关闭,否则会影响播放(表现为视频和音频卡顿)。
- KsyMediaPlayer的BufferUpdateListener,回调的是当前边播放边缓存的进度
- KsyMediaPlayer的InfoListener,回调的是Buffer为空引起的BufferingBegin和BufferingEnd事件,以及当前下载速率事件。
##SDK支持 目前播放器SDK支持的流媒体传输协议有:
- RTMP,HTTP,HLS及RTSP(RTP,SDP)
解码基于FFMPEG,音视频格式支持列表如下(以下仅列出常见格式)
- MP4,3GP,FLV,TS/TP,RMVB ,MKV,M4V,AVI,WMV ,MKV
##SDK使用说明
###结构 SDK包含三个工程,其中
- KSYMediaPlayer- 播放器核心Library库
- KSYMediaWidget- 播放器UI-Library库
- KSYMediaDemo- SDK demo app
其中KSYMediaPlayer/libs/目录下,是不同指令集CPU对应的播放器底层so包,分为:
- libksyffmpeg.so
- libksyplayer.so
- libksyrtmp.so
- libksyutil.so
###集成
根据用户的需求,可以选择两种方式集成:
-
如果仅需要播放器核心库,不需要UI及上层逻辑,那么仅需引入播放器核心库KsyMediaPlayer,其使用方式类似原生Android的MediaPlayer,具体接口文档请参考javadoc
-
如果需要播放器及对应UI,用户需要引入播放器核心库KsyMediaPlayer以及播放器UI库KsyMediaWidget两个library project。在自己的Acitivity中,使用com.ksy.media.widget.MediaPlayerView,实现MediaPlayerView.PlayerViewCallback回调即可,具体代码请参考KSYMediaDemo
###Manifest权限申明
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
##功能及API说明 ###DRM说明 客户如果采用直播的形式推流到金山云流媒体服务器,那么可以选择是否采用我们的DRM加密服务。播放器端基于自定义对称加解密算法对关键帧进行解密,播放器支持三种形式获取解密Key,更加安全可靠。
由于请求DRM解密Key的URL参数中存在我们的鉴权签名信息(signature),出于安全性考虑,用户可以自行选择以下三种模型之一来获取Key。 无论使用哪种模型,app开发者都需要实现IDRMRetriverRequest两个接口⽅法,这些接⼝⽅法都在线程池执行,用户无需开启新的线程。
1.app提供AK,sk完成签名,并且提供完整取Key URL的方式(不安全,建议仅测试时使用)
//这种本地签名,生成完整url的⽅方式 ,需要APP 保存AK ,SK ,计算签名无需用户实现,也不需要通过用户server
//接口调用方法:
public DRMKey retriveDRMKeyFromAppServer(String cekVersion,String cekUrl){
return null;
}
//返回null就可以
public DRMFullURL retriveDRMFullUrl(String cekVersion,String cekUrl) throwsException{
DRMFullURLfullURL= new DRMFullURL("@AK" , "@SK" ,cekUrl,
cekVersion);
return fullURL;
}
2.app提供不存放AK,SK,app从appserver获取drm完整url,之后再从ksyserver获取drm
//app携带cekURL和cekVersion信息去appserver获取完整drm路径之后,再请求ksyserver获取DRM,开发者只需要实现
public DRMFullURL retriveDRMFullUrl(String cekVersion,String cekUrl)throws Exception{
//发送http请求,从appserver获取drmurl,之后将url拆解成DRMFullURL对象
returnfullURL;
}
public DRMKey retriveDRMKeyFromAppServer(String cekVersion,String cekUrl){
return null;
}
3.app提供不存放AK,SK,由appserver访问ksyserver获取drm后返回给APP
//app携带cekURL和cekVersion信息发送给appserver,appserver生成完整url之后去ksy服务器获取完整drm之后返回给app,开发者只需要实现
public DRMFullURL retriveDRMFullUrl(String cekVersion,String cekUrl)throws Exception{
DRMFullURL fullURL= new DRMFullURL(cekUrl,cekVersion)
return fullURL;
//直接将参数返回即可
}
public DRMKey retriveDRMKeyFromAppServer(String cekVersion,String cekUrl){
//开发者需要在这里构建
http请求appserver获取drm
return DRMKey;
}
KSY Server获取解密KEY的接口如下所示:
####请求解密Key接口 GET NewCek
此GET为cek-url创建一个cek密钥串(16进制), 并返回此cek
HTTP/1.1 GET /xiaoyi/NewCek?signature=Wq4VjoEnqbldJe6HfRyTkRavcRg=&accesskeyid=8oN7siZgTOSFHft0cXTg&expire=1710333224&nonce=466cc944cdd58b9d&cekurl=rtmp://live.ksyun.com/xiaoyi/ipc1
Host: drm.ksyun.com
Date: Wed, 28 Oct 2009 22:32:00 GMT
请求参数描述:
signature:使用ks3颁发的AK,SK对数据进⾏行签名
accesskeyid:ks3颁发的AK.
expire:对应于本次请求的超时时间. 本地计算签名超时时间当前UTC时间 + 3600秒
nonce:相当于本次请求的UID.本地计算签名随机数为expire
resource:camera对应的URL
version:DRM版本号,播放器提供
成功响应示例:
HTTP/1.1 200 OK
Content-Length: length
Content-Type: text/plain
Date: Wed, 28 Oct 2009 22:32:00 GMT
Server: Nginx
<?xml version="1.0" encoding="UTF-8"?>
<Result>
<Cek>c1cbf122374d55bba69595f0f58d5c80</Cek>
</Result>
错误响应示例:
HTTP/1.1 400 Bad Request
Content-Length: length
Content-Type: text/plain
Date: Wed, 28 Oct 2009 22:32:00 GMT
Server: Nginx
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>BadParams</Code>
<Message>Expire must be a number</Message>
</Error>
app开发者需要实现IDRMRetriverRequest两个接口方法,两个接口方法都在线程池执行,无需开启新的线程
public abstract DRMFullURL retriveDRMFullUrl(String cekVersion,StringcekUrl)throws Exception;
//获取drm的url完整路径,如上url实例
//方案1:如果直接返回
DRMFullURLfullURL=newDRMFullURL("@AK" ,"@SK" ,cekUrl,cekVersion);
//默认采⽤本地⽣成url⽅式直接从ksy务器获取drm
//retriveDRMKeyFromAppServer无需实现
//方案2:如果AKSK存放在appserver,那么这个接口方法开发者需要执行http请求访问appserver获取drm的完整路径,并且将url的各项参数拆解成DRMFullURL,returnDRMFullURLfullURL=newDRMFullURL(kSCDRMHostPort,customerName,
drmMethod,signature,accessKey,expire,noce,cekUrl,version);
//retriveDRMKeyFromAppServer接口方法就无需实现。
//方案3:如果直接返回DRMFullURLfullURL= new DRMFullURL(cekUrl,cekVersion);那么就采用第三种方式,在appserver生成完整url,并且由appserver访问ksyserver获取drm之后直接返回给app,retriveDRMKeyFromAppServer
接口就需要开发者实现从appserver获取drm接口
###错误码对应表
错误码 | 错误类型 | 描述 |
---|---|---|
10000 | ERROR_UNKNOWN | 未知错误 |
10001 | ERROR_IO | IO错误 |
10002 | ERROR_TIMEOUT | 请求超时 |
10003 | ERROR_UNSUPPORT | 不支持的格式 |
10004 | ERROR_NOFILE | 文件不存在 |
10005 | ERROR_SEEKUNSUPPORT | 当前不支持seek |
10006 | ERROR_SEEKUNREACHABLE | 当前seek不可达 |
10007 | ERROR_DRM | DRM出错 |
10008 | ERROR_MEM | 内存溢出 |
10009 | ERROR_WRONGPARAM | 参数错误 |