Android接入腾讯直播(一)

<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" />



### []( )录屏推流



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="开始录屏推流" />



录屏推流需要多增加一个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);



}

}



#### **如何做好面试突击,规划学习方向?**

面试题集可以帮助你查漏补缺,有方向有针对性的学习,为之后进大厂做准备。但是如果你仅仅是看一遍,而不去学习和深究。那么这份面试题对你的帮助会很有限。最终还是要靠资深技术水平说话。

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。建议先制定学习计划,根据学习计划把知识点关联起来,形成一个系统化的知识体系。

学习方向很容易规划,但是如果只通过碎片化的学习,对自己的提升是很慢的。

同时我还搜集整理2020年字节跳动,以及腾讯,阿里,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含**知识脉络 + 分支细节**。

![image](https://img-blog.csdnimg.cn/img_convert/ba35badc6273e8be395ae8220361996d.webp?x-oss-process=image/format,png) 

在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多。

![image](https://img-blog.csdnimg.cn/img_convert/44dcab598dce576d706b44b894b6f1a0.webp?x-oss-process=image/format,png) 

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。


参考docs.qq.com/doc/DSkNLaERkbnFoS0ZF
mLivePlayer.setRenderFillMode(mRenderMode);

        mLivePlayer.startPlay(playURL);



    }

}





如何做好面试突击,规划学习方向?

面试题集可以帮助你查漏补缺,有方向有针对性的学习,为之后进大厂做准备。但是如果你仅仅是看一遍,而不去学习和深究。那么这份面试题对你的帮助会很有限。最终还是要靠资深技术水平说话。

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。建议先制定学习计划,根据学习计划把知识点关联起来,形成一个系统化的知识体系。

学习方向很容易规划,但是如果只通过碎片化的学习,对自己的提升是很慢的。

同时我还搜集整理2020年字节跳动,以及腾讯,阿里,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节

[外链图片转存中…(img-GhLfQVOQ-1724153775593)]

在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多。

[外链图片转存中…(img-c7T81U1b-1724153775593)]

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

参考docs.qq.com/doc/DSkNLaERkbnFoS0ZF

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值