Files
xxh-video/app/src/main/java/net/spacen/xxh_video/MainActivity.java
zhongjin c36e1434e4 new
2021-11-27 21:04:16 +08:00

571 lines
22 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
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;
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 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;
private VideoView vv_view;
private SurfaceView sv_view;
private IjkMediaPlayer ijkMediaPlayer;
private String mPlayURL = "";
private boolean mIsPlaying = false;
private boolean mFetching = false; //是否正在获取视频源,测试专用
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);
setContentView(R.layout.activity_main);
// requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
MyMqttService.setCLIENTID(getAndroidID());
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();
}
@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);
mLivePlayer = new V2TXLivePlayerImpl(mContext);
mImageLoading = (ImageView) findViewById(R.id.liveplayer_iv_loading);
}
private void initCacheStrategyButton() {
//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);
}
});
}
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.setRenderRotation(mRenderRotation);
mLivePlayer.setRenderFillMode(mRenderMode);
mLivePlayer.setCacheParams(1.0f, 5.0f);
/**
* 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
public void onBackPressed() {
stopPlay();
super.onBackPressed();
}
@Override
public void onDestroy() {
super.onDestroy();
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;
}
if (mLivePlayer != null) {
mLivePlayer.setObserver(null);
mLivePlayer.stopPlay();
}
mIsPlaying = false;
//处理UI相关操作
onPlayStop();
}
private void destroy() {
if (mOkHttpClient != null) {
mOkHttpClient.dispatcher().cancelAll();
}
if (mLivePlayer != null) {
mLivePlayer.stopPlay();
mLivePlayer = null;
}
if (mVideoView != null) {
mVideoView.onDestroy();
mVideoView = null;
}
}
public void onPlayStop() {
mButtonPlay.setBackgroundResource(R.drawable.liveplayer_play_start_btn);
mLayoutRoot.setBackgroundResource(R.drawable.liveplayer_content_bg);
mImageRoot.setVisibility(View.VISIBLE);
// mLogInfoWindow.clear();
stopLoadingAnimation();
}
private class MyPlayerObserver extends V2TXLivePlayerObserver {
@Override
public void onWarning(V2TXLivePlayer player, int code, String msg, Bundle extraInfo) {
Log.w(TAG, "[Player] onWarning: player-" + player + " code-" + code + " msg-" + msg + " info-" + extraInfo);
}
@Override
public void onError(V2TXLivePlayer player, int code, String msg, Bundle extraInfo) {
Log.e(TAG, "[Player] onError: player-" + player + " code-" + code + " msg-" + msg + " info-" + extraInfo);
}
@Override
public void onSnapshotComplete(V2TXLivePlayer v2TXLivePlayer, Bitmap bitmap) {
}
@Override
public void onVideoPlayStatusUpdate(V2TXLivePlayer player, V2TXLiveDef.V2TXLivePlayStatus status, V2TXLiveDef.V2TXLiveStatusChangeReason reason, Bundle bundle) {
Log.i(TAG, "[Player] onVideoPlayStatusUpdate: player-" + player + ", status-" + status + ", reason-" + reason);
switch (status) {
case V2TXLivePlayStatusLoading:
//startLoadingAnimation();
break;
case V2TXLivePlayStatusPlaying:
//stopLoadingAnimation();
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);
break;
case V2TXLivePlayStatusStopped:
if (reason == V2TXLiveDef.V2TXLiveStatusChangeReason.V2TXLiveStatusChangeReasonRemoteOffline) {
stopPlay();
}
default:
break;
}
}
@Override
public void onAudioPlayStatusUpdate(V2TXLivePlayer player, V2TXLiveDef.V2TXLivePlayStatus status, V2TXLiveDef.V2TXLiveStatusChangeReason reason, Bundle bundle) {
Log.i(TAG, "[Player] onAudioPlayStatusUpdate: player-" + player + ", status-" + status + ", reason-" + reason);
switch (status) {
case V2TXLivePlayStatusLoading:
//startLoadingAnimation();
break;
case V2TXLivePlayStatusPlaying:
//stopLoadingAnimation();
break;
case V2TXLivePlayStatusStopped:
if (reason == V2TXLiveDef.V2TXLiveStatusChangeReason.V2TXLiveStatusChangeReasonRemoteOffline) {
stopPlay();
}
default:
break;
}
}
@Override
public void onPlayoutVolumeUpdate(V2TXLivePlayer player, int volume) {
// Log.i(TAG, "onPlayoutVolumeUpdate: player-" + player + ", volume-" + volume);
}
@Override
public void onStatisticsUpdate(V2TXLivePlayer player, V2TXLiveDef.V2TXLivePlayerStatistics statistics) {
Bundle netStatus = new Bundle();
netStatus.putInt(TXLiveConstants.NET_STATUS_VIDEO_WIDTH, statistics.width);
netStatus.putInt(TXLiveConstants.NET_STATUS_VIDEO_HEIGHT, statistics.height);
int appCpu = statistics.appCpu / 10;
int totalCpu = statistics.systemCpu / 10;
String strCpu = appCpu + "/" + totalCpu + "%";
netStatus.putCharSequence(TXLiveConstants.NET_STATUS_CPU_USAGE, strCpu);
netStatus.putInt(TXLiveConstants.NET_STATUS_NET_SPEED, statistics.videoBitrate + statistics.audioBitrate);
netStatus.putInt(TXLiveConstants.NET_STATUS_AUDIO_BITRATE, statistics.audioBitrate);
netStatus.putInt(TXLiveConstants.NET_STATUS_VIDEO_BITRATE, statistics.videoBitrate);
netStatus.putInt(TXLiveConstants.NET_STATUS_VIDEO_FPS, statistics.fps);
netStatus.putInt(TXLiveConstants.NET_STATUS_AUDIO_CACHE, 0);
netStatus.putInt(TXLiveConstants.NET_STATUS_VIDEO_CACHE, 0);
netStatus.putInt(TXLiveConstants.NET_STATUS_V_SUM_CACHE_SIZE, 0);
netStatus.putInt(TXLiveConstants.NET_STATUS_V_DEC_CACHE_SIZE, 0);
netStatus.putString(TXLiveConstants.NET_STATUS_AUDIO_INFO, "");
Log.d(TAG, "Current status, CPU:" + netStatus.getString(TXLiveConstants.NET_STATUS_CPU_USAGE) +
", RES:" + netStatus.getInt(TXLiveConstants.NET_STATUS_VIDEO_WIDTH) + "*" + netStatus.getInt(TXLiveConstants.NET_STATUS_VIDEO_HEIGHT) +
", SPD:" + netStatus.getInt(TXLiveConstants.NET_STATUS_NET_SPEED) + "Kbps" +
", FPS:" + netStatus.getInt(TXLiveConstants.NET_STATUS_VIDEO_FPS) +
", ARA:" + netStatus.getInt(TXLiveConstants.NET_STATUS_AUDIO_BITRATE) + "Kbps" +
", VRA:" + netStatus.getInt(TXLiveConstants.NET_STATUS_VIDEO_BITRATE) + "Kbps");
//mLogInfoWindow.setLogText(netStatus, null, 0);
}
}
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);
}
@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();
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();
} else {
vv_view.stopPlayback();
vv_view.setVisibility(View.GONE);
mVideoView.setVisibility(View.VISIBLE);
mLivePlayer.startPlay(url);
}
}
}