|
|
@ -5,14 +5,18 @@ import androidx.annotation.OptIn;
|
|
|
|
import androidx.appcompat.app.ActionBar;
|
|
|
|
import androidx.appcompat.app.ActionBar;
|
|
|
|
import androidx.appcompat.app.AppCompatActivity;
|
|
|
|
import androidx.appcompat.app.AppCompatActivity;
|
|
|
|
import androidx.media3.common.MediaItem;
|
|
|
|
import androidx.media3.common.MediaItem;
|
|
|
|
|
|
|
|
import androidx.media3.common.PlaybackException;
|
|
|
|
|
|
|
|
import androidx.media3.common.Player;
|
|
|
|
import androidx.media3.common.util.UnstableApi;
|
|
|
|
import androidx.media3.common.util.UnstableApi;
|
|
|
|
import androidx.media3.common.util.Util;
|
|
|
|
import androidx.media3.common.util.Util;
|
|
|
|
import androidx.media3.datasource.rtmp.RtmpDataSource;
|
|
|
|
import androidx.media3.datasource.rtmp.RtmpDataSource;
|
|
|
|
|
|
|
|
import androidx.media3.exoplayer.DefaultLoadControl;
|
|
|
|
import androidx.media3.exoplayer.ExoPlayer;
|
|
|
|
import androidx.media3.exoplayer.ExoPlayer;
|
|
|
|
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
|
|
|
|
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
|
|
|
|
import androidx.media3.ui.PlayerView;
|
|
|
|
import androidx.media3.ui.PlayerView;
|
|
|
|
|
|
|
|
|
|
|
|
import android.content.Intent;
|
|
|
|
import android.content.Intent;
|
|
|
|
|
|
|
|
import android.net.Uri;
|
|
|
|
import android.os.Bundle;
|
|
|
|
import android.os.Bundle;
|
|
|
|
import android.os.Environment;
|
|
|
|
import android.os.Environment;
|
|
|
|
import android.os.Handler;
|
|
|
|
import android.os.Handler;
|
|
|
@ -41,6 +45,7 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
|
|
|
|
|
|
|
|
// private PlayerView playerView;
|
|
|
|
// private PlayerView playerView;
|
|
|
|
private static final String TAG = "STRM";
|
|
|
|
private static final String TAG = "STRM";
|
|
|
|
|
|
|
|
private static final int MAX_RETRIES = 5;
|
|
|
|
|
|
|
|
|
|
|
|
private ExoPlayer exoPlayer;
|
|
|
|
private ExoPlayer exoPlayer;
|
|
|
|
private String mDeviceIp;
|
|
|
|
private String mDeviceIp;
|
|
|
@ -53,15 +58,14 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
private int rotation;
|
|
|
|
private int rotation;
|
|
|
|
private int netCamera;
|
|
|
|
private int netCamera;
|
|
|
|
private int vendor;
|
|
|
|
private int vendor;
|
|
|
|
|
|
|
|
private PlayerView playerView;
|
|
|
|
|
|
|
|
private int retryCount;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
binding = ActivityStreamBinding.inflate(getLayoutInflater());
|
|
|
|
binding = ActivityStreamBinding.inflate(getLayoutInflater());
|
|
|
|
setContentView(binding.getRoot());
|
|
|
|
setContentView(binding.getRoot());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
initHandler();
|
|
|
|
initHandler();
|
|
|
|
initIntent();
|
|
|
|
initIntent();
|
|
|
|
initView();
|
|
|
|
initView();
|
|
|
@ -106,7 +110,7 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
binding.toolbar.refresh.setVisibility(View.VISIBLE);
|
|
|
|
binding.toolbar.refresh.setVisibility(View.VISIBLE);
|
|
|
|
binding.toolbar.back.setOnClickListener(this);
|
|
|
|
binding.toolbar.back.setOnClickListener(this);
|
|
|
|
binding.toolbar.refresh.setOnClickListener(this);
|
|
|
|
binding.toolbar.refresh.setOnClickListener(this);
|
|
|
|
|
|
|
|
playerView = binding.playerView;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void startStreaming(final String cmd, final Runnable runnable) {
|
|
|
|
private void startStreaming(final String cmd, final Runnable runnable) {
|
|
|
@ -114,13 +118,10 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
Thread th = new Thread(new Runnable() {
|
|
|
|
Thread th = new Thread(new Runnable() {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
public void run() {
|
|
|
|
|
|
|
|
|
|
|
|
Dadb adb = null;
|
|
|
|
Dadb adb = null;
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
Log.i(TAG, "Start connecting " + mDeviceIp);
|
|
|
|
Log.i(TAG, "Start connecting " + mDeviceIp);
|
|
|
|
adb = AdbManager.getAdb(mDeviceIp, AdbUtils.DEFAULT_ADB_PORT);
|
|
|
|
adb = AdbManager.getAdb(mDeviceIp, AdbUtils.DEFAULT_ADB_PORT);
|
|
|
|
|
|
|
|
|
|
|
|
Log.i(TAG, "Finish connecting " + mDeviceIp);
|
|
|
|
Log.i(TAG, "Finish connecting " + mDeviceIp);
|
|
|
|
if (adb == null) {
|
|
|
|
if (adb == null) {
|
|
|
|
mHandler.postDelayed(new Runnable() {
|
|
|
|
mHandler.postDelayed(new Runnable() {
|
|
|
@ -131,26 +132,22 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
}, 100);
|
|
|
|
}, 100);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AdbShellResponse adbShellResponse = null;
|
|
|
|
AdbShellResponse adbShellResponse = null;
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
adbShellResponse = adb.shell("am force-stop com.xypower.mplive");
|
|
|
|
adbShellResponse = adb.shell("am force-stop com.xypower.mplive");
|
|
|
|
Thread.sleep(200);
|
|
|
|
Thread.sleep(200);
|
|
|
|
} catch (Exception ex) {
|
|
|
|
} catch (Exception ex) {
|
|
|
|
ex.printStackTrace();
|
|
|
|
ex.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
adbShellResponse = adb.shell(cmd);
|
|
|
|
adbShellResponse = adb.shell(cmd);
|
|
|
|
} catch (Exception ex) {
|
|
|
|
} catch (Exception ex) {
|
|
|
|
ex.printStackTrace();
|
|
|
|
ex.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (adbShellResponse != null) {
|
|
|
|
if (adbShellResponse != null) {
|
|
|
|
if (adbShellResponse.getExitCode() == 0) {
|
|
|
|
if (adbShellResponse.getExitCode() == 0) {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
Thread.sleep(5000);
|
|
|
|
Thread.sleep(100);
|
|
|
|
} catch (Exception ex) {
|
|
|
|
} catch (Exception ex) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
runOnUiThread(runnable);
|
|
|
|
runOnUiThread(runnable);
|
|
|
@ -159,7 +156,6 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
} catch (Exception ex) {
|
|
|
|
} catch (Exception ex) {
|
|
|
|
ex.printStackTrace();
|
|
|
|
ex.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
@ -206,26 +202,68 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void initializePlayer() {
|
|
|
|
private void initializePlayer() {
|
|
|
|
|
|
|
|
// // 创建重试策略
|
|
|
|
PlayerView playerView = findViewById(R.id.playerView);
|
|
|
|
// DefaultLoadControl loadControl = new DefaultLoadControl.Builder()
|
|
|
|
|
|
|
|
// .setBufferDurationsMs(
|
|
|
|
|
|
|
|
// 5000, // minBufferMs
|
|
|
|
|
|
|
|
// 10000, // maxBufferMs
|
|
|
|
|
|
|
|
// 500, // bufferForPlaybackMs
|
|
|
|
|
|
|
|
// 500 // bufferForPlaybackAfterRebufferMs
|
|
|
|
|
|
|
|
// ).build();
|
|
|
|
exoPlayer = new ExoPlayer.Builder(this).build();
|
|
|
|
exoPlayer = new ExoPlayer.Builder(this).build();
|
|
|
|
playerView.setPlayer(exoPlayer);
|
|
|
|
playerView.setPlayer(exoPlayer);
|
|
|
|
|
|
|
|
exoPlayer.addListener(new Player.Listener() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void onPlayerError(PlaybackException error) {
|
|
|
|
|
|
|
|
Log.e(TAG, "播放错误: " + error.getMessage());
|
|
|
|
|
|
|
|
handlePlaybackError();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void onPlaybackStateChanged(int state) {
|
|
|
|
|
|
|
|
if (state == Player.STATE_READY) {
|
|
|
|
|
|
|
|
// 重置重试计数器当成功连接时
|
|
|
|
|
|
|
|
retryCount = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
startPlayback();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void handlePlaybackError() {
|
|
|
|
|
|
|
|
if (retryCount < MAX_RETRIES) {
|
|
|
|
|
|
|
|
retryCount++;
|
|
|
|
|
|
|
|
Log.d(TAG, "准备重试 (" + retryCount + "/" + MAX_RETRIES + ")...");
|
|
|
|
|
|
|
|
mHandler.postDelayed(() -> {
|
|
|
|
|
|
|
|
if (exoPlayer != null) {
|
|
|
|
|
|
|
|
startPlayback();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}, 3000);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
Log.e(TAG, "达到最大重试次数,停止尝试");
|
|
|
|
|
|
|
|
// 这里可以添加UI提示或执行其他错误处理
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void startPlayback() {
|
|
|
|
|
|
|
|
if (exoPlayer == null) return;
|
|
|
|
|
|
|
|
Log.d(TAG, "开始播放,重试次数: " + retryCount);
|
|
|
|
MediaItem mediaItem = MediaItem.fromUri("rtmp://" + mDeviceIp + "/live/0");
|
|
|
|
MediaItem mediaItem = MediaItem.fromUri("rtmp://" + mDeviceIp + "/live/0");
|
|
|
|
ProgressiveMediaSource videoSource = new ProgressiveMediaSource.Factory(new RtmpDataSource.Factory())
|
|
|
|
ProgressiveMediaSource videoSource = new ProgressiveMediaSource.Factory(new RtmpDataSource.Factory())
|
|
|
|
.createMediaSource(mediaItem);
|
|
|
|
.createMediaSource(mediaItem);
|
|
|
|
exoPlayer.setMediaSource(videoSource);
|
|
|
|
exoPlayer.setMediaSource(videoSource);
|
|
|
|
exoPlayer.prepare();
|
|
|
|
exoPlayer.prepare();
|
|
|
|
exoPlayer.play();
|
|
|
|
exoPlayer.setPlayWhenReady(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
protected void onDestroy() {
|
|
|
|
protected void onDestroy() {
|
|
|
|
super.onDestroy();
|
|
|
|
super.onDestroy();
|
|
|
|
|
|
|
|
|
|
|
|
stopStreaming();
|
|
|
|
stopStreaming();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@OptIn(markerClass = UnstableApi.class) @Override
|
|
|
|
@OptIn(markerClass = UnstableApi.class)
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPause() {
|
|
|
|
protected void onPause() {
|
|
|
|
super.onPause();
|
|
|
|
super.onPause();
|
|
|
|
if (Util.SDK_INT < 24) {
|
|
|
|
if (Util.SDK_INT < 24) {
|
|
|
@ -233,7 +271,8 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@OptIn(markerClass = UnstableApi.class) @Override
|
|
|
|
@OptIn(markerClass = UnstableApi.class)
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onStop() {
|
|
|
|
protected void onStop() {
|
|
|
|
super.onStop();
|
|
|
|
super.onStop();
|
|
|
|
if (Util.SDK_INT >= 24) {
|
|
|
|
if (Util.SDK_INT >= 24) {
|
|
|
@ -242,7 +281,10 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void releasePlayer() {
|
|
|
|
private void releasePlayer() {
|
|
|
|
|
|
|
|
if (exoPlayer != null) {
|
|
|
|
exoPlayer.release();
|
|
|
|
exoPlayer.release();
|
|
|
|
|
|
|
|
exoPlayer = null;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|