feat(streaming): 添加自编码串流模式切换功能
This commit is contained in:
@@ -16,6 +16,10 @@ import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.Switch;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.SurfaceHolder;
|
||||
import com.ttstd.controller.webrtc.SelfCodecDecoder;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -58,6 +62,14 @@ public class MainActivity extends AppCompatActivity {
|
||||
private TextView tvStats;
|
||||
private Spinner spinnerResolution;
|
||||
|
||||
// 屏幕串流"自编码"模式相关 UI 与解码器
|
||||
private Switch switchStreamMode;
|
||||
private TextView tvStreamMode;
|
||||
private SurfaceView selfCodecSurface;
|
||||
private SelfCodecDecoder selfCodecDecoder;
|
||||
private SurfaceHolder.Callback surfaceCallback;
|
||||
private boolean programmaticSwitch = false;
|
||||
|
||||
private WebSocketClient wsClient;
|
||||
private WebRtcClient webRtcClient;
|
||||
private EglBase eglBase;
|
||||
@@ -162,6 +174,8 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
setupResolutionSpinner();
|
||||
updateUI(false);
|
||||
|
||||
setupSelfCodecUi();
|
||||
}
|
||||
|
||||
private void adjustVideoSize(int videoWidth, int videoHeight, int rotation) {
|
||||
@@ -309,6 +323,8 @@ public class MainActivity extends AppCompatActivity {
|
||||
private void initWebRtcAndConnect() {
|
||||
webRtcClient = new WebRtcClient(this, wsClient, myDeviceId);
|
||||
webRtcClient.initialize(eglBase);
|
||||
webRtcClient.setSelfCodecDecoder(selfCodecDecoder);
|
||||
webRtcClient.setStreamModeReportListener(mode -> runOnUiThread(() -> syncStreamModeUi(mode)));
|
||||
webRtcClient.setConnectionListener(new WebRtcClient.ConnectionListener() {
|
||||
@Override
|
||||
public void onConnectionEstablished() {
|
||||
@@ -598,8 +614,83 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
if (connected) {
|
||||
statsHandler.post(statsRunnable);
|
||||
if (switchStreamMode != null) switchStreamMode.setEnabled(true);
|
||||
} else {
|
||||
statsHandler.removeCallbacks(statsRunnable);
|
||||
if (switchStreamMode != null) {
|
||||
switchStreamMode.setEnabled(false);
|
||||
programmaticSwitch = true;
|
||||
switchStreamMode.setChecked(false);
|
||||
programmaticSwitch = false;
|
||||
}
|
||||
if (tvStreamMode != null) tvStreamMode.setText("串流: WebRTC");
|
||||
if (selfCodecDecoder != null) selfCodecDecoder.release();
|
||||
}
|
||||
}
|
||||
|
||||
/** 初始化"自编码"串流模式的 UI 与解码器。 */
|
||||
private void setupSelfCodecUi() {
|
||||
switchStreamMode = findViewById(R.id.switch_stream_mode);
|
||||
tvStreamMode = findViewById(R.id.tv_stream_mode);
|
||||
selfCodecSurface = findViewById(R.id.self_codec_surface);
|
||||
selfCodecDecoder = new SelfCodecDecoder();
|
||||
surfaceCallback = new SurfaceHolder.Callback() {
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
if (selfCodecDecoder != null) {
|
||||
selfCodecDecoder.setSurface(holder.getSurface());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
}
|
||||
};
|
||||
selfCodecSurface.getHolder().addCallback(surfaceCallback);
|
||||
switchStreamMode.setEnabled(false);
|
||||
switchStreamMode.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
if (programmaticSwitch) return;
|
||||
applyStreamMode(isChecked);
|
||||
});
|
||||
}
|
||||
|
||||
/** 用户切换串流模式:发送信令并切换本地视图。 */
|
||||
private void applyStreamMode(boolean self) {
|
||||
if (webRtcClient != null && webRtcClient.isDataChannelOpen()) {
|
||||
webRtcClient.sendStreamMode(self ? WebRtcClient.STREAM_MODE_SELF_CODEC
|
||||
: WebRtcClient.STREAM_MODE_WEBRTC);
|
||||
}
|
||||
tvStreamMode.setText(self ? "串流: 自编码" : "串流: WebRTC");
|
||||
if (self) {
|
||||
selfCodecSurface.setVisibility(View.VISIBLE);
|
||||
remoteVideoView.setVisibility(View.GONE);
|
||||
selfCodecDecoder.setEnabled(true);
|
||||
} else {
|
||||
selfCodecSurface.setVisibility(View.GONE);
|
||||
remoteVideoView.setVisibility(View.VISIBLE);
|
||||
selfCodecDecoder.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
/** 收到被控端回报的当前模式:同步 UI 与视图(防止切换失败不一致)。 */
|
||||
private void syncStreamModeUi(int mode) {
|
||||
boolean self = (mode == WebRtcClient.STREAM_MODE_SELF_CODEC);
|
||||
programmaticSwitch = true;
|
||||
switchStreamMode.setChecked(self);
|
||||
programmaticSwitch = false;
|
||||
tvStreamMode.setText(self ? "串流: 自编码" : "串流: WebRTC");
|
||||
if (self) {
|
||||
selfCodecSurface.setVisibility(View.VISIBLE);
|
||||
remoteVideoView.setVisibility(View.GONE);
|
||||
selfCodecDecoder.setEnabled(true);
|
||||
} else {
|
||||
selfCodecSurface.setVisibility(View.GONE);
|
||||
remoteVideoView.setVisibility(View.VISIBLE);
|
||||
selfCodecDecoder.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user