直播视频流加载优化

yt_mpremote
liuguijing 2 months ago
parent f609c2012c
commit 8a68778555

@ -533,6 +533,8 @@ public class DeviceActivity extends AppCompatActivity implements View.OnClickLis
int orientation = jsonChannel.optInt("orientation", 0);
if (orientation > 0) {
rotation = (orientation - 1) * 90;
} else if (orientation == 0){
rotation = 90;
}
int cameraType = jsonChannel.optInt("cameraType", 0);
usb = (cameraType == 1) ? 1 : 0;

@ -5,14 +5,18 @@ import androidx.annotation.OptIn;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
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.Util;
import androidx.media3.datasource.rtmp.RtmpDataSource;
import androidx.media3.exoplayer.DefaultLoadControl;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
import androidx.media3.ui.PlayerView;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
@ -41,6 +45,7 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
// private PlayerView playerView;
private static final String TAG = "STRM";
private static final int MAX_RETRIES = 5;
private ExoPlayer exoPlayer;
private String mDeviceIp;
@ -53,15 +58,14 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
private int rotation;
private int netCamera;
private int vendor;
private PlayerView playerView;
private int retryCount;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityStreamBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
initHandler();
initIntent();
initView();
@ -106,7 +110,7 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
binding.toolbar.refresh.setVisibility(View.VISIBLE);
binding.toolbar.back.setOnClickListener(this);
binding.toolbar.refresh.setOnClickListener(this);
playerView = binding.playerView;
}
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() {
@Override
public void run() {
Dadb adb = null;
try {
Log.i(TAG, "Start connecting " + mDeviceIp);
adb = AdbManager.getAdb(mDeviceIp, AdbUtils.DEFAULT_ADB_PORT);
Log.i(TAG, "Finish connecting " + mDeviceIp);
if (adb == null) {
mHandler.postDelayed(new Runnable() {
@ -131,26 +132,22 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
}, 100);
return;
}
AdbShellResponse adbShellResponse = null;
try {
adbShellResponse = adb.shell("am force-stop com.xypower.mplive");
Thread.sleep(200);
} catch (Exception ex) {
ex.printStackTrace();
}
try {
adbShellResponse = adb.shell(cmd);
} catch (Exception ex) {
ex.printStackTrace();
}
if (adbShellResponse != null) {
if (adbShellResponse.getExitCode() == 0) {
try {
Thread.sleep(5000);
Thread.sleep(100);
} catch (Exception ex) {
}
runOnUiThread(runnable);
@ -159,7 +156,6 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
@ -206,26 +202,68 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
}
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();
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");
ProgressiveMediaSource videoSource = new ProgressiveMediaSource.Factory(new RtmpDataSource.Factory())
.createMediaSource(mediaItem);
exoPlayer.setMediaSource(videoSource);
exoPlayer.prepare();
exoPlayer.play();
exoPlayer.setPlayWhenReady(true);
}
@Override
protected void onDestroy() {
super.onDestroy();
stopStreaming();
}
@OptIn(markerClass = UnstableApi.class) @Override
@OptIn(markerClass = UnstableApi.class)
@Override
protected void onPause() {
super.onPause();
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() {
super.onStop();
if (Util.SDK_INT >= 24) {
@ -242,7 +281,10 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
}
private void releasePlayer() {
if (exoPlayer != null) {
exoPlayer.release();
exoPlayer = null;
}
}
@Override

Loading…
Cancel
Save