最近项目中新增了视频播放的功能,经查找了解及朋友推荐我选择了集成腾讯云的视频播放实现此功能,相对来说腾讯播放支持的功能比较全面,支持推流、直播、点播、短视频、连麦功能,这里总结一下实现过程及遇到的问题解决。
首先进入腾讯云官网的文档中心,向下滑找到视频服务模块 ,点击点播进入点播功能的文档首页,在左侧导航栏中找到播放器SDK手册展开选择 超级播放器Android ,现在就可以查看点播的功能介绍,SDK+Demo的下载地址及相关主要的方法使用介绍,eg:创建播放器、视频信息获取、切换视频、移除播放器 等,看到这里就应该能明白这个Demo中实现的功能了,进入SDK下载页面选择要下载的SDK。
下载好SDK+Demo接下来就开始集成。这里以 全功能专业版为例:
一:配置工程,有aar和jar两种方式,以aar集成为例
1、解压下载的SDK,看到如下文件:
2、在LiteAVSDK_UGC_Android_4.4.3774\LiteAVSDK_UGC_Android\Demo\app\libs文件夹下找到LiteAVSDK_UGC.aar文件,copy到自己的项目libs文件夹中。
3、在工程app目录下的
build.gradle
文件中,添加引入aar
包的代码:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
// 导入腾讯云 SDK aar
compile(name: 'LiteAVSDK_UGC', ext: 'aar')
……
}
4、在工程目录下的build.gradle
文件中,添加flatDirr
,指定本地仓库:
allprojects {
repositories {
flatDir {
dirs 'libs'
}
jcenter()
}
}
5、在工程目录下的build.gradle
的defaultConfig里面,指定ndk
兼容架构:
defaultConfig {
……
ndk {
abiFilters "armeabi", "armeabi-v7a"
}
}
注意:配置完第五条,记得编译工程Rebuild Project
6、添加App权限:
在AndroidManifest.xml中添加音视频所需权限,如下。
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"/>
<uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
7、配置完成后验证下工程设备是否正确:
在你的MainActivity
的onCreate
中调用TXLiveBase.getSDKVersion
String sdkver = TXLiveBase.getSDKVersionStr();
Log.d("liteavsdk", "liteav sdk version is : " + sdkver);
若前面几个步骤中的配置都正确,工程将顺利编译通过,运行后会在LogCat看到相关的log信息。
二:写视频播放的代码
在确定工程都已配置好以后,就可以进行视频播放功能编写了。视频云中的超级播放器SuperVideoPlayer
是基于TXVodPlayer
实现的集视频信息拉取、横竖屏切换、清晰度选择、弹幕等功能于一体的解决方案,且完全开源。我们将demo工程中的SuperVideoPlayer
文件及其中引用到的相关类和资源都copy到自己的工程中,导入相关的包。可以参考点播的完整文档在SuperVideoPlayer
文件中修改相关的属性。
-
播放方式(
url
方式和fileId
方式):
1、url
方式:
TXVodPlayer 内部会自动识别播放协议,您只需要将您的播放 URL 传给 startPlay 函数即可。
String url = "http://www.jmzsjy.com/UploadFile/微课/地方风味小吃——宫廷香酥牛肉饼.mp4";
mVodPlayer.startPlay(url);
2、field
方式:
TXPlayerAuthBuilder authBuilder = new TXPlayerAuthBuilder();
authBuilder.setAppId(1252463788);
authBuilder.setFileId("4564972819220421305");
mVodPlayer.startPlay(authBuilder);
-
画面调整(和);
1、setRenderMode
:铺满or适应
RENDER_MODE_FILL_SCREEN
:将图像等比例铺满整个屏幕,多余部分裁剪掉,此模式下画面不会留黑边,但可能因为部分区域被裁剪而显示不全。
RENDER_MODE_ADJUST_RESOLUTION
:将图像等比例缩放,适配最长边,缩放后的宽和高都不会超过显示区域,居中显示,画面可能会留有黑边。2、
setRenderRotation
:画面旋转
RENDER_ROTATION_PORTRAIT
:正常播放(Home键在画面正下方)
RENDER_ROTATION_LANDSCAPE
:画面顺时针旋转270度(Home键在画面正左方) 变速播放
通过接口setRate设置点播播放速率来完成,支持快速与慢速播放,如0.5X、1.0X、1.2X、2X等。
//如下代码用于展示点播倍速播放
//设置1.2倍速播放
mVodPlayer.setRate(1.2);
// ...
//开始播放
mVodPlayer.startPlay(playUrl,_playType);
- 本地缓存
//指定一个本地mp4缓存目录
TXVodPlayConfig mConfig = new TXVodPlayConfig();
mConfig.setCacheFolderPath(
Environment.getExternalStorageDirectory().getPath(); +"/txcache");
//指定本地最多缓存多少文件,避免缓存太多数据
mConfig.setMaxCacheItems(10);
mVodPlayer.setConfig(mConfig);
// ...
//开始播放
mVodPlayer.startPlay(playUrl);
以下是视频播放的布局文件及主要代码及,仅供参考。
<?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"
android:orientation="vertical"
>
<FrameLayout
android:id="@+id/layout_player"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_black"
android:minHeight="200dp"
>
<com.doctor.videoplay.view.SuperVideoPlayer
android:id="@+id/video_player_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"></com.doctor.videoplay.view.SuperVideoPlayer>
<ImageView
android:id="@+id/play_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/biz_video_list_play_icon_big" />
</FrameLayout>
</LinearLayout>
视频播放activity的代码
import android.view.WindowManager;
import android.widget.ImageView;
import com.doctor.videoplay.model.Video;
import com.doctor.videoplay.model.VideoUrl;
import com.doctor.videoplay.view.MediaController;
import com.doctor.videoplay.view.SuperVideoPlayer;
import com.doctor.videoplay.view.VodRspData;
import com.tencent.rtmp.TXLivePlayer;
public class PlayVideoActivity extends Activity implements View.OnClickListener {
private SuperVideoPlayer mSuperVideoPlayer;
private ImageView mPlayBtnView;
private String videoUrl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_video);
hideBottomUIMenu();//隐藏虚拟按键,否则全屏时虚拟按键会影响视频播放进度条的调整。
checkPermission();//检查权限
getWindow().addFlags(WindowManager.LayoutParams.
FLAG_KEEP_SCREEN_ON);
initView();
}
/**
* 初始化控件
*/
private void initView() {
videoUrl = "http://www.jmzsjy.com/UploadFile/微课/地方风味小吃——宫廷香酥牛肉饼.mp4";
mSuperVideoPlayer = (SuperVideoPlayer) findViewById(R.id.video_player_item);
//创建主播放器
mSuperVideoPlayer.setVideoPlayCallback(mVideoPlayCallback);
//播放按钮
mPlayBtnView = (ImageView) findViewById(R.id.play_btn);
mPlayBtnView.setOnClickListener(this);
playVideo();
}
/**
* 检查权限
*/
private void checkPermission() {
if (Build.VERSION.SDK_INT >= 23) {
List<String> permissions = new ArrayList<>();
if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)) {
permissions.add(Manifest.permission.CAMERA);
}
if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (permissions.size() != 0) {
ActivityCompat.requestPermissions(this, permissions.toArray(new String[0]), 100);
}
}
}
/**
* 播放视频
*/
private void playVideo() {
mPlayBtnView.setVisibility(View.GONE);
mSuperVideoPlayer.setVisibility(View.VISIBLE);
mSuperVideoPlayer.setAutoHideController(false);
Video video = new Video();
VideoUrl videoUrl1 = new VideoUrl();
videoUrl1.setFormatName("1080P");//视频格式名称,例如高清,标清,720P等等
videoUrl1.setFormatUrl(videoUrl);//视频Url
videoUrl1.setIsOnlineVideo(false);//设置是否在线播放
ArrayList<VideoUrl> arrayList1 = new ArrayList<>();
arrayList1.add(videoUrl1);
video.setVideoName("测试视频一");
video.setVideoUrl(arrayList1);
ArrayList<Video> videoArrayList = new ArrayList<>();
videoArrayList.add(video);
mSuperVideoPlayer.loadMultipleVideo(videoArrayList, 0, 0, 0);//按照指定的格式,指定的进度播放视频列表中指定的视频。
}
//视频播放中的回调处理
private SuperVideoPlayer.VideoPlayCallbackImpl mVideoPlayCallback = new SuperVideoPlayer.VideoPlayCallbackImpl() {
@Override
public void onCloseVideo() {
mSuperVideoPlayer.onDestroy();
mPlayBtnView.setVisibility(View.VISIBLE);
mSuperVideoPlayer.setVisibility(View.GONE);
resetPageToPortrait();
}
@Override
public void onSwitchPageType() {
if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
mSuperVideoPlayer.setPageType(MediaController.PageType.SHRINK);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
mSuperVideoPlayer.setPageType(MediaController.PageType.EXPAND);
}
}
@Override
public void onPlayFinish() {
mPlayBtnView.setVisibility(View.VISIBLE);
}
@Override
public void onBack() {
if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
mSuperVideoPlayer.setPageType(MediaController.PageType.SHRINK);
} else {
finish();
}
}
@Override
public void onLoadVideoInfo(VodRspData data) {
}
};
/***
* 恢复屏幕至竖屏
*/
private void resetPageToPortrait() {
if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
mSuperVideoPlayer.setPageType(MediaController.PageType.SHRINK);
}
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.play_btn) {
playVideo();
}
}
/**
* 隐藏虚拟按键,并且全屏
*/
protected void hideBottomUIMenu() {
//隐藏虚拟按键,并且全屏
if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
View v = this.getWindow().getDecorView();
v.setSystemUiVisibility(View.GONE);
} else if (Build.VERSION.SDK_INT >= 19) {
//for new api versions.
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE;
decorView.setSystemUiVisibility(uiOptions);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
}
@Override
protected void onDestroy() {
if (mSuperVideoPlayer != null) {
mSuperVideoPlayer.onDestroy();
}
super.onDestroy();
}
}
三、注意事项:
1、官方文档标明:SDK支持在Android4.0.3 (API 15)及以上系统上运行,但只有Android4.3(API18)以上的系统才能开启硬件编码。
2、SDK的开发环境为:
Android NDK: android-ndk-r12b
Android SDK Tools: android-sdk_25.0.2
minSdkVersion: 15
targetSdkVersion: 21
app的开发环境不需要跟SDK的一致,保持兼容就好。
3、视频云 SDK 中的播放器只支持 FLV 、RTMP 和 HLS(m3u8)三种格式的直播地址,以及 MP4、 HLS(m3u8)和 FLV 三种格式的点播地址。
四、遇到的问题及解决方法:
1、如图:
解决方法:
因为ndk中多了,"arm64-v8a"
,删除这段代码并Rebuild Project,再运行就ok啦。官方的文档中说明了完整版的连麦功能所使用的声学组件暂时不支持X64架构的手机。
ndk {
abiFilters "armeabi", "armeabi-v7a","arm64-v8a"
}