腾讯云直播初体验

转自:http://blog.csdn.net/g_ying_jie/article/details/72818519

移动直播安卓的集成其实相对简单,主要分为推流端功能和播放端功能,主要实现条件大致分为以下三点:
①RTMP SDK集成与使用
②拼接出推流地址(可由后台服务器提供)
③拼接出播放地址(可由后台服务器提供)

***本文将主要介绍SDK的集成和功能实现方案。***
一、RTMP SDK集成

① [SDK下载地址](https://www.qcloud.com/product/mlvb#wiki)

解压后可看到以下文件


将jar包复制到项目下的libs文件。在项目的main文件夹下新建jniLibs文件夹将so文件拷贝进去,同步下项目生成如下项目结构。


②配置相关的权限

  1. <uses-permission android:name=“android.permission.INTERNET” />  
  2. <uses-permission android:name=”android.permission.ACCESS_NETWORK_STATE” />  
  3. <uses-permission android:name=”android.permission.ACCESS_WIFI_STATE” />  
  4. <uses-permission android:name=”android.permission.READ_PHONE_STATE” />  
  5. <uses-permission android:name=”android.permission.CALL_PHONE”/>  
  6. <uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE”/>  
  7. <uses-permission android:name=”android.permission.READ_LOGS” />  
  8. <uses-permission android:name=”android.permission.RECORD_AUDIO” />  
  9. <uses-permission android:name=”android.permission.CAMERA” />  
  10. <uses-feature android:name=”android.hardware.Camera”/>  
  11. <uses-feature android:name=”android.hardware.camera.autofocus” />  
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<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_LOGS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.Camera"/>
<uses-feature android:name="android.hardware.camera.autofocus" />


注意:安卓6.0以后的系统需要在代码中动态获取相机、麦克风、sd卡权限,相关方法百度很多就不在过多赘述,谨在此提供一下小编的一种方案

  1. private static final int REQUEST_EXTERNAL_STORAGE = 1;  
  2. private static String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO};  
  3. private boolean checkedPermission;  
  4.   
  5. private void checkPermission() {  
  6.     if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)  
  7.             != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)  
  8.             != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)  
  9.             != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)  
  10.             != PackageManager.PERMISSION_GRANTED) {  
  11.         //进入到这里代表没有权限.  
  12.         if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CALL_PHONE)) {  
  13.             //已经禁止提示了  
  14.             Toast.makeText(MainActivity.this, TCConstants.ERROR_MSG_PERMISSION_FORBID, Toast.LENGTH_SHORT).show();  
  15.         } else {  
  16.             ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);  
  17.         }  
  18.     } else {  
  19.         checkedPermission = true;  
  20.     }  
  21. }  
  22.   
  23. @Override  
  24. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {  
  25.     switch (requestCode) {  
  26.         case REQUEST_EXTERNAL_STORAGE:  
  27.             if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {  
  28.                 //用户同意授权  
  29.                 checkedPermission = true;  
  30.             }  
  31.             break;  
  32.     }  
  33. }  
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO};
private boolean checkedPermission;

private void checkPermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
            != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
            != PackageManager.PERMISSION_GRANTED) {
        //进入到这里代表没有权限.
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CALL_PHONE)) {
            //已经禁止提示了
            Toast.makeText(MainActivity.this, TCConstants.ERROR_MSG_PERMISSION_FORBID, Toast.LENGTH_SHORT).show();
        } else {
            ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
        }
    } else {
        checkedPermission = true;
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case REQUEST_EXTERNAL_STORAGE:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //用户同意授权
                checkedPermission = true;
            }
            break;
    }
}

③验证SDK配置情况

  1. //在onCreate中调用getSDKVersion接口获取版本号:  
  2.   
  3. int[] sdkver = TXLivePusher.getSDKVersion();  
  4. if (sdkver != null && sdkver.length >= 3) {  
  5.     Log.d(”rtmpsdk”,“rtmp sdk version is:” + sdkver[0] + “.” + sdkver[1] + “.” + sdkver[2]);  
  6. }  
//在onCreate中调用getSDKVersion接口获取版本号:

int[] sdkver = TXLivePusher.getSDKVersion();
if (sdkver != null && sdkver.length >= 3) {
    Log.d("rtmpsdk","rtmp sdk version is:" + sdkver[0] + "." + sdkver[1] + "." + sdkver[2]);
}

运行之后将在logcat中看到如下log信息:07-13 20:25:05.099 26119-26119/? D/rtmpsdk: rtmp sdk version is:1.5.188


二、主播端推流功能实现

①视频播放器,用于给主播展示推流的视频

  1. <span style=“font-size:18px;”><com.tencent.rtmp.ui.TXCloudVideoView  
  2.     android:id=”@+id/video_view”  
  3.     android:layout_width=”match_parent”  
  4.     android:layout_height=”match_parent” /></span>  
<com.tencent.rtmp.ui.TXCloudVideoView
    android:id="@+id/video_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

②开启推流

  1. //推流相关  
  2. private TXCloudVideoView mTXCloudVideoView;  
  3. private TXLivePusher mTXLivePusher;  
  4. private TXLivePushConfig mTXPushConfig = new TXLivePushConfig();  
  5.   
  6. //开启推流  
  7. protected void startPublish() {  
  8.     if (mTXLivePusher == null) {  
  9.         mTXLivePusher = new TXLivePusher(this);  
  10.         mTXLivePusher.setConfig(mTXPushConfig);  
  11.     }  
  12.     //可由服务器拼接此推流地址  
  13.     mTXLivePusher.startPusher(TCConstants.PUBLISH_URL);  
  14.     mTXLivePusher.startCameraPreview(mTXCloudVideoView);  
  15. }  
//推流相关
private TXCloudVideoView mTXCloudVideoView;
private TXLivePusher mTXLivePusher;
private TXLivePushConfig mTXPushConfig = new TXLivePushConfig();

//开启推流
protected void startPublish() {
    if (mTXLivePusher == null) {
        mTXLivePusher = new TXLivePusher(this);
        mTXLivePusher.setConfig(mTXPushConfig);
    }
    //可由服务器拼接此推流地址
    mTXLivePusher.startPusher(TCConstants.PUBLISH_URL);
    mTXLivePusher.startCameraPreview(mTXCloudVideoView);
}

③停止推流,注意结束推流很简单,不过要做好清理工作,因为用于推流的 TXLivePusher 和用于显示影像的 TXCloudVideoView 都是不能多实例并行运转的,所以清理工作不当会导致下次直播遭受不良的影响。

  1. //停止推流  
  2. protected void stopPublish() {  
  3.     if (mTXLivePusher != null) {  
  4.         mTXLivePusher.stopCameraPreview(true);//停止摄像头预览  
  5.         mTXLivePusher.stopPusher();//停止推流  
  6.         mTXLivePusher.setPushListener(null);//解绑 listener  
  7.     }  
  8.     this.finish();  
  9. }  
//停止推流
protected void stopPublish() {
    if (mTXLivePusher != null) {
        mTXLivePusher.stopCameraPreview(true);//停止摄像头预览
        mTXLivePusher.stopPusher();//停止推流
        mTXLivePusher.setPushListener(null);//解绑 listener
    }
    this.finish();
}


三、客户端视频播放

①准备视频播放器

  1. <com.tencent.rtmp.ui.TXCloudVideoView  
  2.     android:id=”@+id/play_view”  
  3.     android:layout_width=”match_parent”  
  4.     android:layout_height=”match_parent” />  
<com.tencent.rtmp.ui.TXCloudVideoView
    android:id="@+id/play_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

②开始播放

  1. private TXCloudVideoView playerView;  
  2. private TXLivePlayer livePlayer;  
  3. protected void starPlay() {  
  4.     //创建player对象  
  5.     livePlayer = new TXLivePlayer(this);  
  6.     //关联player对象与界面view  
  7.     livePlayer.setPlayerView(playerView);  
  8.     livePlayer.setConfig(new TXLivePlayConfig());  
  9.     livePlayer.setRenderMode(TXLiveConstants.RENDER_MODE_FULL_FILL_SCREEN);  
  10.     //推荐FLV播放格式  
  11.     livePlayer.startPlay(TCConstants.PLAY_URL, TXLivePlayer.PLAY_TYPE_LIVE_FLV);  
  12. }  
private TXCloudVideoView playerView;
private TXLivePlayer livePlayer;
protected void starPlay() {
    //创建player对象
    livePlayer = new TXLivePlayer(this);
    //关联player对象与界面view
    livePlayer.setPlayerView(playerView);
    livePlayer.setConfig(new TXLivePlayConfig());
    livePlayer.setRenderMode(TXLiveConstants.RENDER_MODE_FULL_FILL_SCREEN);
    //推荐FLV播放格式
    livePlayer.startPlay(TCConstants.PLAY_URL, TXLivePlayer.PLAY_TYPE_LIVE_FLV);
}

③停止播放

  1. protected void stopPlay() {  
  2.     if (playerView != null) {  
  3.         livePlayer.setPlayListener(null);  
  4.         livePlayer.stopPlay(true);  
  5.         playerView.onDestroy();  
  6.     }  
  7.     this.finish();  
  8. }  
protected void stopPlay() {
    if (playerView != null) {
        livePlayer.setPlayListener(null);
        livePlayer.stopPlay(true);
        playerView.onDestroy();
    }
    this.finish();
}


到此直播的基本功能已经实现了,后续会介绍一些精细的用法和注意的地方,敬请期待。有什么问题可以在评论区留言,相互交流,我会不定期回复解答

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值