|
|
@ -14,34 +14,27 @@ 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.app.AlertDialog;
|
|
|
|
import android.content.Intent;
|
|
|
|
import android.content.Intent;
|
|
|
|
import android.net.Uri;
|
|
|
|
|
|
|
|
import android.os.Bundle;
|
|
|
|
import android.os.Bundle;
|
|
|
|
import android.os.Handler;
|
|
|
|
import android.os.Handler;
|
|
|
|
import android.util.Log;
|
|
|
|
import android.util.Log;
|
|
|
|
import android.view.Menu;
|
|
|
|
import android.view.Menu;
|
|
|
|
import android.view.MenuItem;
|
|
|
|
import android.view.MenuItem;
|
|
|
|
import android.view.Surface;
|
|
|
|
|
|
|
|
import android.view.SurfaceHolder;
|
|
|
|
|
|
|
|
import android.view.SurfaceView;
|
|
|
|
|
|
|
|
import android.view.View;
|
|
|
|
import android.view.View;
|
|
|
|
import android.widget.Toast;
|
|
|
|
import android.widget.Toast;
|
|
|
|
|
|
|
|
|
|
|
|
import com.xypower.mpremote.databinding.ActivityStreamBinding;
|
|
|
|
import com.xypower.mpremote.databinding.ActivityStreamBinding;
|
|
|
|
import com.xypower.mpremote.utils.AdbUtils;
|
|
|
|
import com.xypower.mpremote.utils.AdbUtils;
|
|
|
|
|
|
|
|
import com.xypower.mpremote.utils.AlertDialogUtils;
|
|
|
|
|
|
|
|
|
|
|
|
import org.videolan.libvlc.LibVLC;
|
|
|
|
|
|
|
|
import org.videolan.libvlc.Media;
|
|
|
|
|
|
|
|
import org.videolan.libvlc.MediaPlayer;
|
|
|
|
import org.videolan.libvlc.MediaPlayer;
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import dadb.AdbShellResponse;
|
|
|
|
import dadb.AdbShellResponse;
|
|
|
|
import dadb.Dadb;
|
|
|
|
import dadb.Dadb;
|
|
|
|
|
|
|
|
|
|
|
|
public class StreamActivity extends AppCompatActivity implements View.OnClickListener {
|
|
|
|
public class StreamActivity extends AppCompatActivity implements View.OnClickListener {
|
|
|
|
|
|
|
|
|
|
|
|
// private PlayerView playerView;
|
|
|
|
|
|
|
|
private static final String TAG = "STRM";
|
|
|
|
private static final String TAG = "STRM";
|
|
|
|
private static final int MAX_RETRIES = 5;
|
|
|
|
private static final int MAX_RETRIES = 5;
|
|
|
|
|
|
|
|
|
|
|
@ -65,9 +58,8 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
private long bufferingStartTime = 0;
|
|
|
|
private long bufferingStartTime = 0;
|
|
|
|
private static final long BUFFERING_TIMEOUT_MS = 10000; // 10秒缓冲超时
|
|
|
|
private static final long BUFFERING_TIMEOUT_MS = 10000; // 10秒缓冲超时
|
|
|
|
private String RTMP_URL;
|
|
|
|
private String RTMP_URL;
|
|
|
|
private SurfaceView playerView;
|
|
|
|
private PlayerView playerView;
|
|
|
|
private MediaPlayer mediaPlayer;
|
|
|
|
private AlertDialog alertDialog;
|
|
|
|
private LibVLC libVLC;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
|
@ -82,37 +74,19 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
|
|
|
|
|
|
|
|
private void initEvent() {
|
|
|
|
private void initEvent() {
|
|
|
|
RTMP_URL = "rtmp://" + mDeviceIp + "/live/0";
|
|
|
|
RTMP_URL = "rtmp://" + mDeviceIp + "/live/0";
|
|
|
|
|
|
|
|
String cmd = "am start -n com.xypower.mplive/com.xypower.mplive.MainActivity" + " --ei cameraId " + Integer.toString(cameraId) + " --ei rotation " + Integer.toString(rotation) + " --ei netCamera " + Integer.toString(netCamera) + " --ei vendor " + Integer.toString(vendor) + " --ei autoStart 1" + " --es url \"" + RTMP_URL + "\"";
|
|
|
|
String cmd = "am start -n com.xypower.mplive/com.xypower.mplive.MainActivity"
|
|
|
|
|
|
|
|
+ " --ei cameraId " + Integer.toString(cameraId)
|
|
|
|
|
|
|
|
+ " --ei rotation " + Integer.toString(rotation)
|
|
|
|
|
|
|
|
+ " --ei netCamera " + Integer.toString(netCamera)
|
|
|
|
|
|
|
|
+ " --ei vendor " + Integer.toString(vendor)
|
|
|
|
|
|
|
|
+ " --ei autoStart 1"
|
|
|
|
|
|
|
|
+ " --es url \"" + RTMP_URL + "\"";
|
|
|
|
|
|
|
|
Runnable runnable = new Runnable() {
|
|
|
|
Runnable runnable = new Runnable() {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
public void run() {
|
|
|
|
initializePlayer();
|
|
|
|
initializePlayer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
alertDialog = AlertDialogUtils.show(this, "视频加载中");
|
|
|
|
startStreaming(cmd, runnable);
|
|
|
|
startStreaming(cmd, runnable);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void initHandler() {
|
|
|
|
private void initHandler() {
|
|
|
|
// mHandler = new Handler();
|
|
|
|
// mHandler = new Handler();
|
|
|
|
|
|
|
|
|
|
|
|
// 配置 VLC 参数
|
|
|
|
|
|
|
|
ArrayList<String> options = new ArrayList<>();
|
|
|
|
|
|
|
|
options.add("--aout=opensles"); // 优化音频延迟:ml-citation{ref="6" data="citationList"}
|
|
|
|
|
|
|
|
options.add("--audio-time-stretch");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
libVLC = new LibVLC(this, options);
|
|
|
|
|
|
|
|
mediaPlayer = new MediaPlayer(libVLC);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void initIntent() {
|
|
|
|
private void initIntent() {
|
|
|
@ -131,29 +105,9 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
binding.toolbar.back.setOnClickListener(this);
|
|
|
|
binding.toolbar.back.setOnClickListener(this);
|
|
|
|
binding.toolbar.refresh.setOnClickListener(this);
|
|
|
|
binding.toolbar.refresh.setOnClickListener(this);
|
|
|
|
playerView = binding.playerView;
|
|
|
|
playerView = binding.playerView;
|
|
|
|
SurfaceHolder holder = playerView.getHolder();
|
|
|
|
|
|
|
|
holder.addCallback(new SurfaceHolder.Callback() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void surfaceCreated(SurfaceHolder holder) {
|
|
|
|
|
|
|
|
Surface surface = holder.getSurface();
|
|
|
|
|
|
|
|
mediaPlayer.getVLCVout().setVideoSurface(surface,holder);
|
|
|
|
|
|
|
|
mediaPlayer.getVLCVout().attachViews(); // 绑定视图:ml-citation{ref="8" data="citationList"}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void startStreaming(final String cmd, final Runnable runnable) {
|
|
|
|
private void startStreaming(final String cmd, final Runnable runnable) {
|
|
|
|
Log.d(TAG, cmd);
|
|
|
|
|
|
|
|
Thread th = new Thread(new Runnable() {
|
|
|
|
Thread th = new Thread(new Runnable() {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
public void run() {
|
|
|
@ -197,12 +151,10 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
th.start();
|
|
|
|
th.start();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void stopStreaming() {
|
|
|
|
private void stopStreaming() {
|
|
|
|
// String cmd = "am start -n com.xypower.mplive/com.xypower.mplive.MainActivity --ei autoClose 1";
|
|
|
|
|
|
|
|
String cmd = "am force-stop com.xypower.mplive";
|
|
|
|
String cmd = "am force-stop com.xypower.mplive";
|
|
|
|
Thread th = new Thread(new Runnable() {
|
|
|
|
Thread th = new Thread(new Runnable() {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
@ -240,107 +192,42 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
th.start();
|
|
|
|
th.start();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void initializePlayer2() {
|
|
|
|
private void initializePlayer() {
|
|
|
|
// // 创建重试策略
|
|
|
|
if (player == null) {
|
|
|
|
// DefaultLoadControl loadControl = new DefaultLoadControl.Builder()
|
|
|
|
player = new ExoPlayer.Builder(this).setLoadControl(new DefaultLoadControl.Builder().setBufferDurationsMs(5000, // minBufferMs
|
|
|
|
// .setBufferDurationsMs(
|
|
|
|
10000, // maxBufferMs
|
|
|
|
// 5000, // minBufferMs
|
|
|
|
500, // bufferForPlaybackMs
|
|
|
|
// 10000, // maxBufferMs
|
|
|
|
500 // bufferForPlaybackAfterRebufferMs
|
|
|
|
// 500, // bufferForPlaybackMs
|
|
|
|
).setPrioritizeTimeOverSizeThresholds(true).build()).build();
|
|
|
|
// 500 // bufferForPlaybackAfterRebufferMs
|
|
|
|
playerView.setPlayer(player);
|
|
|
|
// ).build();
|
|
|
|
player.addListener(new Player.Listener() {
|
|
|
|
// player = new ExoPlayer.Builder(this).build();
|
|
|
|
@Override
|
|
|
|
// playerView.setPlayer(player);
|
|
|
|
public void onPlayerError(PlaybackException error) {
|
|
|
|
// player.addListener(new Player.Listener() {
|
|
|
|
Log.e(TAG, "播放错误: " + error.getMessage());
|
|
|
|
// @Override
|
|
|
|
handlePlaybackError();
|
|
|
|
// 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 handlePlaybackError2() {
|
|
|
|
|
|
|
|
// if (retryCount < MAX_RETRIES) {
|
|
|
|
|
|
|
|
// retryCount++;
|
|
|
|
|
|
|
|
// Log.d(TAG, "准备重试 (" + retryCount + "/" + MAX_RETRIES + ")...");
|
|
|
|
|
|
|
|
// mHandler.postDelayed(() -> {
|
|
|
|
|
|
|
|
// if (player != null) {
|
|
|
|
|
|
|
|
// startPlayback();
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }, 3000);
|
|
|
|
|
|
|
|
// } else {
|
|
|
|
|
|
|
|
// Log.e(TAG, "达到最大重试次数,停止尝试");
|
|
|
|
|
|
|
|
// // 这里可以添加UI提示或执行其他错误处理
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void startPlayback2() {
|
|
|
|
|
|
|
|
if (player == null) return;
|
|
|
|
|
|
|
|
Log.d(TAG, "开始播放,重试次数: " + retryCount);
|
|
|
|
|
|
|
|
MediaItem mediaItem = MediaItem.fromUri("rtmp://" + mDeviceIp + "/live/0");
|
|
|
|
|
|
|
|
ProgressiveMediaSource videoSource = new ProgressiveMediaSource.Factory(new RtmpDataSource.Factory())
|
|
|
|
|
|
|
|
.createMediaSource(mediaItem);
|
|
|
|
|
|
|
|
player.setMediaSource(videoSource);
|
|
|
|
|
|
|
|
player.prepare();
|
|
|
|
|
|
|
|
player.setPlayWhenReady(true);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
private void initializePlayer() {
|
|
|
|
public void onPlaybackStateChanged(int state) {
|
|
|
|
// if (player == null) {
|
|
|
|
if (state == Player.STATE_BUFFERING) {
|
|
|
|
// player = new ExoPlayer.Builder(this)
|
|
|
|
if (!isBuffering) {
|
|
|
|
// .setLoadControl(new DefaultLoadControl.Builder()
|
|
|
|
isBuffering = true;
|
|
|
|
// .setBufferDurationsMs(
|
|
|
|
bufferingStartTime = System.currentTimeMillis();
|
|
|
|
// 5000, // minBufferMs
|
|
|
|
// 启动缓冲超时检查
|
|
|
|
// 10000, // maxBufferMs
|
|
|
|
retryHandler.postDelayed(bufferingTimeoutRunnable, BUFFERING_TIMEOUT_MS);
|
|
|
|
// 500, // bufferForPlaybackMs
|
|
|
|
}
|
|
|
|
// 500 // bufferForPlaybackAfterRebufferMs
|
|
|
|
} else if (state == Player.STATE_READY) {
|
|
|
|
// ).setPrioritizeTimeOverSizeThresholds(true)
|
|
|
|
AlertDialogUtils.dismiss(alertDialog);
|
|
|
|
// .build())
|
|
|
|
isBuffering = false;
|
|
|
|
// .build();
|
|
|
|
retryHandler.removeCallbacks(bufferingTimeoutRunnable);
|
|
|
|
//
|
|
|
|
retryCount = 0;
|
|
|
|
//// playerView.setPlayer(player);
|
|
|
|
currentRetryDelay = INITIAL_RETRY_DELAY_MS;
|
|
|
|
//
|
|
|
|
Log.d(TAG, "播放器准备就绪");
|
|
|
|
// player.addListener(new Player.Listener() {
|
|
|
|
}
|
|
|
|
// @Override
|
|
|
|
}
|
|
|
|
// public void onPlayerError(PlaybackException error) {
|
|
|
|
});
|
|
|
|
// Log.e(TAG, "播放错误: " + error.getMessage());
|
|
|
|
}
|
|
|
|
// handlePlaybackError();
|
|
|
|
startPlayback();
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// @Override
|
|
|
|
|
|
|
|
// public void onPlaybackStateChanged(int state) {
|
|
|
|
|
|
|
|
// if (state == Player.STATE_BUFFERING) {
|
|
|
|
|
|
|
|
// if (!isBuffering) {
|
|
|
|
|
|
|
|
// isBuffering = true;
|
|
|
|
|
|
|
|
// bufferingStartTime = System.currentTimeMillis();
|
|
|
|
|
|
|
|
// // 启动缓冲超时检查
|
|
|
|
|
|
|
|
// retryHandler.postDelayed(bufferingTimeoutRunnable, BUFFERING_TIMEOUT_MS);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// } else if (state == Player.STATE_READY) {
|
|
|
|
|
|
|
|
// isBuffering = false;
|
|
|
|
|
|
|
|
// retryHandler.removeCallbacks(bufferingTimeoutRunnable);
|
|
|
|
|
|
|
|
// retryCount = 0;
|
|
|
|
|
|
|
|
// currentRetryDelay = INITIAL_RETRY_DELAY_MS;
|
|
|
|
|
|
|
|
// Log.d(TAG, "播放器准备就绪");
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// startPlayback();
|
|
|
|
|
|
|
|
Media media = new Media(libVLC, Uri.parse(RTMP_URL));
|
|
|
|
|
|
|
|
mediaPlayer.setMedia(media);
|
|
|
|
|
|
|
|
mediaPlayer.play();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -356,13 +243,9 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
|
|
|
|
|
|
|
|
private void startPlayback() {
|
|
|
|
private void startPlayback() {
|
|
|
|
if (player == null) return;
|
|
|
|
if (player == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
Log.d(TAG, "开始播放,重试次数: " + retryCount);
|
|
|
|
Log.d(TAG, "开始播放,重试次数: " + retryCount);
|
|
|
|
// MediaItem mediaItem = MediaItem.fromUri(Uri.parse(RTMP_URL));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MediaItem mediaItem = MediaItem.fromUri(RTMP_URL);
|
|
|
|
MediaItem mediaItem = MediaItem.fromUri(RTMP_URL);
|
|
|
|
ProgressiveMediaSource videoSource = new ProgressiveMediaSource.Factory(new RtmpDataSource.Factory())
|
|
|
|
ProgressiveMediaSource videoSource = new ProgressiveMediaSource.Factory(new RtmpDataSource.Factory()).createMediaSource(mediaItem);
|
|
|
|
.createMediaSource(mediaItem);
|
|
|
|
|
|
|
|
player.setMediaSource(videoSource);
|
|
|
|
player.setMediaSource(videoSource);
|
|
|
|
// player.setMediaItem(mediaItem);
|
|
|
|
// player.setMediaItem(mediaItem);
|
|
|
|
player.prepare();
|
|
|
|
player.prepare();
|
|
|
@ -371,15 +254,13 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
|
|
|
|
|
|
|
|
private void handlePlaybackError() {
|
|
|
|
private void handlePlaybackError() {
|
|
|
|
releasePlayerInternal();
|
|
|
|
releasePlayerInternal();
|
|
|
|
|
|
|
|
|
|
|
|
if (retryCount < MAX_RETRIES) {
|
|
|
|
if (retryCount < MAX_RETRIES) {
|
|
|
|
retryCount++;
|
|
|
|
retryCount++;
|
|
|
|
Log.d(TAG, "准备重试 (" + retryCount + "), 延迟: " + currentRetryDelay + "ms");
|
|
|
|
Log.d(TAG, "准备重试 (" + retryCount + "), 延迟: " + currentRetryDelay + "ms");
|
|
|
|
|
|
|
|
|
|
|
|
retryHandler.postDelayed(() -> {
|
|
|
|
retryHandler.postDelayed(() -> {
|
|
|
|
initializePlayer();
|
|
|
|
initializePlayer();
|
|
|
|
// 增加下次重试的延迟时间(使用退避算法)
|
|
|
|
// 增加下次重试的延迟时间(使用退避算法)
|
|
|
|
currentRetryDelay = Math.min((long)(currentRetryDelay * RETRY_BACKOFF_MULTIPLIER), MAX_RETRY_DELAY_MS);
|
|
|
|
currentRetryDelay = Math.min((long) (currentRetryDelay * RETRY_BACKOFF_MULTIPLIER), MAX_RETRY_DELAY_MS);
|
|
|
|
}, currentRetryDelay);
|
|
|
|
}, currentRetryDelay);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -394,12 +275,11 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
protected void onDestroy() {
|
|
|
|
protected void onDestroy() {
|
|
|
|
super.onDestroy();
|
|
|
|
super.onDestroy();
|
|
|
|
|
|
|
|
AlertDialogUtils.dismiss(alertDialog);
|
|
|
|
|
|
|
|
releasePlayerInternal();
|
|
|
|
stopStreaming();
|
|
|
|
stopStreaming();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -408,7 +288,7 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
protected void onPause() {
|
|
|
|
protected void onPause() {
|
|
|
|
super.onPause();
|
|
|
|
super.onPause();
|
|
|
|
if (Util.SDK_INT < 24) {
|
|
|
|
if (Util.SDK_INT < 24) {
|
|
|
|
releasePlayer();
|
|
|
|
releasePlayerInternal();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -417,16 +297,10 @@ public class StreamActivity extends AppCompatActivity implements View.OnClickLis
|
|
|
|
protected void onStop() {
|
|
|
|
protected void onStop() {
|
|
|
|
super.onStop();
|
|
|
|
super.onStop();
|
|
|
|
if (Util.SDK_INT >= 24) {
|
|
|
|
if (Util.SDK_INT >= 24) {
|
|
|
|
releasePlayer();
|
|
|
|
releasePlayerInternal();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void releasePlayer() {
|
|
|
|
|
|
|
|
if (player != null) {
|
|
|
|
|
|
|
|
player.release();
|
|
|
|
|
|
|
|
player = null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public boolean onCreateOptionsMenu(Menu menu) {
|
|
|
|
public boolean onCreateOptionsMenu(Menu menu) {
|
|
|
|