Android接入腾讯直播(一)

  • 小直播

小直播 App 是一套开源的完整的在线直播解决方案,它基于云直播服务、即时通信(IM)和对象存储服务(COS)构建,并使用云服务器(CVM)提供简单的后台服务,可以实现登录、注册、开播、房间列表、连麦互动、文字互动和弹幕消息等功能。

我这边来个最简单的教程:

第一步 下载SDK

Checkout 项目:https://gitee.com/cloudtencent/MLVBSDK
下载下来以后然选择:Android/XiaoZhiBo导入Android Studio即可。

第二步 创建测试license

进入 https://console.cloud.tencent.com/live/license,使用微信或者QQ扫码登录后创建一个测试license即可

第三步 打开小直播项目中TCGlobalConfig.java

填写LICENCE_URL,LICENCE_KEY,APP_SVR_URL 三个值即可。

LICENCE_URL和LICENCE_KEY在第二步创建后会自动生成,填写即可
APP_SVR_URL 统一填写:https://xzb.qcloud.com

第四步 运行项目即可开播

当然仅限快速测试使用,上线需要正式的license和APP_SVR_URL

上线的时候也只需要更新ALICENCE_URL,LICENCE_KEY,APP_SVR_URL即可

  • 腾讯云工具包 App

如果您是开发人员,可以直接下载我们的腾讯云工具包 App,工具包 中的每一个菜单项均对应 SDK 中的一项独立功能,您可以根据当前项目需要进行针对性的调试。

第一步 下载SDK

Checkout 项目:https://github.com/tencentyun/LiteAVProfessional_Android/tree/master/Demo
下载下来以后然选择:Demo导入即可。

第二步 创建测试license

进入 https://console.cloud.tencent.com/live/license,使用微信或者QQ扫码登录后创建一个测试license即可

第三步 修改配置

打开项目中DemoApplication.java填写licenceUrl和licenseKey
打开项目中GenerateTestUserSig.java填写BIZID,APPID,SDKAPPID,SECRETKEY

第四步 运行项目即可开播

setVideoQuality方法报错替换如下即可:

 V2TXLiveDef.V2TXLiveVideoEncoderParam param = new V2TXLiveDef.V2TXLiveVideoEncoderParam(Resolution);
                    param.videoResolutionMode = ResolutionMode;
                    mLivePusher.setVideoQuality(param);

demo都跑通了,下面手写一个精简的推流和拉流功能吧。

  • 精简推流拉流

主播推流,观众拉流
经过参考demo发现推流有摄像头推流和录屏推流,拉流就一种
推流只有一个推流地址,拉流有多种拉流地址(RTMP,FLV,HLS,低延时)

第一步 初始化

package com.z.zplay;

import android.app.Application;

import com.tencent.rtmp.TXLiveBase;

public class IApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        String licenceURL = "https://xxxxxxxxxxxxxxxxxxxxx.license"; 
        String licenceKey = "xxxxxxxxxxxxxxxxxxxxxx"; 
        TXLiveBase.getInstance().setLicence(this, licenceURL, licenceKey);
    }

}

    //other
    implementation 'com.squareup.okhttp3:okhttp:3.6.0'
    implementation 'com.squareup.retrofit2:retrofit:2.8.2'
    implementation 'com.king.zxing:zxing-lite:1.1.2'
    implementation 'org.greenrobot:eventbus:3.1.1'

    //腾讯直播
    implementation 'com.tencent.liteav:LiteAVSDK_Professional:latest.release'
    implementation 'com.tencent.imsdk:imsdk:4.9.1'
    <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.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <uses-feature android:name="android.hardware.Camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

第二步 获取拉流推流地址

不管你是要推流还是拉流都要先获取地址

	//腾讯提供的测试地址,正式上线需要换成自己的
   public static final String URL_FETCH_PUSH_URL = "https://lvb.qcloud.com/weapp/utils/get_test_pushurl";
   
    private fun fetchPusherURL() {
        val okHttpClient = OkHttpClient().newBuilder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS)
            .build()
        val request = Request.Builder()
            .url(Constants.URL_FETCH_PUSH_URL)
            .addHeader("Content-Type", "application/json; charset=utf-8")
            .build()
        okHttpClient.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
            }

            @Throws(IOException::class)
            override fun onResponse(call: Call, response: Response) {
                if (response.isSuccessful) {
                    try {
                        val jsonRsp = JSONObject(response.body()!!.string())
                        val pusherURLDefault = jsonRsp.optString(Constants.URL_PUSH)
                        val rtmpPlayURL = jsonRsp.optString(Constants.URL_PLAY_RTMP)
                        val flvPlayURL = jsonRsp.optString(Constants.URL_PLAY_FLV)
                        val hlsPlayURL = jsonRsp.optString(Constants.URL_PLAY_HLS)
                        val realtimePlayURL = jsonRsp.optString(Constants.URL_PLAY_ACC)
                        startLivePusher(
                            pusherURLDefault,
                            rtmpPlayURL,
                            flvPlayURL,
                            hlsPlayURL,
                            realtimePlayURL
                        )
                    } catch (e: JSONException) {
                        e.printStackTrace()
                    }

                }
            }
        })
    }


    private fun startLivePusher(
        pushURL: String,
        rtmpPlayURL: String,
        flvPlayURL: String,
        hlsPlayURL: String,
        realtimePlayURL: String
    ) {
        var intent = Intent()
        if (clickType == 1) {
            intent.setClass(this, PushActivity::class.java)
        } else if (clickType == 2) {
            intent.setClass(this, ScreenPushActivity::class.java)
        }
        intent.putExtra(Constants.INTENT_URL_PUSH, pushURL)
        intent.putExtra(Constants.INTENT_URL_PLAY_RTMP, rtmpPlayURL)
        intent.putExtra(Constants.INTENT_URL_PLAY_FLV, flvPlayURL)
        intent.putExtra(Constants.INTENT_URL_PLAY_HLS, hlsPlayURL)
        intent.putExtra(Constants.INTENT_URL_PLAY_ACC, realtimePlayURL)
        startActivity(intent)

    }

其中pushURL为推流地址,另外4个为拉流地址。

第三步 推流

摄像头推流

package com.z.zplay;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import com.king.zxing.util.CodeUtils;
import com.tencent.live2.V2TXLiveDef;
import com.tencent.live2.V2TXLivePusher;
import com.tencent.live2.impl.V2TXLivePusherImpl;
import com.tencent.rtmp.TXLiveConstants;
import com.tencent.rtmp.TXLog;
import com.tencent.rtmp.ui.TXCloudVideoView;

import static com.tencent.live2.V2TXLiveCode.V2TXLIVE_ERROR_INVALID_LICENSE;
import static com.tencent.live2.V2TXLiveDef.V2TXLiveVideoResolutionMode.V2TXLiveVideoResolutionModeLandscape;
import static com.tencent.live2.V2TXLiveDef.V2TXLiveVideoResolutionMode.V2TXLiveVideoResolutionModePortrait;


//先推流,后创建IM

public class PushActivity extends AppCompatActivity {

    private V2TXLivePusher mLivePusher;
    private TXCloudVideoView mPusherView;
    private static final String TAG = "PushActivity";



    private String mPusherURL       = "";   // 推流地址
    private String mRTMPPlayURL     = "";   // RTMP 拉流地址
    private String mFlvPlayURL      = "";   // flv 拉流地址
    private String mHlsPlayURL      = "";   // hls 拉流地址
    private String mRealtimePlayURL = "";   // 低延时拉流地址

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_push);
        initData();
        initPusher();
        startPush();
    }


    private void initData() {
        Intent intent = getIntent();
        mPusherURL = intent.getStringExtra(Constants.INTENT_URL_PUSH);
        mRTMPPlayURL = intent.getStringExtra(Constants.INTENT_URL_PLAY_RTMP);
        mFlvPlayURL = intent.getStringExtra(Constants.INTENT_URL_PLAY_FLV);
        mHlsPlayURL = intent.getStringExtra(Constants.INTENT_URL_PLAY_HLS);
        mRealtimePlayURL = intent.getStringExtra(Constants.INTENT_URL_PLAY_ACC);

        Bitmap qrCode = CodeUtils.createQRCode(mRTMPPlayURL, 200);
        ImageView ivCode = findViewById(R.id.iv_code);
        ivCode.setImageBitmap(qrCode);
    }


    private void initPusher() {
        mPusherView = findViewById(R.id.pusher_tx_cloud_view);
        mLivePusher = new V2TXLivePusherImpl(this, V2TXLiveDef.V2TXLiveMode.TXLiveMode_RTMP);
    }

    private void startPush() {
            mLivePusher.setRenderView(mPusherView);
            mLivePusher.startCamera(true);
            mLivePusher.startPush(mPusherURL);

    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        mLivePusher.stopCamera();
        mLivePusher.stopPush();
    }
}

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    tools:context=".PushActivity">

    <com.tencent.rtmp.ui.TXCloudVideoView
        android:id="@+id/pusher_tx_cloud_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />


    <ImageView
        android:id="@+id/iv_code"
        android:layout_width="100dp"
        android:layout_height="100dp" />

</FrameLayout>

录屏推流

package com.z.zplay;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import com.king.zxing.util.CodeUtils;
import com.tencent.live2.V2TXLiveDef;
import com.tencent.live2.V2TXLivePusher;
import com.tencent.live2.impl.V2TXLivePusherImpl;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import static com.tencent.live2.V2TXLiveCode.V2TXLIVE_OK;

public class ScreenPushActivity extends AppCompatActivity {
    private Button btn_start_push;
    private static V2TXLivePusher sLivePusher;

    private String mPusherURL = "";   // 推流地址
    private String mRTMPPlayURL = "";   // RTMP 拉流地址
    private String mFlvPlayURL = "";   // flv 拉流地址
    private String mHlsPlayURL = "";   // hls 拉流地址
    private String mRealtimePlayURL = "";   // 低延时拉流地址

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_screen_push);
        btn_start_push = findViewById(R.id.btn_start_push);
        initData();

        btn_start_push.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startPush(mPusherURL);
            }
        });
    }


    private void initData() {
        Intent intent = getIntent();
        mPusherURL = intent.getStringExtra(Constants.INTENT_URL_PUSH);
        mRTMPPlayURL = intent.getStringExtra(Constants.INTENT_URL_PLAY_RTMP);
        mFlvPlayURL = intent.getStringExtra(Constants.INTENT_URL_PLAY_FLV);
        mHlsPlayURL = intent.getStringExtra(Constants.INTENT_URL_PLAY_HLS);
        mRealtimePlayURL = intent.getStringExtra(Constants.INTENT_URL_PLAY_ACC);

        Bitmap qrCode = CodeUtils.createQRCode(mRTMPPlayURL, 200);
        ImageView ivCode = findViewById(R.id.iv_code);
        ivCode.setImageBitmap(qrCode);
    }


    private void startPush(String pushURL) {
        sLivePusher = new V2TXLivePusherImpl(this, V2TXLiveDef.V2TXLiveMode.TXLiveMode_RTMP);
        sLivePusher.startMicrophone();
        sLivePusher.startScreenCapture();
        int result = sLivePusher.startPush(pushURL);
        if (result == V2TXLIVE_OK) {
            Toast.makeText(this, "push成功", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "push失败", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        sLivePusher.stopScreenCapture();
        sLivePusher.setObserver(null);
        sLivePusher.stopPush();
    }
}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    tools:context=".ScreenPushActivity">


    <ImageView
        android:id="@+id/iv_code"
        android:layout_width="100dp"
        android:layout_height="100dp" />


    <Button
        android:id="@+id/btn_start_push"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="开始录屏推流" />

</LinearLayout>

录屏推流需要多增加一个activity配置

     <activity
            android:name="com.tencent.rtmp.video.TXScreenCapture$TXScreenCaptureAssistantActivity"
            android:theme="@android:style/Theme.Translucent" />

第四步 拉流

package com.z.zplay;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;

import com.tencent.live2.V2TXLiveDef;
import com.tencent.live2.V2TXLivePlayer;
import com.tencent.live2.impl.V2TXLivePlayerImpl;
import com.tencent.rtmp.ui.TXCloudVideoView;

public class GetPushActivity extends AppCompatActivity {
	//这个URL就是推流生成的二维码的数据
    private String mPlayURL = "";

    private V2TXLivePlayer mLivePlayer;               //直播拉流的视频播放器
    private TXCloudVideoView mVideoView;


    private V2TXLiveDef.V2TXLiveFillMode mRenderMode = V2TXLiveDef.V2TXLiveFillMode.V2TXLiveFillModeFit;    //Player 当前渲染模式
    private V2TXLiveDef.V2TXLiveRotation mRenderRotation = V2TXLiveDef.V2TXLiveRotation.V2TXLiveRotation0;         //Player 当前渲染角度

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_get_push);
        mPlayURL = getIntent().getStringExtra(Constants.INTENT_URL);
        mVideoView = (TXCloudVideoView) findViewById(R.id.liveplayer_video_view);
        mLivePlayer = new V2TXLivePlayerImpl(this);
        startPlay();
    }


    private void startPlay() {
        String playURL = mPlayURL;
        mLivePlayer.setRenderView(mVideoView);
        mLivePlayer.setRenderRotation(mRenderRotation);
        mLivePlayer.setRenderFillMode(mRenderMode);
        mLivePlayer.startPlay(playURL);

    }
}

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".GetPushActivity">


    <com.tencent.rtmp.ui.TXCloudVideoView
        android:id="@+id/liveplayer_video_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

第五步 运行即可,可配合腾讯云工具包 App一块测试

以上都是最精简的可跑通的核心代码,其他配置的比如声道,美颜等按需增加。
推流和拉流不包含在直播间聊天的功能,如果需要聊天,那么需要增加腾讯云IM服务SDK

其他配置请参考:官方文档
腾讯直播Demo

  • 即时通信IM

第一步 下载SDK

Checkout 项目:https://github.com/tencentyun/TIMSDK/tree/master/Android/Demo
下载下来以后然选择:Demo导入Android Studio即可。

第二步 创建测试应用

登录 即时通信 IM 控制台创建一个应用

第三步 配置

GenerateTestUserSig.java填写SDKAPPID,SECRETKEY即可

第四步 运行项目即可登录聊天和开播

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哆啦A梦z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值