播放
短视频列表播放
针对典型的短视频列表播放场景,Android端播放器SDK提供了完善的列表播放功能,结合预加载等机制大幅改善短视频的起播速度。长视频场景不建议使用该功能。
使用限制
AliListPlayer存在以下限制,推荐使用多个AliPlayer的方式来实现短视频列表播放。,详细内容请参见通过列表播放提升沉浸式短视频播放体验。
AliListPlayer不支持PlayAuth方式播放。
AliListPlayer不支持多实例,要保持全局单实例,使用多个AliListPlayer会出现视频源混乱的问题。
5.4.5.0以前版本的Android端播放器SDK中,AliListPlayer不支持m3u8格式的视频;5.4.5.0及以后版本的Android端播放器SDK才支持m3u8格式的视频(需要打开本地缓存功能)。
操作步骤
创建播放器。
通过AliPlayerFactory
类创建AliListPlayer播放器。示例如下:
AliListPlayer aliyunListPlayer;
.....
aliyunListPlayer = AliPlayerFactory.createAliListPlayer(getApplicationContext());
aliyunListPlayer.setTraceId("traceId"); //traceId为设备或用户的唯一标识符,通常为imei或idfa
可选:设置监听器。
创建列表播放时,监听器为非必须配置,但如果不设置,将无法收到播放器的播放失败、播放进度等事件通知,因此,建议您设置。其中OnPreparedListener
、OnErrorListener
、OnCompletionListener
、OnLoadingStatusListener
、OnInfoListener
较为重要,建议您设置。
展开查看代码
aliyunListPlayer.setOnCompletionListener(new IPlayer.OnCompletionListener() {
@Override
public void onCompletion() {
//播放完成事件
}
});
aliyunListPlayer.setOnErrorListener(new IPlayer.OnErrorListener() {
@Override
public void onError(ErrorInfo errorInfo) {
//出错事件
}
});
aliyunListPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() {
@Override
public void onPrepared() {
//准备成功事件
}
});
aliyunListPlayer.setOnVideoSizeChangedListener(new IPlayer.OnVideoSizeChangedListener() {
@Override
public void onVideoSizeChanged(int width, int height) {
//视频分辨率变化回调
}
});
aliyunListPlayer.setOnRenderingStartListener(new IPlayer.OnRenderingStartListener() {
@Override
public void onRenderingStart() {
//首帧渲染显示事件
}
});
aliyunListPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
@Override
public void onInfo(int type, long extra) {
//其他信息的事件,type包括了:循环播放开始,缓冲位置,当前播放位置,自动播放开始等
}
});
aliyunListPlayer.setOnLoadingStatusListener(new IPlayer.OnLoadingStatusListener() {
@Override
public void onLoadingBegin() {
//缓冲开始。
}
@Override
public void onLoadingProgress(int percent, float kbps) {
//缓冲进度
}
@Override
public void onLoadingEnd() {
//缓冲结束
}
});
aliyunListPlayer.setOnSeekCompleteListener(new IPlayer.OnSeekCompleteListener() {
@Override
public void onSeekComplete() {
//拖动结束
}
});
aliyunListPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() {
@Override
public void onSubtitleShow(long id, String data) {
//显示字幕
}
@Override
public void onSubtitleHide(long id) {
//隐藏字幕
}
});
aliyunListPlayer.setOnTrackChangedListener(new IPlayer.OnTrackChangedListener() {
@Override
public void onChangedSuccess(TrackInfo trackInfo) {
//切换音视频流或者清晰度成功
}
@Override
public void onChangedFail(TrackInfo trackInfo, ErrorInfo errorInfo) {
//切换音视频流或者清晰度失败
}
});
aliyunListPlayer.setOnStateChangedListener(new IPlayer.OnStateChangedListener() {
@Override
public void onStateChanged(int newState) {
//播放器状态改变事件
}
});
aliyunListPlayer.setOnSnapShotListener(new IPlayer.OnSnapShotListener() {
@Override
public void onSnapShot(Bitmap bm, int with, int height) {
//截图事件
}
});
设置预加载个数。
合理设置预加载个数,能够有效的提高起播的速度。示例如下:
//设置预加载个数。总共加载的个数为: 1 + count*2。
aliyunListPlayer.setPreloadCount(int count);
添加或移除多个播放源。
列表播放支持两种播放源:VidSts播放和UrlSource播放。Url为视频的播放地址。示例如下:
//添加VidSts播放源
aliyunListPlayer.addVid(String videoId, String uid);
//添加UrlSource播放源
aliyunListPlayer.addUrl(String url, String uid);
//移除某个源
aliyunListPlayer.removeSource(String uid);
设置显示View。
播放器支持SurfaceView和TextureView,任选其中一种即可。
设置SurfaceView,示例如下:
展开查看代码
SurfaceView surfaceView = findViewById(R.id.surface_view);
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
aliyunListPlayer.setSurface(holder.getSurface());
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
aliyunListPlayer.surfaceChanged();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
aliyunListPlayer.setSurface(null);
}
});
设置TextureView,示例如下:
展开查看代码
TextureView textureView = findViewById(R.id.texture_view);
textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
aliyunListPlayer.setSurface(new Surface(surface));
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
aliyunListPlayer.surfaceChanged();
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
aliyunListPlayer.setSurface(null);
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
});
播放视频源。
添加了一个或多个播放源之后并设置自动播放,调用moveTo
便可以自动播放某个视频源。示例如下:
展开查看代码
//开启自动播放
aliyunListPlayer.setAutoPlay(true);
//url时使用此接口
aliyunVodPlayer.moveTo(String uid);
//vid的时候使用此接口,需要传递stsInfo即STS临时凭证和临时AK对,需要提前获取,获取方式请参见创建RAM角色并进行STS临时授权。
aliyunVodPlayer.moveTo(String uid, StsInfo info);
播放上一个、下一个视频。
播放器提供了moveToPrev
,moveToNext
接口用于播放上一个,下一个视频。示例如下:
展开查看代码
//开启自动播放
aliyunListPlayer.setAutoPlay(true);
//移动到下一个视频。 注意:只能用于url的源。这个方法不适用于vid的播放。
aliyunVodPlayer.moveToNext();
//移动到上一个视频。注意:只能用于url的源。这个方法不适用于vid的播放。
aliyunVodPlayer.moveToPrev();
//移动到下一个视频。注意:只能用于vid的播放。
aliyunVodPlayer.moveToNext(StsInfo info);
// 移动到上一个视频。注意:只能用于vid的播放。
aliyunVodPlayer.moveToPrev(StsInfo info);
可选:使用预渲染实例提升视频切换的顺畅度。
说明 Android端播放器SDK 5.5.2.0及以上版本才支持本功能,并且需要开启本地缓存,开启方法请参见本地缓存。
Android端播放器SDK从5.5.2.0版本开始提供getPreRenderPlayer
和moveToNextWithPrerendered
接口,用于提升滑动切换到下一个视频播放时的顺畅度,根据您的SDK集成场景不同,其使用方法有所差异,具体如下:
全新集成5.5.2.0及以后版本
使用PreRenderPlayer来实现。示例代码如下:
展开查看代码
//preRenderPlayer只能在moveToNext时使用,并且需要开启本地缓存。
IPlayer preRenderPlayer = listPlayer.getPreRenderPlayer();
if (preRenderPlayer != null) {
//设置surface
preRenderPlayer.setSurface(surface);
preRenderPlayer.start();
listPlayer.setSurface(null);
//STS播放方式,将moveToNext接口替换成moveToNextWithPrerendered
listPlayer.moveToNextWithPrerendered(createStsInfo(source));
}
从低版本升级至5.5.2.0及以后版本
您需要修改低版本SDK的代码实现,具体如下:
修改渲染View。
低版本的Android端播放器SDK全局使用一个渲染View,在每次切换播放源时,先从布局中remove前一个View,再添加下一个View到当前界面上。从5.5.2.0版本开始,支持使用多个渲染View,在RecyclerView.ViewHolder
的布局中添加多个View,在切换播放源时,可以预加载下一个播放源,以提升切换的顺畅度。您需要删除低版本的渲染View的代码,并添加新版本添加多个渲染View的代码,示例代码如下:
展开查看代码
/*
删除如下代码
如下几行代码为低版本添加渲染View的代码。会将渲染View添加到FrameLayout中,然后在切换播放源时,会将mPlayerViewContainer移除、添加。
*/
private void initPlayer() {
//...
mPlayerViewContainer = View.inflate(getContext(), R.layout.layout_player_view, null);
FrameLayout frameLayout = mPlayerViewContainer.findViewById(R.id.framelayout);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT);
View renderView = createRenderView(Common.RENDER_VIEW_NAME);
frameLayout.addView(renderView, 0, params);
//...
}
/*
添加或修改如下代码以添加多个渲染View
修改RecyclerView的item布局,以及对应的ViewHolder
*/
public final class MyHolder extends RecyclerView.ViewHolder {
//...
private Surface mSurface;
MyHolder(@NonNull View itemView) {
super(itemView);
//...
TextureView mTextureView = itemView.findViewById(R.id.texture_view);
mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mSurface = new Surface(surface);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
mSurface = null;
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {}
});
}
//...
//对外呈现获取Surface的接口
public Surface getSurface() {
return mSurface;
}
}
修改RecyclerView中的item布局的示例代码如下:
展开查看XML
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black">
<TextureView
android:id="@+id/texture_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- 删除封面图片,如果效果不好,可以保留封面图片的相关逻辑。 -->
<!-- <FrameLayout-->
<!-- android:id="@+id/player_view"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- android:clickable="false"-->
<!-- android:clipChildren="false"-->
<!-- android:focusable="false">-->
<!-- <ImageView-->
<!-- android:id="@+id/img_thumb"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- android:layout_gravity="center"-->
<!-- android:adjustViewBounds="true"-->
<!-- android:clickable="false"-->
<!-- android:focusable="false"-->
<!-- android:scaleType="fitXY" />-->
<!-- </FrameLayout>-->
</FrameLayout>
修改切换播放源的逻辑。
从Android端播放器SDK 5.5.2.0版本开始,在调用moveToNext
时,会增加对preRenderPlayer
的调用,因此需要单独对渲染View(Surface)进行设置。其中,moveToNext
、moveToPre
、moveTo
的逻辑有所差异。示例代码如下:
展开查看代码
/*
说明:mQuickPlayer是AlivcQuickPlayer类的实例对象,封装了ListPlayer的接口。
*/
private void startPlay(int position, boolean isInitComplete) {
//...
//根据position获取ViewHolder实例对象
LittleVideoListAdapter.MyHolder holder = (LittleVideoListAdapter.MyHolder) recycler.findViewHolderForLayoutPosition(position);
//...
//1.moveToPre时,先设置Surface,再调用moveToPre
if (holder != null) {
mQuickPlayer.setSurface(holder.getSurface());
}
mQuickPlayer.moveToPrev(video, position, mVideoSourceType);
//2.moveTo时,先设置Surface,再调用moveTo
if (holder != null) {
mQuickPlayer.setSurface(holder.getSurface());
}
//mQuickPlayer.startPlay()内部最终会调用moveTo()接口
mQuickPlayer.startPlay(video, position, mVideoSourceType);
//3.moveToPre时,需要增加一个参数,将Surface传递进去
mQuickPlayer.moveToNext(video, position, mVideoSourceType, holder.getSurface());
//...
}
修改AlivcQuickPlayer
类的示例代码如下:
展开查看代码
//修改moveToPre方法
public void moveToPrev(AlivcVideoInfo.Video source, final int position, VideoSourceType videoSourceType) {
//...
//增加如下代码
mVideoListPlayer.clearScreen();
if (videoSourceType == VideoSourceType.TYPE_STS) {
mVideoListPlayer.moveToPrev(createStsInfo(source));
} else {
mVideoListPlayer.moveToPrev();
}
}
//增加moveToNext的重载方法
public void moveToNext(AlivcVideoInfo.Video source, int position, VideoSourceType videoSourceType, Surface surface) {
//...
//moveToNext时,可以获取preRenderPlayer对象,并使用该Player播放
IPlayer preRenderPlayer = mVideoListPlayer.getPreRenderPlayer();
if (preRenderPlayer != null) {
preRenderPlayer.clearScreen();
preRenderPlayer.setSurface(surface);
preRenderPlayer.start();
mVideoListPlayer.setSurface(null);
} else {
mVideoListPlayer.clearScreen();
mVideoListPlayer.setSurface(surface);
}
//STS播放方式
if (videoSourceType == VideoSourceType.TYPE_STS) {
//当preRenderPlayer不为null时候,调用moveToNextWithPrerendered进行播放
if (preRenderPlayer != null) {
mVideoListPlayer.moveToNextWithPrerendered(createStsInfo(source));
} else {
mVideoListPlayer.moveToNext(createStsInfo(source));
}
} else {
//URL播放方式
if (preRenderPlayer != null) {
mVideoListPlayer.moveToNextWithPrerendered();
} else {
mVideoListPlayer.moveToNext();
}
}
}
可选:修改滑动播放的逻辑。
支持通过修改滑动播放的逻辑,实现在滑动切换视频时,当滑动到下一个视频的一半画面出现时,开始播放下一个视频。通过修改PagerLayoutManager
类中的代码实现,即当RecyclerView的item出现在屏幕一半时,切换播放源,示例代码如下:
展开查看代码
recyclerView.addOnScrollListener(new OnScrollListener() {
private int measuredHeight;
private int mScrollDiff;
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
measuredHeight = recyclerView.getMeasuredHeight();
mScrollDiff = 0;
}
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
mScrollDiff = 0;
View viewIdle = mPagerSnapHelper.findSnapView(PagerLayoutManager.this);
if (viewIdle == null) {
return;
}
int positionIdle = getPosition(viewIdle);
if (mOnViewPagerListener != null && getChildCount() == 1 && mOldPosition != positionIdle) {
mOnViewPagerListener.onPageSelected(positionIdle, positionIdle == getItemCount() - 1, viewIdle);
mOldPosition = positionIdle;
}
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (measuredHeight > 0 && mOnViewPagerListener != null) {
mScrollDiff += dy;
changeVideoAfterScrolled(recyclerView, dy >= 0);
}
}
private void changeVideoAfterScrolled(RecyclerView recyclerView, boolean isNext) {
if (Math.abs(mScrollDiff) >= measuredHeight / 2) {
View snapView = mPagerSnapHelper.findSnapView(PagerLayoutManager.this);
if (snapView != null) {
int position = getPosition(snapView);
if (mOldPosition != position) {
if (isNext) {
mOnViewPagerListener.onPageHideHalf(position - 1);
} else {
mOnViewPagerListener.onPageHideHalf(position + 1);
}
mOnViewPagerListener.onPageSelected(position, false, snapView);
mOldPosition = position;
recyclerView.smoothScrollToPosition(position);
mScrollDiff = 0;
}
}
}
}
});
播放带透明度视频
功能简介
阿里云播放器SDK支持渲染Alpha通道,实现播放透明礼物的动态效果。在直播间等场景中,播放透明礼物动效且不会遮挡直播间内容,明显提升用户观看和互动体验。
使用限制
一体化SDK6.8.0及以后版本或播放器SDK6.9.0及以后版本支持透明渲染能力。
功能优势
使用带有透明度信息的MP4视频作为礼物特效可以提供更好的动效质量,较小的文件体积,更高的兼容性和更高的开发效率。这使得礼物特效能够更好地展示给用户,提升用户体验。
更好的动效质量:MP4视频可以保留原始的动效质量,包括细节和颜色等,相比于其他格式,如 APN 或IXD,MP4可以更准确地还原设计师创作的动效效果。
较小的文件体积:MP4视频文件相比于其他格式,如APNG或IXD,可以更有效地压缩文件体积,提升加载速度并降低网络带宽消耗。
更高的兼容性:MP4视频是一种通用的视频格式,在各种设备和浏览器中都得到广泛支持,支持在主流设备上播放和观看礼物特效。
更高的开发效率:使用MP4视频作为礼物特效的技术方案相对简单,不需要开发人员去研究和实现复杂的解析和渲染逻辑,开发人员可以专注于其他功能的实现,提高开发效率。
示例代码
新增如下接口:设置alpha模式(alpha通道在视频素材的方位:上、下、左、右),默认值是None。
/**
* 设置Alpha渲染模式
*
* @param alphaRenderMode 镜像模式。见{@link AlphaRenderMode}。
*/
/****
* Set a alpha render mode
*
* @param alphaRenderMode The specified alpha render mode. See {@link AlphaRenderMode}.
*/
abstract public void setAlphaRenderMode(AlphaRenderMode alphaRenderMode);
//--------------View用法-------------
// 对于View需要设置透明
//TextureView
TextureView aliplayerView; //用于播放的 view
aliplayerView.setOpaque(false);
//SurfaceView
SurfaceView aliplayerView; //用于播放的 view
aliplayerView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
aliplayerView.setZOrderOnTop(true); //把SurfaceView置于显示窗口的最顶层
//-----------AliPlayer用法-----------
//设置alpha模式
aliplayer.setAlphaRenderMode(IPlayer.AlphaRenderMode.RENDER_MODE_ALPHA_AT_RIGHT);
//设置alpha模式对应的素材
UrlSource urlSource = new UrlSource();
urlSource.setUri("https://alivc-player.oss-cn-shanghai.aliyuncs.com/video/%E4%B8%9A%E5%8A%A1%E9%9C%80%E6%B1%82%E6%A0%B7%E6%9C%AC/alpha%E9%80%9A%E9%81%93/alpha_right.mp4");
aliplayer.setDataSource(urlSource);
aliplayer.setOnCompletionListener(new IPlayer.OnCompletionListener() {
@Override
public void onCompletion() {
//可选:单实例播放完成后如果有衔接问题,可以清屏
aliplayer.clearScreen();
}
}
aliplayer.setAutoPlay(true);
aliplayer.prepare();
外挂字幕
Android端播放器SDK支持添加和切换外挂字幕,现已支持SRT、SSA、ASS、VTT这4种格式的字幕。示例如下:
创建显示字幕的View。
根据不同的字幕格式创建不同的View。
//用于显示SRT和VTT字幕
SubtitleView subtitleView = new SubtitleView(getContext());
//用于显示ASS和SSA字幕
AssSubtitleView assSubtitleView = new AssSubtitleView(getContext());
//将字幕View添加到布局视图中
viewGroup.addView(assSubtitleView);
设置字幕相关监听。
展开查看代码
mAliPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() {
@Override
public void onSubtitleExtAdded(int trackIndex, String url) { }
@Override
public void onSubtitleShow(int trackIndex, long id, String data) {
// ass 字幕
assSubtitleView.show(id,data);
// srt 字幕
SubtitleView.Subtitle subtitle = new SubtitleView.Subtitle();
subtitle.id = id + "";
subtitle.content = data;
subtitleView.show(subtitle);
}
@Override
public void onSubtitleHide(int trackIndex, long id) {
// ass 字幕
assSubtitleView.dismiss(id);
// srt 字幕
subtitleView.dismiss(id + "");
}
@Override
public void onSubtitleHeader(int trackIndex, String header) { }
});
添加字幕。
mAliPlayer.addExtSubtitle(url);
切换字幕。
//trackIndex:传入字幕索引;true:表示显示传入的字幕;false:表示隐藏传入的字幕
mAliPlayer.selectExtSubtitle(trackIndex, true);
纯音频播放
通过禁用视频播放,达到纯音频播放的效果。在prepare之前配置PlayerConfig。
PlayerConfig config = mAliPlayer.getConfig();
config.mDisableVideo = true; //设置开启纯音频播放
mAliPlayer.setConfig(config);
软硬解切换
说明 解码方式需要在播放前切换,播放中切换解码方式将不会生效。
Android端播放器SDK提供了H.264、H.265的硬解码能力,同时提供了enableHardwareDecoder
提供开关。默认开,并且在硬解初始化失败时,自动切换为软解,保证视频的正常播放。示例如下:
//开启硬解。默认开启
mAliyunVodPlayer.enableHardwareDecoder(true);
如果从硬解自动切换为软解,将会通过onInfo
回调,示例如下:
mApsaraPlayerActivity.setOnInfoListener(new IPlayer.OnInfoListener() {
@Override
public void onInfo(InfoBean infoBean) {
if (infoBean.getCode() == InfoCode.SwitchToSoftwareVideoDecoder) {
//切换到软解
}
}
});
网络自适应切换视频清晰度
说明 HLS的多码率自适应视频流可以在视频点播中经过视频打包转码模板组进行转码处理后生成,详细操作请参见点播多码率自适应配置。
经过视频点播转码生成的自适应流,如果使用Vid方式播放,则需要指定默认播放清晰度列表为DEFINITION_AUTO
,才会获取并播放自适应的视频流;否则将按照默认逻辑选择低清晰度的视频流进行播放,默认清晰播放顺序请参见清晰度相关问题。以VidAuth播放方式为例,指定清晰度列表的示例如下:
VidAuth vidAuth = new VidAuth();
List<Definition> list = new ArrayList<>();
list.add(Definition.DEFINITION_AUTO);
vidAuth.setDefinition(list);
Android端播放器SDK支持多码率自适应HLS、DASH视频流。在prepare
成功之后,通过getMediaInfo
可以获取到各个码流的信息,即TrackInfo
。示例如下:
List<TrackInfo> trackInfos = aliyunVodPlayer.getMediaInfo().getTrackInfos();
在播放过程中,可以通过调用播放器的selectTrack
方法切换播放的码流,取值为AUTO_SELECT_INDEX时,为多码率自适应。示例如下:
int index = trackInfo.getIndex();
//多码率切换
aliyunVodPlayer.selectTrack(index);
//多码率切换并自适应
aliyunVodPlayer.selectTrack(TrackInfo.AUTO_SELECT_INDEX);
切换的结果会在OnTrackChangedListener
监听之后会回调(在调用selectTrack
之前设置)。示例如下:
aliyunVodPlayer.setOnTrackChangedListener(new IPlayer.OnTrackChangedListener() {
@Override
public void onChangedSuccess(TrackInfo trackInfo) {
//切换成功
}
@Override
public void onChangedFail(TrackInfo trackInfo, ErrorInfo errorInfo) {
//切换失败。失败原因通过errorInfo.getMsg()获取
}
});
截图
Android端播放器SDK提供了对当前视频截图的功能,由snapshot
接口实现。截取的是原始的数据,并转为bitmap
返回。回调接口为OnSnapShotListener
。示例如下:
//设置截图回调
aliyunVodPlayer.setOnSnapShotListener(new OnSnapShotListener(){
@Override
public void onSnapShot(Bitmap bm, int with, int height){
//获取到的bitmap以及图片的宽高。
}
});
//截取当前播放的画面
aliyunVodPlayer.snapshot();
试看
Android端播放器SDK通过配合点播服务配置,可以实现试看功能,支持VidSts和VidAuth(视频点播推荐使用此方式)两种播放方式。如何配置和使用试看功能,请参见试看视频。
配置试看功能之后,通过VidPlayerConfigGen.setPreviewTime()
方法设置播放器的试看时长。以VidSts播放方式为例,示例如下:
VidSts vidSts = new VidSts;
....
VidPlayerConfigGen configGen = new VidPlayerConfigGen();
configGen.setPreviewTime(20);//20秒试看
vidSts.setPlayConfig(configGen);//设置给播放源
...
当设置试看的时长,通过Android端播放器SDK播放视频时,服务端将不会返回完整的视频内容,而是返回试看时间段的内容。
设置黑名单
Android端播放器SDK提供了硬解的黑名单机制。对于明确不能使用硬解播放的机器,可以直接使用软解,避免了无效的操作。示例如下:
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.model="Lenovo K320t";
AliPlayerFactory.addBlackDevice(BlackType.HW_Decode_H264 ,deviceInfo );
设置Referer
Android端播放器SDK支持设置Referer,配合控制台的黑白名单Referer,可以控制访问权限,由PlayerConfig
方法设置请求Referer。播放器SDK的设置示例如下:
//先获取配置
PlayerConfig config = mAliyunVodPlayer.getConfig();
//设置referer,示例:http://example.aliyundoc.com。(注意:设置referer时,需要加上前面的协议部分。)
config.mReferrer = referrer;
....//其他设置
//设置配置给播放器
mAliyunVodPlayer.setConfig(config);
设置UserAgent
Android端播放器SDK提供了PlayerConfig
用来设置请求UA。设置之后,播放器请求的过程中将会带上UA信息。示例如下:
//先获取配置
PlayerConfig config = mAliyunVodPlayer.getConfig();
//设置UA
config.mUserAgent = "需要设置的UserAgent";
....//其他设置
//设置配置给播放器
mAliyunVodPlayer.setConfig(config);
配置网络重试时间和次数
支持设置Android端播放器SDK的网络超时的时间和重试次数,由PlayerConfig
方法实现。示例如下:
//先获取配置
PlayerConfig config = mAliyunVodPlayer.getConfig();
//设置网络超时时间,单位:毫秒
config.mNetworkTimeout = 5000;
//设置超时重试次数。每次重试间隔为networkTimeout。networkRetryCount=0则表示不重试,重试策略app决定,默认值为2
config.mNetworkRetryCount=2;
....//其他设置
//设置配置给播放器
mAliyunVodPlayer.setConfig(config);
说明 如果设置了NetworkRetryCount,若此时发生网络问题,导致出现loading后,那么将会重试NetworkRetryCount次,每次的间隔时间为mNetworkTimeout。
如果重试多次之后,还是loading的状态,那么就会回调onError
事件,此时,ErrorInfo.getCode()=ErrorCode.ERROR_LOADING_TIMEOUT。
如果NetworkRetryCount设置为0,当网络重试超时的时候,播放器就会回调onInfo
事件,事件的InfoBean.getCode()=InfoCode.NetworkRetry。 此时,可以调用播放器的reload
方法进行重新加载网络,或者进行其他的处理。
配置缓存和延迟控制
Android端播放器SDK通过PlayerConfig
提供了设置缓存和延迟的控制接口。示例如下:
展开查看代码
//先获取配置
PlayerConfig config = mAliyunVodPlayer.getConfig();
//最大延迟。注意:直播有效。当延时比较大时,播放器sdk内部会追帧等,保证播放器的延时在这个范围内。
config.mMaxDelayTime = 5000;
// 最大缓冲区时长。单位ms。播放器每次最多加载这么长时间的缓冲数据。
config.mMaxBufferDuration = 50000;
//高缓冲时长。单位ms。当网络不好导致加载数据时,如果加载的缓冲时长到达这个值,结束加载状态。
config.mHighBufferDuration = 3000;
// 起播缓冲区时长。单位ms。这个时间设置越短,起播越快。也可能会导致播放之后很快就会进入加载状态。
config.mStartBufferDuration = 500;
....//其他设置
//往前缓存的最大时长。单位ms。默认为0。
config.mMaxBackwardBufferDurationMs = 0;
//设置配置给播放器
mAliyunVodPlayer.setConfig(config);
说明 三个缓冲区时长的大小关系必须为:mStartBufferDuration ≤ mHighBufferDuration ≤ mMaxBufferDuration。
当最大缓冲区时长(mMaxBufferDuration)大于5分钟时,为防止因为缓冲区过大导致的内存异常,系统将默认按5分钟生效。当mMaxBufferDuration设置超过50000 ms(即50s)时,可以启用大缓存,来降低内存占用,进一步提高播放性能,如有需要,请参见大缓存。
设置HTTP Header
通过PlayerConfig
方法,可以给播放器中的请求加上HTTP的header参数。示例如下:
展开查看代码
//先获取配置
PlayerConfig config = mAliyunVodPlayer.getConfig();
//定义header
String[] headers = new String[1];
headers[0]="Host:example.com";//比如需要设置Host到header中。
//设置header
config.setCustomHeaders(headers);
....//其他设置
//设置配置给播放器
mAliyunVodPlayer.setConfig(config);
RTS降级播放
在使用超低延时直播RTS地址播放的场景下,通过设置RTS的降级地址(如HLS地址或FLV地址),当RTS拉流失败时,会自动降级到该地址播放。示例如下:
PlayerConfig config = player.getConfig();
//可选,配置config其他项
UrlSource urlSource = new UrlSource();
urlSource.setUri(downgradeUrl);
//设置降级URL
player.enableDowngrade(urlSource, config);
设置视频背景色
Android播放器SDK支持设置播放器渲染的背景色。接口和用法说明如下:
接口示例
/**
@brief 设置视频的背景色
@param color the color
*/
/****
@brief Set video background color
@param color the color
*/
-(void) setVideoBackgroundColor:(UIColor *)color;
用法说明
//参数为8位16进制数据,8位数据两两为一组,按照顺序分别表示R(red) G(green) B(blue) A(alpha 透明度)
//例如0x00ff00ff,表示绿色
[aliPlayer setVideoBackgroundColor:0x00ff00ff]
vidAuth设置指定播放域名
通过vidAuth方式可以指定vid对应的域名等字段,支持的字段详情请参见GetPlayInfo请求参数。接口及用法说明如下:
接口示例
/**
* 设置播放参数
*
* @param playConfig 播放参数
*/
public void setPlayConfig(VidPlayerConfigGen playConfig);
用法说明
通过其中的VidPlayerConfigGen接口的addPlayerConfig添加playDomain字段。
vidAuth = new VidAuth();
VidPlayerConfigGen configGen = new VidPlayerConfigGen();
//增加playDomain字段,可以添加的字段参考
//https://help.aliyun.com/zh/vod/developer-reference/api-vod-2017-03-21-getplayinfo?spm=a2c4g.11186623.0.0.2bec2e44eqeDgx#api-detail-35
configGen.addPlayerConfig("playDomain", "com.xxx.xxx");
vidAuth.setPlayConfig(configGen);
性能
本地缓存
Android端播放器SDK提供了本地缓存的功能,能够让用户重复播放视频时,提高起播速度、提高seek速度、减少卡顿,也能达到节省流量的目的。
开启本地缓存
本地缓存功能默认关闭,如需使用,需要手动开启。通过AliPlayerGlobalSettings
中的enableLocalCache
控制。示例如下:
展开查看代码
/**
* 开启本地缓存,开启之后,会缓存到本地文件中。
*
* @param enable - 本地缓存功能开关。true:开启本地缓存,false:关闭,默认关闭。
* @param maxBufferMemoryKB - 5.4.7.1及以后版本已废弃,暂无作用
* @param localCacheDir - 本地缓存的文件目录,为绝对路径。
*/
public static void enableLocalCache(boolean enable,
int maxBufferMemoryKB,
java.lang.String localCacheDir)
/**
* 本地缓存文件清理相关配置。
*
* @param expireMin - 5.4.7.1及以后版本已废弃,暂无作用。
* @param maxCapacityMB - 最大缓存容量。单位:兆,默认值20GB,在清理时,如果缓存总容量超过此大小,则会以cacheItem为粒度,按缓存的最后时间排序,一个一个的删除最旧的缓存文件,直到小于等于最大缓存容量。
* @param freeStorageMB - 磁盘最小空余容量。单位:兆,默认值0,在清理时,同最大缓存容量,如果当前磁盘容量小于该值,也会按规则一个一个的删除缓存文件,直到freeStorage大于等于该值或者所有缓存都被清理掉。
*/
public static void setCacheFileClearConfig(long expireMin,
long maxCapacityMB,
long freeStorageMB)
/**
* 设置加载url的hash值回调。如果不设置,SDK使用md5算法。
*/
public static void setCacheUrlHashCallback(AliPlayerGlobalSettings.OnGetUrlHashCallback cb)
说明 如果视频播放URL带有鉴权参数,本地缓存和播放时鉴权参数会变化,可以将URL的鉴权参数去掉后再计算md5值。例如:带有鉴权参数的视频播放URL为http://****.mp4?aaa
,则加载时使用http://****.mp4
计算md5值。
如果服务器同时支持HTTP和HTTPS协议,但是不同的协议指向的媒体文件是同一个,则可以将请求头去掉或者统一后再计算md5值。例如:
针对5.5.4.0及以后版本的播放器SDK,如果视频播放URL带有鉴权参数且播放协议为HLS,可以通过设置PlayerConfig.mEnableStrictAuthMode
字段,进行不同鉴权模式的选择(默认值为false):
开启或关闭单个URL的本地缓存
如果想要针对单个URL开启或关闭本地缓存功能,可以在player config
中设置。
//先获取配置
PlayerConfig config = mAliyunVodPlayer.getConfig();
//是否针对播放的URL开启本地缓存,默认值为true。当AliPlayerGlobalSettings处的本地缓开启时,且同时开启此处的本地缓存,即设置为true,该URL的本地缓存才会生效;若此处设置为false,则关闭该URL的本地缓存。
config.mEnableLocalCache = false;
....//其他设置
//设置配置给播放器
mAliyunVodPlayer.setConfig(config);
大缓存
通过设置数据的最大缓冲区时长可以在播放视频时通过缓存视频数据到内存中,从而提高播放性能和观看体验。当最大缓冲区时长设置过大时,会造成缓冲区对内存的消耗。通过启用大缓存,可以将视频数据缓存到文件中,从而降低内存的占用,进一步提高播放器性能。
当mMaxBufferDuration设置超过50000 ms时,通过开启本地缓存触发大缓存功能自动启用。操作流程如下:
开启全局本地缓存。
本地缓存功能默认关闭,如需使用,需要手动开启。通过AliPlayerGlobalSettings
中的enableLocalCache
控制。代码示例请参见本地缓存中的开启本地缓存。
开启URL的本地缓存。
代码示例请参见本地缓存中的开启或关闭单个URL的本地缓存。
预加载
Android端播放器SDK提供预加载功能,是对本地缓存功能的升级,通过设置视频缓存的内存占用大小,更能提升视频的起播速度。
说明 Android端播放器SDK默认提供预加载时网络资源自动调度能力,以减少预加载的网络请求对正在播放视频的网络请求的影响。自动调度的策略是:仅当正在播放的视频缓冲到达一定阈值后,才会允许预加载进行请求。若您需要自行控制预加载的实时请求,可以通过以下方法将此策略关闭:
AliPlayerGlobalSettings.enableNetworkBalance(false);
开启本地缓存功能,详细操作请参见本地缓存。
获取AliMediaLoader实例。
AliMediaLoader实例为单例,即无论获取多少次,创建的都是同一个实例。
MediaLoader mediaLoader = MediaLoader.getInstance();
配置AliMediaLoader。
配置回调,并开始加载。
展开查看代码
/**
* 设置加载状态回调
*/
mediaLoader.setOnLoadStatusListener(new MediaLoader.OnLoadStatusListener() {
@Override
public void onError(String url, int code, String msg) {
//加载出错
}
@Override
public void onCompleted(String s) {
//加载完成
}
@Override
public void onCanceled(String s) {
//加载取消
}
});
/**
* 开始加载文件。异步加载。可以同时加载多个视频文件。
* @param url - 视频文件地址。
* @param duration - 加载的时长大小,单位:毫秒。
*/
mediaLoader.load("url","duration");
可选:删除加载文件。
可按需删除加载文件,以节省空间。Android端播放器SDK不提供删除接口,需要在App删除加载目录下的文件。
动态预加载
动态预加载策略,支持集成方既可以控制当前正在播放视频的缓存,又可以控制预加载的个数和缓存,满足业务方对播放体验与成本开销之间取得平衡的诉求。
展开查看代码
// 开启推荐配置和动态预加载
ListPlayer.setPreloadScene(IListPlayer.SceneType.SCENE_SHORT);
// 配置基准预加载时长
// 设置预加载时长为1000ms
PreloadConfig config = new PreloadConfig();
config.mPreloadDuration = 1000;
ListPlayer.updatePreloadConfig(config);
// 配置预加载的数量,支持双向
// 1为向前预加载的数量,3为向后预加载的数量
ListPlayer.setPreloadCount(1, 3);
// 配置动态预加载的递减的offset
ListPlayer.enablePreloadStrategy(IListPlayer.StrategyType.STRATEGY_DYNAMIC_PRELOAD_DURATION, true);
ListPlayer.setPreloadStrategy(IListPlayer.StrategyType.STRATEGY_DYNAMIC_PRELOAD_DURATION, "{\"algorithm\": \"sub\",\"offset\": \"200\"}");
获取下载速度
获取当前播放视频的下载速度,在onInfo回调中获取,由getExtraValue
接口实现。
展开查看代码
mAliPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
@Override
public void onInfo(InfoBean infoBean) {
if(infoBean.getCode() == InfoCode.CurrentDownloadSpeed){
//当前下载速度
long extraValue = infoBean.getExtraValue();
}
}
});