This commit is contained in:
zhongjin
2021-11-27 21:04:16 +08:00
parent 42215dfa59
commit c36e1434e4
95 changed files with 1037 additions and 30 deletions

View File

@@ -1,16 +1,28 @@
package net.spacen.xxh_video;
import static com.tencent.live2.V2TXLiveCode.V2TXLIVE_ERROR_INVALID_PARAMETER;
import static com.tencent.live2.V2TXLiveCode.V2TXLIVE_OK;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.AnimationDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;
@@ -18,6 +30,7 @@ import com.tencent.live2.V2TXLiveDef;
import com.tencent.live2.V2TXLivePlayer;
import com.tencent.live2.V2TXLivePlayerObserver;
import com.tencent.live2.impl.V2TXLivePlayerImpl;
import com.tencent.rtmp.TXLiveBase;
import com.tencent.rtmp.TXLiveConstants;
import com.tencent.rtmp.TXLivePlayer;
import com.tencent.rtmp.ui.TXCloudVideoView;
@@ -26,16 +39,42 @@ import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import okhttp3.OkHttpClient;
import tv.danmaku.ijk.media.player.IMediaPlayer;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;
public class MainActivity extends AppCompatActivity {
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
public final String TAG = MainActivity.class.getSimpleName();
private Context mContext;
private ImageView mImageLoading; //显示视频缓冲动画
private RelativeLayout mLayoutRoot; //视频暂停时更新背景
private LinearLayout mLayoutToolbar; //视频Tools
private RelativeLayout mliveplayer_title;
private ImageView mImageRoot; //背景icon
private ImageButton mButtonPlay; //视频的播放控制按钮
private ImageButton mButtonRenderRotation; //调整视频播放方向:横屏、竖屏
private ImageButton mButtonRenderMode; //调整视频渲染模式:全屏、自适应
private ImageButton mButtonCacheStrategy; //设置视频的缓存策略
private ImageView mImageCacheStrategyShadow;
private ImageButton mImageLogInfo;
//private RadioSelectView mLayoutCacheStrategy; //显示所有缓存模式的View
//private LogInfoWindow mLogInfoWindow;
private int mLogClickCount = 0;
private V2TXLivePlayer mLivePlayer; //直播拉流的视频播放器
private TXCloudVideoView mVideoView;
@@ -50,6 +89,12 @@ public class MainActivity extends AppCompatActivity {
private OkHttpClient mOkHttpClient = null; //获取超低时延视频源直播地址
private int mCacheStrategy = Constants.CACHE_STRATEGY_AUTO; //Player缓存策略
private int mActivityPlayType = Constants.ACTIVITY_TYPE_LIVE_PLAY; //播放类型
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);
@@ -63,36 +108,135 @@ public class MainActivity extends AppCompatActivity {
MyMqttService.startService(this); //开启服务
//timer.schedule(task,0,10000);
String licenceURL = "https://license.vod2.myqcloud.com/license/v2/1304883579_1/v_cube.license"; // 获取到的 licence url
String licenceKey = "cd83b2d9f0570e9ab4b5059a3cf5ba36"; // 获取到的 licence key
TXLiveBase.getInstance().setLicence(this, licenceURL, licenceKey);
EventBus.getDefault().register(this);
mContext = this;
TextView t1 = (TextView) findViewById(R.id.liveplayer_title_textview);
t1.setText(getAndroidID());
Toast.makeText(this, getAndroidID() + " 哈哈,我成功启动了!", Toast.LENGTH_LONG).show();
Log.e("AutoRun","哈哈,我成功启动了!");
mPlayURL = "rtmp://v.dl8.tv/show/mini";
//mPlayerView 即 step1 中添加的界面 view
mVideoView = (TXCloudVideoView) findViewById(R.id.video_view);
vv_view = (VideoView) findViewById(R.id.vv_view);
vv_view.setVisibility(View.GONE);
initialize();
}
mContext = this;
@Override
public void onClick(View view) {
showToolbox();
}
private void hideToolbox() {
mLayoutToolbar.setVisibility(View.GONE);
mliveplayer_title.setVisibility(View.GONE);
}
private void showToolbox() {
mLayoutToolbar.setVisibility(View.VISIBLE);
mliveplayer_title.setVisibility(View.VISIBLE);
mLayoutToolbar.postDelayed(new Runnable() {
@Override
public void run() {
hideToolbox();
}},10000);
}
private void initialize() {
mLayoutRoot = (RelativeLayout) findViewById(R.id.liveplayer_rl_root);
mliveplayer_title = (RelativeLayout) findViewById(R.id.liveplayer_title);
mImageRoot = (ImageView) findViewById(R.id.liveplayer_iv_root);
mLayoutToolbar = (LinearLayout) findViewById(R.id.liveplayer_ll_menu_layout);
initPlayView();
initPlayButton();
initRenderRotationButton();
initRenderModeButton();
initCacheStrategyButton();
//initNavigationBack();
//initRTMPURL();
showToolbox();
// 初始化完成之后自动播放
startPlay();
}
private void initPlayView() {
mVideoView = (TXCloudVideoView) findViewById(R.id.video_view);
mVideoView.setLogMargin(12, 12, 110, 60);
mVideoView.showLog(false);
mVideoView.setOnClickListener(this);
vv_view.setOnClickListener(this);
//创建 player 对象
mLivePlayer = new V2TXLivePlayerImpl(mContext);
mImageLoading = (ImageView) findViewById(R.id.liveplayer_iv_loading);
}
//关键 player 对象与界面 view
mLivePlayer.setRenderView(mVideoView);
private void initCacheStrategyButton() {
String flvUrl = "rtmp://v.dl8.tv/show/mini";
//mLayoutCacheStrategy = (RadioSelectView) findViewById(R.id.liveplayer_rsv_cache_strategy);
mImageCacheStrategyShadow = (ImageView) findViewById(R.id.liveplayer_btn_cache_strategy_shadow);
mButtonCacheStrategy = (ImageButton) findViewById(R.id.liveplayer_btn_cache_strategy);
mButtonCacheStrategy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(mContext, CameraPushEntranceActivity.class);
/*
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);
}
});
}
//自动模式
mLivePlayer.setCacheParams(1.0f, 5.0f);
private void startPlay() {
String playURL = mPlayURL;
int code = checkPlayURL(playURL);
if (code != Constants.PLAY_STATUS_SUCCESS) {
mIsPlaying = false;
} else {
mLivePlayer.setRenderView(mVideoView);
mLivePlayer.setObserver(new MyPlayerObserver());
//极速模式
//mLivePlayer.setCacheParams(1.0f, 1.0f);
mLivePlayer.setRenderRotation(mRenderRotation);
mLivePlayer.setRenderFillMode(mRenderMode);
//流畅模式
//mLivePlayer.setCacheParams(5.0f, 5.0f);
//设置完成之后再启动播放
mLivePlayer.setCacheParams(1.0f, 5.0f);
mLivePlayer.startPlay(flvUrl);
/**
* result返回值
* 0 V2TXLIVE_OK; -2 V2TXLIVE_ERROR_INVALID_PARAMETER; -3 V2TXLIVE_ERROR_REFUSED;
*/
code = mLivePlayer.startPlay(playURL);
mIsPlaying = code == 0;
Log.d("video render", "timetrack start play");
}
//处理UI相关操作
onPlayStart(code);
}
@Override
@@ -107,6 +251,20 @@ public class MainActivity extends AppCompatActivity {
destroy();
}
private void startLoadingAnimation() {
if (mImageLoading != null) {
mImageLoading.setVisibility(View.VISIBLE);
((AnimationDrawable) mImageLoading.getDrawable()).start();
}
}
private void stopLoadingAnimation() {
if (mImageLoading != null) {
mImageLoading.setVisibility(View.GONE);
((AnimationDrawable) mImageLoading.getDrawable()).stop();
}
}
private void stopPlay() {
if (!mIsPlaying) {
return;
@@ -137,11 +295,11 @@ public class MainActivity extends AppCompatActivity {
public void onPlayStop() {
// mButtonPlay.setBackgroundResource(R.drawable.liveplayer_play_start_btn);
// mLayoutRoot.setBackgroundResource(R.drawable.liveplayer_content_bg);
// mImageRoot.setVisibility(View.VISIBLE);
mButtonPlay.setBackgroundResource(R.drawable.liveplayer_play_start_btn);
mLayoutRoot.setBackgroundResource(R.drawable.liveplayer_content_bg);
mImageRoot.setVisibility(View.VISIBLE);
// mLogInfoWindow.clear();
// stopLoadingAnimation();
stopLoadingAnimation();
}
private class MyPlayerObserver extends V2TXLivePlayerObserver {
@@ -235,6 +393,150 @@ public class MainActivity extends AppCompatActivity {
}
private int checkPlayURL(final String playURL) {
if (TextUtils.isEmpty(playURL)) {
return Constants.PLAY_STATUS_EMPTY_URL;
}
if (!playURL.startsWith(Constants.URL_PREFIX_HTTP) && !playURL.startsWith(Constants.URL_PREFIX_HTTPS)
&& !playURL.startsWith(Constants.URL_PREFIX_RTMP) && !playURL.startsWith("/")) {
return Constants.PLAY_STATUS_INVALID_URL;
}
boolean isLiveRTMP = playURL.startsWith(Constants.URL_PREFIX_RTMP);
boolean isLiveFLV = (playURL.startsWith(Constants.URL_PREFIX_HTTP) || playURL.startsWith(Constants.URL_PREFIX_HTTPS)) && playURL.contains(Constants.URL_SUFFIX_FLV);
if (mActivityPlayType == Constants.ACTIVITY_TYPE_LIVE_PLAY) {
if (isLiveRTMP) {
return Constants.PLAY_STATUS_SUCCESS;
}
if (isLiveFLV) {
return Constants.PLAY_STATUS_SUCCESS;
}
return Constants.PLAY_STATUS_INVALID_URL;
}
if (mActivityPlayType == Constants.ACTIVITY_TYPE_REALTIME_PLAY) {
if (!isLiveRTMP) {
return Constants.PLAY_STATUS_INVALID_RTMP_URL;
}
if (!playURL.contains(Constants.URL_TX_SECRET)) {
return Constants.PLAY_STATUS_INVALID_SECRET_RTMP_URL;
}
return Constants.PLAY_STATUS_SUCCESS;
}
return Constants.PLAY_STATUS_INVALID_URL;
}
private void togglePlay() {
Log.d(TAG, "togglePlay: mIsPlaying:" + mIsPlaying + ", mCurrentPlayType:" + mActivityPlayType);
if (mIsPlaying) {
stopPlay();
} else {
startPlay();
}
}
public void onPlayStart(int code) {
/*
switch (code) {
case V2TXLIVE_OK:
startLoadingAnimation();
break;
case V2TXLIVE_ERROR_INVALID_PARAMETER:
Toast.makeText(mContext, R.string.liveplayer_warning_res_url_invalid, Toast.LENGTH_SHORT).show();
break;
default:
break;
}
if (code != V2TXLIVE_OK) {
mButtonPlay.setBackgroundResource(R.drawable.liveplayer_play_start_btn);
mLayoutRoot.setBackgroundResource(R.drawable.liveplayer_content_bg);
mImageRoot.setVisibility(View.VISIBLE);
Bundle params = new Bundle();
params.putString(TXLiveConstants.EVT_DESCRIPTION, mContext.getResources().getString(R.string.liveplayer_warning_checkout_res_url));
mLogInfoWindow.setLogText(null, params, LogInfoWindow.CHECK_RTMP_URL_FAIL);
} else {
mButtonPlay.setBackgroundResource(R.drawable.liveplayer_play_pause_btn);
mLayoutRoot.setBackgroundColor(getResources().getColor(R.color.liveplayer_black));
mImageRoot.setVisibility(View.GONE);
Bundle params = new Bundle();
params.putString(TXLiveConstants.EVT_DESCRIPTION, mContext.getResources().getString(R.string.liveplayer_warning_checkout_res_url));
mLogInfoWindow.setLogText(null, params, LogInfoWindow.CHECK_RTMP_URL_OK);
}
*/
}
private void initPlayButton() {
mButtonPlay = (ImageButton) findViewById(R.id.liveplayer_btn_play);
mButtonPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
togglePlay();
}
});
}
private void initRenderRotationButton() {
mButtonRenderRotation = (ImageButton) findViewById(R.id.liveplayer_btn_render_rotate_landscape);
mButtonRenderRotation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
V2TXLiveDef.V2TXLiveRotation renderRotation = getRenderRotation();
if (renderRotation == V2TXLiveDef.V2TXLiveRotation.V2TXLiveRotation0) {
mButtonRenderRotation.setBackgroundResource(R.drawable.liveplayer_render_rotate_portrait);
renderRotation = V2TXLiveDef.V2TXLiveRotation.V2TXLiveRotation270;
} else if (renderRotation == V2TXLiveDef.V2TXLiveRotation.V2TXLiveRotation270) {
mButtonRenderRotation.setBackgroundResource(R.drawable.liveplayer_render_rotate_landscape);
renderRotation = V2TXLiveDef.V2TXLiveRotation.V2TXLiveRotation0;
}
setRenderRotation(renderRotation);
}
});
}
private void setRenderMode(V2TXLiveDef.V2TXLiveFillMode renderMode) {
mRenderMode = renderMode;
mLivePlayer.setRenderFillMode(renderMode);
}
private V2TXLiveDef.V2TXLiveFillMode getRenderMode() {
return mRenderMode;
}
private void setRenderRotation(V2TXLiveDef.V2TXLiveRotation renderRotation) {
mRenderRotation = renderRotation;
mLivePlayer.setRenderRotation(renderRotation);
}
private V2TXLiveDef.V2TXLiveRotation getRenderRotation() {
return mRenderRotation;
}
private void initRenderModeButton() {
mButtonRenderMode = (ImageButton) findViewById(R.id.liveplayer_btn_render_mode_fill);
mButtonRenderMode.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
V2TXLiveDef.V2TXLiveFillMode renderMode = getRenderMode();
if (getRenderMode() == V2TXLiveDef.V2TXLiveFillMode.V2TXLiveFillModeFill) {
mButtonRenderMode.setBackgroundResource(R.drawable.liveplayer_render_mode_fill);
renderMode = V2TXLiveDef.V2TXLiveFillMode.V2TXLiveFillModeFit;
} else if (getRenderMode() == V2TXLiveDef.V2TXLiveFillMode.V2TXLiveFillModeFit) {
mButtonRenderMode.setBackgroundResource(R.drawable.liveplayer_adjust_mode_btn);
renderMode = V2TXLiveDef.V2TXLiveFillMode.V2TXLiveFillModeFill;
}
setRenderMode(renderMode);
}
});
}
private String getAndroidID() {
return Settings.Secure.getString( getContentResolver(), Settings.Secure.ANDROID_ID);
@@ -243,15 +545,15 @@ public class MainActivity extends AppCompatActivity {
@Subscribe(threadMode = ThreadMode.MAIN)
public void onGetMessage(MessageWrap message) {
// getBinding().tvMessage.setText(message.message);
Log.i(TAG, "收到消息: " + new String(message.message));
Toast.makeText(getApplicationContext(), "EventBus: " + new String(message.message), Toast.LENGTH_LONG).show();
// Log.i(TAG, "收到消息: " + new String(message.message));
// Toast.makeText(getApplicationContext(), "EventBus: " + new String(message.message), Toast.LENGTH_LONG).show();
String url = new String(message.message);
if (url.substring(url.length()-4).equals("m3u8")){
mLivePlayer.stopPlay();
mVideoView.setVisibility(View.GONE);
vv_view.setVisibility(View.VISIBLE);
vv_view.setVideoPath(url);
vv_view.start();