筆記:騰訊云直播SDK測(cè)試demo

看著騰訊直播的官方指導(dǎo)接入SDK乡小,寫(xiě)了一個(gè)demo翅溺,有點(diǎn)簡(jiǎn)陋并且沒(méi)全部demo應(yīng)用,有空再更新吧诀黍,先做個(gè)筆記Mark先
demo地址

import android.content.DialogInterface;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.util.TypedValue;
import android.view.Surface;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.tencent.rtmp.ITXLivePushListener;
import com.tencent.rtmp.TXLiveConstants;
import com.tencent.rtmp.TXLivePushConfig;
import com.tencent.rtmp.TXLivePusher;
import com.tencent.rtmp.ui.TXCloudVideoView;
import com.tencent.ugc.TXRecordCommon;

import static com.tencent.rtmp.TXLiveConstants.PAUSE_FLAG_PAUSE_AUDIO;
import static com.tencent.rtmp.TXLiveConstants.PAUSE_FLAG_PAUSE_VIDEO;

public class StartLiveActivity extends AppCompatActivity{


    private TXLivePushConfig mLivePushConfig;
    private TXCloudVideoView mCaptureView;
    private TXLivePusher mLivePusher;

    //設(shè)置清晰度
    private boolean mAutoBitrate;//畫(huà)質(zhì)優(yōu)先
    private boolean mAutoResolution;//分辨率優(yōu)先
    private int mVideoQuality = TXLiveConstants.VIDEO_QUALITY_HIGH_DEFINITION;//直播視頻質(zhì)量

    //美顏
    private int mBeautyStyle;//磨皮風(fēng)格:  0:光滑  1:自然  2:朦朧
    private int mBeautyLevel;//磨皮等級(jí): 取值為 0-9.取值為 0 時(shí)代表關(guān)閉美顏效果.默認(rèn)值: 0,即關(guān)閉美顏效果.;
    private int mWhiteningLevel;//美白等級(jí): 取值為 0-9.取值為 0 時(shí)代表關(guān)閉美白效果.默認(rèn)值: 0,即關(guān)閉美白效果.
    private int mRuddyLevel;//紅潤(rùn)等級(jí): 取值為 0-9.取值為 0 時(shí)代表關(guān)閉美白效果.默認(rèn)值: 0,即關(guān)閉美白效果.

    //濾鏡
    private int filterIndex;//濾鏡圖片
    private int filterDegree;//濾鏡程度
    private float expouseCompensation;//曝光值

    //攝像頭
    private boolean mFlashTurnOn=true;//是否開(kāi)啟
    private boolean mTouchFocus=false;//是否手動(dòng)(true)自動(dòng)對(duì)焦(false)袋坑,默認(rèn)手動(dòng)

    //設(shè)置水印
    private boolean isLogo=true;//true設(shè)置,false不設(shè)置
    private boolean HWVideoCode =true;//是否開(kāi)啟軟(false眯勾,默認(rèn))硬件編碼(true)

    //本地錄制
    private TextView recordTv;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_live);
        recordTv=findViewById(R.id.recordTv);

        mLivePusher = new TXLivePusher(this);
        mLivePushConfig = new TXLivePushConfig();

        mLivePushConfig.setTouchFocus(mTouchFocus);//是否自動(dòng)對(duì)焦

        mLivePushConfig.setFrontCamera(true);//是否前置攝像頭

        initLogo();//設(shè)置水印

        initHardWareCode();//軟硬件編碼

        setPasueBackImg();//后臺(tái)推流枣宫,設(shè)置主播暫停背景圖

        //horizontalPushCustom();//調(diào)整觀眾端表現(xiàn)
        //horizontalPushLiver();//調(diào)整主播端表現(xiàn)

        initLiveType();//開(kāi)播類型
    }

    @Override
    protected void onResume() {
        super.onResume();

        //10.4 切前臺(tái)處理
        //mCaptureView.onResume();     // mCaptureView 是攝像頭的圖像渲染view
        //mLivePusher.resumePusher();  // 通知 SDK 重回前臺(tái)推流
    }

    @Override
    protected void onStop() {
        super.onStop();

        //10.3 切后臺(tái)處理
        //mCaptureView.onPause();  // mCaptureView 是攝像頭的圖像渲染view
        //mLivePusher.pausePusher(); // 通知 SDK 進(jìn)入“后臺(tái)推流模式”了

        //10.4 后臺(tái)推攝像頭采集數(shù)據(jù)
        //如果希望主播在切后臺(tái)或者跳轉(zhuǎn)其他界面還能看到攝像頭采集的畫(huà)面, 按照以下配置即可吃环。
        //1镶柱、step 10.1 和 step 10.2 無(wú)需設(shè)置。
        //2模叙、在 step 10.3 中歇拆,注釋 mLivePusher.pausePusher() 該方法。
        //3范咨、在 step 10.4 中故觅,注釋 mLivePusher.resumePusher() 該方法。
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        stopRtmpPublish();//結(jié)束推流
    }

    //開(kāi)播類型
    private void initLiveType() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("開(kāi)始純音頻直播還是音視頻直播");
        builder.setIcon(R.mipmap.ic_launcher);
        builder.setMessage("請(qǐng)選擇純音頻直播或是音視頻直播");
        builder.setPositiveButton("音視頻直播", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                initStartLive();//開(kāi)始直播
            }
        });
        builder.setNegativeButton("純音頻直播", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                initOnlyVoiceLive();

            }
        });
        builder.show();
    }

    //純音頻直播
    private void initOnlyVoiceLive() {

        // 只有在推流啟動(dòng)前設(shè)置啟動(dòng)純音頻推流才會(huì)生效渠啊,推流過(guò)程中設(shè)置不會(huì)生效输吏。
        mLivePushConfig.enablePureAudioPush(true);   // true 為啟動(dòng)純音頻推流,而默認(rèn)值是 false替蛉;
        mLivePusher.setConfig(mLivePushConfig);      // 重新設(shè)置 config

        String rtmpUrl = Constant.START_LIVE_URL;//開(kāi)始直播的推流地址
        mLivePusher.startPusher(rtmpUrl);
    }

    //開(kāi)始直播
    private void initStartLive() {

        mLivePusher.setConfig(mLivePushConfig);

        String rtmpUrl = Constant.START_LIVE_URL;//開(kāi)始直播的推流地址
        mLivePusher.startPusher(rtmpUrl);

        mCaptureView = (TXCloudVideoView) findViewById(R.id.video_view);
        mLivePusher.startCameraPreview(mCaptureView);
    }

    //純音頻直播
    public void voiceLive(View view) {
        Log.e("uuuuuuuu :", "純音頻直播");
        initOnlyVoiceLive();
    }

    //設(shè)置清晰度
    public void setDifinition(View view) {
        Log.e("uuuuuuuu :", "設(shè)置清晰度");

        AlertDialog.Builder localBuilder = new AlertDialog.Builder(this);

        final String[] arrayOfString = {"秀場(chǎng)直播", "手游直播", "連麥(主畫(huà)面)", "連麥(小畫(huà)面)", "視頻通話"};

        localBuilder
                .setTitle("設(shè)置清晰度")
                .setIcon(R.mipmap.ic_launcher)
                .setItems(arrayOfString, new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt) {

                        switch (paramAnonymousInt) {
                            case 0://秀場(chǎng)直播
                                mAutoBitrate = false;
                                mAutoResolution = false;
                                //VIDEO_QUALITY_SUPER_DEFINITION
                                mVideoQuality = TXLiveConstants.VIDEO_QUALITY_HIGH_DEFINITION;
                                mLivePusher.setVideoQuality(mVideoQuality, mAutoBitrate, mAutoResolution);
                                break;
                            case 1://手游直播
                                mAutoBitrate = true;
                                mAutoResolution = true;
                                mVideoQuality = TXLiveConstants.VIDEO_QUALITY_SUPER_DEFINITION;
                                mLivePusher.setVideoQuality(mVideoQuality, mAutoBitrate, mAutoResolution);
                                break;
                            case 2://連麥(主畫(huà)面)
                                mAutoBitrate = true;
                                mAutoResolution = true;
                                mVideoQuality = TXLiveConstants.VIDEO_QUALITY_LINKMIC_MAIN_PUBLISHER;
                                mLivePusher.setVideoQuality(mVideoQuality, mAutoBitrate, mAutoResolution);
                                break;
                            case 3://連麥(小畫(huà)面)
                                mAutoBitrate = false;
                                mAutoResolution = false;
                                mVideoQuality = TXLiveConstants.VIDEO_QUALITY_LINKMIC_SUB_PUBLISHER;
                                mLivePusher.setVideoQuality(mVideoQuality, mAutoBitrate, mAutoResolution);
                                break;
                            case 4://視頻通話
                                mAutoBitrate = true;
                                mAutoResolution = true;
                                mVideoQuality = TXLiveConstants.VIDEO_QUALITY_REALTIEM_VIDEOCHAT;
                                mLivePusher.setVideoQuality(mVideoQuality, mAutoBitrate, mAutoResolution);
                                break;
                        }

                        //暫時(shí)不知道什么用
                        if (mVideoQuality == TXLiveConstants.VIDEO_QUALITY_STANDARD_DEFINITION ||
                                mVideoQuality == TXLiveConstants.VIDEO_QUALITY_HIGH_DEFINITION ||
                                mVideoQuality == TXLiveConstants.VIDEO_QUALITY_SUPER_DEFINITION) {
                            mLivePushConfig.setVideoEncodeGop(5);
                        }

                        // 列表對(duì)話框不加這句贯溅,點(diǎn)擊選擇后也后不會(huì)消失
                        paramAnonymousDialogInterface.dismiss();
                    }
                }).create().show();
    }

    //設(shè)置美顏
    public void beatify(View view) {
        Log.e("uuuuuuuu :", "美顏濾鏡");

        //美顏濾鏡
        mBeautyStyle = 0;//磨皮風(fēng)格:  0:光滑  1:自然  2:朦朧
        mBeautyLevel = 0;//磨皮等級(jí): 取值為 0-9.取值為 0 時(shí)代表關(guān)閉美顏效果.默認(rèn)值: 0,即關(guān)閉美顏效果.;
        mWhiteningLevel = 0;//美白等級(jí): 取值為 0-9.取值為 0 時(shí)代表關(guān)閉美白效果.默認(rèn)值: 0,即關(guān)閉美白效果.
        mRuddyLevel = 0;//紅潤(rùn)等級(jí): 取值為 0-9.取值為 0 時(shí)代表關(guān)閉美白效果.默認(rèn)值: 0,即關(guān)閉美白效果.


        AlertDialog.Builder localBuilder = new AlertDialog.Builder(this);
        View view_beaty = getLayoutInflater().inflate(R.layout.beaty, null);

        SeekBar mStyleSeekBar = view_beaty.findViewById(R.id.mStyleSeekBar);
        final TextView mStyleTV = view_beaty.findViewById(R.id.mStyleTV);
        mStyleSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                mStyleTV.setText(progress + "");
                mBeautyStyle = progress;
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        SeekBar mLevelSeekBar = view_beaty.findViewById(R.id.mLevelSeekBar);
        final TextView mLevelTV = view_beaty.findViewById(R.id.mLevelTV);
        mLevelSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                mLevelTV.setText(progress + "");
                mBeautyLevel = progress;
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });


        SeekBar whiteningLevelSeekbar = view_beaty.findViewById(R.id.whiteningLevelSeekbar);
        final TextView whiteningLevelTV = view_beaty.findViewById(R.id.whiteningLevelTV);
        whiteningLevelSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                whiteningLevelTV.setText(progress + "");
                mWhiteningLevel = progress;
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });


        SeekBar ruddyLevelSeekbar = view_beaty.findViewById(R.id.ruddyLevelSeekbar);
        final TextView ruddyLevelTV = view_beaty.findViewById(R.id.ruddyLevelTV);
        ruddyLevelSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                ruddyLevelTV.setText(progress + "");
                mRuddyLevel = progress;
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });


        localBuilder
                .setTitle("設(shè)置美顏")
                .setIcon(R.mipmap.ic_launcher)
                .setView(view_beaty)
                .setPositiveButton("確定美顏", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt) {

                        mLivePusher.setBeautyFilter(mBeautyStyle, mBeautyLevel, mWhiteningLevel, mRuddyLevel);

                    }
                })
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt) {

                    }
                })
                .create()
                .show();
    }

    //設(shè)置濾鏡
    public void filter(View view) {
        AlertDialog.Builder localBuilder = new AlertDialog.Builder(this);
        View view_filter = getLayoutInflater().inflate(R.layout.filter, null);

        initFilterType(view_filter);

        localBuilder
                .setTitle("設(shè)置濾鏡")
                .setIcon(R.mipmap.ic_launcher)
                .setView(view_filter)
                .setPositiveButton("確定濾鏡程度", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt) {

                        mLivePusher.setSpecialRatio(filterDegree / 10.f);//濾鏡程度

                    }
                })
                .setNegativeButton("確定濾鏡圖片", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt) {
                        setFilter(filterIndex);//濾鏡圖片
                    }
                })
                .create()
                .show();
    }

    //設(shè)置曝光值
    public void exposure(View view) {
        AlertDialog.Builder localBuilder = new AlertDialog.Builder(this);
        View view_expouse = getLayoutInflater().inflate(R.layout.expouse, null);

        initExpouseView(view_expouse);

        localBuilder
                .setTitle("設(shè)置曝光值")
                .setIcon(R.mipmap.ic_launcher)
                .setView(view_expouse)
                .setPositiveButton("確定曝光值", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt) {
                        mLivePusher.setExposureCompensation(expouseCompensation);
                    }
                })
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt) {

                    }
                })
                .create()
                .show();
    }

    //設(shè)置攝像頭
    public void setCameraHead(View view) {
        Log.e("uuuuuuuu :", "設(shè)置攝像頭");
        AlertDialog.Builder localBuilder = new AlertDialog.Builder(this);
        View view_camera = getLayoutInflater().inflate(R.layout.camera, null);

        initCameraView(view_camera);

        localBuilder
                .setTitle("設(shè)置曝光值")
                .setIcon(R.mipmap.ic_launcher)
                .setView(view_camera)
                .setInverseBackgroundForced(false)
                .setPositiveButton("確定", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt) {

                    }
                })
                .create()
                .show();
    }

    //設(shè)置水印logo
    public void setLogo(View view) {
        Log.e("uuuuuuuu :", "設(shè)置水印logo");
        if (isLogo){
            Toast.makeText(this, "設(shè)置失敗拄氯,水印LOGO已經(jīng)設(shè)置了", Toast.LENGTH_SHORT).show();
        }else {
            Toast.makeText(this, "設(shè)置失敗,需要在mLivePusher.setConfig(mLivePushConfig)之前調(diào)用!它浅,這里已經(jīng)做了译柏,只需修改isLogo的值即可", Toast.LENGTH_SHORT).show();
        }
    }

    //開(kāi)始軟硬件編碼
    public void hardwareCode(View view) {
        Log.e("uuuuuuuu :", "開(kāi)始軟硬件編碼");
        if (HWVideoCode){
            Toast.makeText(this, "硬件加速失敗,原因:\n1姐霍、當(dāng)前手機(jī) API 級(jí)別過(guò)低(最低 18)\n" +
                    "2、需要在mLivePusher.setConfig(mLivePushConfig)之前調(diào)用!镊折,這里已經(jīng)做了,只需修改mTouchFocus的值即可", Toast.LENGTH_SHORT).show();
        }
    }

    //本地錄制
    public void nativeRecord(View view) {
        Log.e("uuuuuuuu :", "本地錄制");
        nativeRecord();
    }

    //后臺(tái)推流
    public void backPush(View view) {
        Log.e("uuuuuuuu :", "純音頻直播");

        Toast.makeText(this, "查看代碼中的10.1、10.2、10.3、10.4", Toast.LENGTH_SHORT).show();

    }

    //網(wǎng)絡(luò)提示
    public void networkTips(View view) {
        Log.e("uuuuuuuu :", "網(wǎng)絡(luò)提示");

        mLivePusher.setPushListener(new ITXLivePushListener() {
            @Override
            public void onPushEvent(int event, Bundle bundle) {
                if (event==TXLiveConstants.PUSH_WARNING_NET_BUSY){
                    Toast.makeText(StartLiveActivity.this, "您當(dāng)前的網(wǎng)絡(luò)狀況不佳,推薦您離 WiFi 近一點(diǎn)勺阐,盡量不要讓 WiFi 穿墻", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onNetStatus(Bundle bundle) {

            }
        });
    }

    //橫屏推流
    public void horizontalPush(View view) {
        Log.e("uuuuuuuu :", "橫屏推流");
    }

    //設(shè)置背景混淆音
    public void setBGM(View view) {
        Log.e("uuuuuuuu :", "設(shè)置背景混淆音");

    }

    //發(fā)送消息
    public void sendMessage(View view) {
        Log.e("uuuuuuuu :", "發(fā)送消息");
        //Android 示例代碼
        //mLivePusher.sendMessage(questionInfo.getBytes("UTF-8"));
        //mLivePusher.sendMessage(new byte[]);
        byte[] bytes = new byte[]{};
        mLivePusher.sendMessageEx(bytes);
    }


    //==================================設(shè)置濾鏡=======================
    //初始化Dialog的空件
    private void initFilterType(final View view_filter) {
        filterDegree = 0;
        final TextView mFilterTV = view_filter.findViewById(R.id.mFilterTV);
        SeekBar mFilterSeekBar = view_filter.findViewById(R.id.mFilterSeekBar);
        mFilterSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                filterDegree = progress;
                mFilterTV.setText("" + filterDegree);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });


        view_filter.findViewById(R.id.bailan).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                filterIndex = 5;
            }
        });
        view_filter.findViewById(R.id.biaozhun).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                filterIndex = 1;
            }
        });
        view_filter.findViewById(R.id.chaotuo).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                filterIndex = 7;
            }
        });
        view_filter.findViewById(R.id.chunzhen).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                filterIndex = 4;
            }
        });
        view_filter.findViewById(R.id.fennen).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                filterIndex = 13;
            }
        });
        view_filter.findViewById(R.id.huaijiu).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                filterIndex = 14;
            }
        });
        view_filter.findViewById(R.id.landiao).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                filterIndex = 15;
            }
        });
        view_filter.findViewById(R.id.langman).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                filterIndex = 10;
            }
        });
        view_filter.findViewById(R.id.qingliang).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                filterIndex = 16;
            }
        });
        view_filter.findViewById(R.id.qinxi).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                filterIndex = 11;
            }
        });
        view_filter.findViewById(R.id.rixi).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                filterIndex = 17;
            }
        });
        view_filter.findViewById(R.id.weimei).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                filterIndex = 12;
            }
        });
        view_filter.findViewById(R.id.white).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                filterIndex = 9;
            }
        });
        view_filter.findViewById(R.id.xiangfen).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                filterIndex = 8;
            }
        });
        view_filter.findViewById(R.id.yinghong).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                filterIndex = 2;
            }
        });
        view_filter.findViewById(R.id.yuanqi).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                filterIndex = 6;
            }
        });
        view_filter.findViewById(R.id.yunshang).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                filterIndex = 3;
            }
        });
    }

    //設(shè)置濾鏡
    private void setFilter(int index) {
        Bitmap bmp = getFilterBitmapByIndex(index);
        if (mLivePusher != null) {
            mLivePusher.setFilter(bmp);
        }
    }

    //獲取圖片資源
    public Bitmap getFilterBitmapByIndex(int index) {
        Bitmap bmp = null;
        switch (index) {
            case 1:
                bmp = decodeResource(getResources(), R.drawable.filter_biaozhun);
                break;
            case 2:
                bmp = decodeResource(getResources(), R.drawable.filter_yinghong);
                break;
            case 3:
                bmp = decodeResource(getResources(), R.drawable.filter_yunshang);
                break;
            case 4:
                bmp = decodeResource(getResources(), R.drawable.filter_chunzhen);
                break;
            case 5:
                bmp = decodeResource(getResources(), R.drawable.filter_bailan);
                break;
            case 6:
                bmp = decodeResource(getResources(), R.drawable.filter_yuanqi);
                break;
            case 7:
                bmp = decodeResource(getResources(), R.drawable.filter_chaotuo);
                break;
            case 8:
                bmp = decodeResource(getResources(), R.drawable.filter_xiangfen);
                break;
            case 9:
                bmp = decodeResource(getResources(), R.drawable.filter_white);
                break;
            case 10:
                bmp = decodeResource(getResources(), R.drawable.filter_langman);
                break;
            case 11:
                bmp = decodeResource(getResources(), R.drawable.filter_qingxin);
                break;
            case 12:
                bmp = decodeResource(getResources(), R.drawable.filter_weimei);
                break;
            case 13:
                bmp = decodeResource(getResources(), R.drawable.filter_fennen);
                break;
            case 14:
                bmp = decodeResource(getResources(), R.drawable.filter_huaijiu);
                break;
            case 15:
                bmp = decodeResource(getResources(), R.drawable.filter_landiao);
                break;
            case 16:
                bmp = decodeResource(getResources(), R.drawable.filter_qingliang);
                break;
            case 17:
                bmp = decodeResource(getResources(), R.drawable.filter_rixi);
                break;
            default:
                bmp = null;
                break;
        }
        return bmp;
    }

    //獲取資源圖片轉(zhuǎn)換
    private Bitmap decodeResource(Resources resources, int id) {
        TypedValue value = new TypedValue();
        resources.openRawResource(id, value);
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inTargetDensity = value.density;
        return BitmapFactory.decodeResource(resources, id, opts);
    }


    //======================================曝光值======================
    //初始化曝光值控件
    private void initExpouseView(View view_expouse) {
        SeekBar mExpuseSeekBar = view_expouse.findViewById(R.id.mExpuseSeekBar);
        final TextView mExpuseTV = view_expouse.findViewById(R.id.mExpuseTV);

        mExpuseSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                float p=(progress-10)/10.0f;
                expouseCompensation=p;
                mExpuseTV.setText("曝光值為:"+p);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }

    //===================================控制攝像頭======================
    private void initCameraView(View view_camera) {
        TextView cameraTV = view_camera.findViewById(R.id.cameraTV);//前后攝像頭
        TextView lampTV = view_camera.findViewById(R.id.lampTV);//閃光燈
        TextView mFocuseTV = view_camera.findViewById(R.id.mFocuseTV);//自動(dòng)手動(dòng)對(duì)焦
        TextView mMirrorTV = view_camera.findViewById(R.id.mMirrorTV);//鏡像效果

        cameraTV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 默認(rèn)是前置攝像頭
                mLivePusher.switchCamera();
            }
        });

        lampTV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mLivePusher.turnOnFlashLight(mFlashTurnOn);
                //mFlashTurnOn為true表示打開(kāi),否則表示關(guān)閉
                if (!mLivePusher.turnOnFlashLight(mFlashTurnOn)) {
                    Toast.makeText(getApplicationContext(), "打開(kāi)閃光燈失敗:絕大部分手機(jī)不支持前置閃光燈!", Toast.LENGTH_SHORT).show();
                }
                mFlashTurnOn=!mFlashTurnOn;
            }
        });

        mFocuseTV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getApplicationContext(), "設(shè)置手自動(dòng)對(duì)焦失敗:需要在mLivePusher.setConfig(mLivePushConfig)之前調(diào)用!矛双,這里已經(jīng)做了渊抽,只需修改mTouchFocus的值即可", Toast.LENGTH_SHORT).show();
            }
        });

        mMirrorTV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 需在 mLivePusher.setConfig(mLivePushConfig); 之后調(diào)用
                mLivePusher.setMirror(true);
            }
        });
    }

    //=================================軟硬件編碼========================
    private void initHardWareCode() {
        if (HWVideoCode){
            if (HWVideoCode){
                if (mLivePushConfig != null) {
                    if(Build.VERSION.SDK_INT < 18){
                        Toast.makeText(getApplicationContext(), "硬件加速失敗,當(dāng)前手機(jī) API 級(jí)別過(guò)低(最低 18)",
                                Toast.LENGTH_SHORT).show();
                        HWVideoCode = false;
                    }
                }
            }

            mLivePushConfig.setHardwareAcceleration(HWVideoCode ? TXLiveConstants.ENCODE_VIDEO_HARDWARE : TXLiveConstants.ENCODE_VIDEO_SOFTWARE);

            // 如果你不清楚要何時(shí)開(kāi)啟硬件加速, 建議設(shè)置為 ENCODE_VIDEO_AUTO
            // 默認(rèn)是啟用軟件編碼, 但手機(jī) CPU 使用率超過(guò) 80% 或者幀率 <= 10, SDK 內(nèi)部會(huì)自動(dòng)切換為硬件編碼
            //ENCODE_VIDEO_HARDWARE 開(kāi)啟硬件加速
            //ENCODE_VIDEO_SOFTWARE 禁用硬件加速议忽,默認(rèn)禁用硬件加速
            //ENCODE_VIDEO_AUTO 自動(dòng)選擇是否啟用硬件加速
        }
    }

    //=================================設(shè)置水印========================
    private void initLogo() {
        if (isLogo){
            //設(shè)置視頻水印懒闷,后面兩個(gè)參數(shù)分別是水印位置的 X 軸坐標(biāo)和 Y 軸坐標(biāo)
            mLivePushConfig.setWatermark(BitmapFactory.decodeResource(getResources(), R.drawable.watermark), 10, 10);

            //設(shè)置視頻水印
            //參數(shù)分別是水印圖片的 Bitmap、水印位置的 X 軸坐標(biāo)栈幸,水印位置的 Y 軸坐標(biāo)愤估,水印寬度。后面三個(gè)參數(shù)取值范圍是[0, 1]
            //后面兩個(gè)參數(shù)分別是水印位置的X軸坐標(biāo)和 Y 軸坐標(biāo)
            //mLivePushConfig.setWatermark(mBitmap, 0.02f, 0.05f, 0.2f);
        }
    }

    //=================================本地錄制========================
    private void nativeRecord(){
        String externalFilesDir = getExternalFilesDir(Environment.DIRECTORY_MOVIES).toString()+".mp4";
        mLivePusher.startRecord(externalFilesDir);
        mLivePusher.setVideoRecordListener(new TXRecordCommon.ITXVideoRecordListener() {
            @Override
            public void onRecordEvent(int event, Bundle bundle) {
                Log.e("本地錄制==","完成"+event);
            }

            @Override
            public void onRecordProgress(long milliSecond) {
                recordTv.setText(String.format("%02d:%02d",milliSecond/1000/60, milliSecond/1000%60));
            }

            @Override
            public void onRecordComplete(TXRecordCommon.TXRecordResult txRecordResult) {
                Log.e("本地錄制==","完成"+txRecordResult.videoPath+"  "+txRecordResult.coverPath);
            }
        });

        recordTv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mLivePusher.stopRecord();
            }
        });
    }

    //=============================后臺(tái)推流============================
    // 設(shè)置主播暫停背景圖
    private void setPasueBackImg() {
        mLivePushConfig.setPauseImg(300,5);
        // 300 為后臺(tái)播放暫停圖片的最長(zhǎng)持續(xù)時(shí)間,單位是秒
        // 10 為后臺(tái)播放暫停圖片的幀率,最小值為 5,最大值為 20
        Bitmap bitmap = decodeResource(getResources(), R.drawable.pause_publish);
        mLivePushConfig.setPauseImg(bitmap);
        // 設(shè)置推流暫停時(shí),后臺(tái)播放的暫停圖片, 圖片最大尺寸不能超過(guò) 1920*1920.


        //10.2 設(shè)置setPauseFlag
        mLivePushConfig.setPauseFlag(PAUSE_FLAG_PAUSE_VIDEO|PAUSE_FLAG_PAUSE_AUDIO);//表示同時(shí)停止視頻和音頻采集速址,并且推送填充用的音視頻流玩焰;

        //mLivePushConfig.setPauseFlag(PAUSE_FLAG_PAUSE_VIDEO);//表示停止攝像頭采集視頻畫(huà)面,但保持麥克風(fēng)繼續(xù)采集聲音芍锚,用于主播更衣等場(chǎng)景昔园;
    }


    //===============================橫屏推流===========================
    //調(diào)整觀眾端表現(xiàn)
    private void horizontalPushCustom() {
        // 豎屏狀態(tài), 手機(jī) Home 鍵在正下方蔓榄。   旋轉(zhuǎn) 0 度
        mLivePushConfig.setHomeOrientation(TXLiveConstants.VIDEO_ANGLE_HOME_DOWN);
        // 橫屏狀態(tài),手機(jī) Home 鍵在右手方默刚。   旋轉(zhuǎn) 270 度
        mLivePushConfig.setHomeOrientation(TXLiveConstants.VIDEO_ANGLE_HOME_RIGHT);
    }

    //調(diào)整主播端表現(xiàn)
    private void horizontalPushLiver() {
        // 豎屏狀態(tài)甥郑,本地渲染相對(duì)正方向的角度為0。
        mLivePusher.setRenderRotation(0);
        // 橫屏狀態(tài)羡棵,本地渲染相對(duì)正方向的角度為90壹若。
        mLivePusher.setRenderRotation(90);
    }

    //Activity自旋轉(zhuǎn)
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        // 自動(dòng)旋轉(zhuǎn)打開(kāi),Activity隨手機(jī)方向旋轉(zhuǎn)之后皂冰,只需要改變推流方向
        int mobileRotation = getWindowManager().getDefaultDisplay().getRotation();
        int pushRotation = TXLiveConstants.VIDEO_ANGLE_HOME_DOWN;
        switch (mobileRotation) {
            case Surface.ROTATION_0:
                pushRotation = TXLiveConstants.VIDEO_ANGLE_HOME_DOWN;
                break;
            case Surface.ROTATION_90:
                pushRotation = TXLiveConstants.VIDEO_ANGLE_HOME_RIGHT;
                break;
            case Surface.ROTATION_270:
                pushRotation = TXLiveConstants.VIDEO_ANGLE_HOME_LEFT;
                break;
            default:
                break;
        }

        //通過(guò)設(shè)置config是設(shè)置生效(可以不用重新推流店展,騰訊云是少數(shù)支持直播中熱切換分辨率的云商之一)
        mLivePusher.setRenderRotation(0);
        mLivePushConfig.setHomeOrientation(pushRotation);
        mLivePusher.setConfig(mLivePushConfig);
    }


    //===============================step 13:背景混音===========================
    //SDK 1.6.1 開(kāi)始支持背景混音,支持主播帶耳機(jī)和不帶耳機(jī)兩種場(chǎng)景秃流,您可以通過(guò) TXLivePusher 中的如下這組接口實(shí)現(xiàn)背景混音功能:
    //playBGM   通過(guò) path 傳入一首歌曲赂蕴,小直播 Demo中我們是從iOS的本地媒體庫(kù)中獲取音樂(lè)文件
    //stopBGM   停止播放背景音樂(lè)
    //pauseBGM  暫停播放背景音樂(lè)
    //resumeBGM 繼續(xù)播放背景音樂(lè)
    //setMicVolume  設(shè)置混音時(shí)麥克風(fēng)的音量大小,推薦在 UI 上實(shí)現(xiàn)相應(yīng)的一個(gè)滑動(dòng)條舶胀,由主播自己設(shè)置
    //setBGMVolume  設(shè)置混音時(shí)背景音樂(lè)的音量大小概说,推薦在 UI 上實(shí)現(xiàn)相應(yīng)的一個(gè)滑動(dòng)條,由主播自己設(shè)置



    //===============================step 14: 結(jié)束推流===========================
    //結(jié)束推流嚣伐,注意做好清理工作
    public void stopRtmpPublish() {
        mLivePusher.stopCameraPreview(true); //停止攝像頭預(yù)覽
        mLivePusher.stopPusher();            //停止推流
        mLivePusher.setPushListener(null);   //解綁 listener

        mLivePusher.stopBGM();
        mLivePusher.stopScreenCapture();
        mCaptureView.setVisibility(View.GONE);
    }
}

注:
①糖赔、直播碼獲取:https://console.cloud.tencent.com/live/livecodemanage

image.png

②轩端、接入文檔地址:
https://cloud.tencent.com/document/product/268/7685

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末放典,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子基茵,更是在濱河造成了極大的恐慌奋构,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拱层,死亡現(xiàn)場(chǎng)離奇詭異弥臼,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)根灯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)径缅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人烙肺,你說(shuō)我怎么就攤上這事芥驳。” “怎么了茬高?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵兆旬,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我怎栽,道長(zhǎng)丽猬,這世上最難降的妖魔是什么宿饱? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮脚祟,結(jié)果婚禮上谬以,老公的妹妹穿的比我還像新娘。我一直安慰自己由桌,他們只是感情好为黎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著行您,像睡著了一般铭乾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上娃循,一...
    開(kāi)封第一講書(shū)人閱讀 51,698評(píng)論 1 305
  • 那天炕檩,我揣著相機(jī)與錄音,去河邊找鬼捌斧。 笑死笛质,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的捞蚂。 我是一名探鬼主播妇押,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼姓迅!你這毒婦竟也來(lái)了敲霍?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤队贱,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后潭袱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體柱嫌,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年屯换,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了编丘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡彤悔,死狀恐怖嘉抓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情晕窑,我是刑警寧澤抑片,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站杨赤,受9級(jí)特大地震影響敞斋,放射性物質(zhì)發(fā)生泄漏截汪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一植捎、第九天 我趴在偏房一處隱蔽的房頂上張望衙解。 院中可真熱鬧,春花似錦焰枢、人聲如沸蚓峦。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)暑椰。三九已至,卻和暖如春拟淮,著一層夾襖步出監(jiān)牢的瞬間干茉,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工很泊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留角虫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓委造,卻偏偏與公主長(zhǎng)得像戳鹅,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子昏兆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,171評(píng)論 25 707
  • 用兩張圖告訴你枫虏,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 12,732評(píng)論 2 59
  • 這兩天在聽(tīng)《馬東的職場(chǎng)A計(jì)劃》里講到爬虱,我們?cè)谏钪凶鍪裁磿?huì)得到高付出高回報(bào)的事情吶隶债,那就是工作,花兩個(gè)小時(shí)作出...
    趙寜兒閱讀 3,472評(píng)論 1 1
  • 1.前言 隨著技術(shù)的發(fā)展跑筝,移動(dòng)端開(kāi)發(fā)也多種多樣起來(lái)死讹,有Native、Hybrid和Web等多種開(kāi)發(fā)方式曲梗。而Nati...
    lanceJin閱讀 1,854評(píng)論 0 7