fix: 优化画质和帧数上限

This commit is contained in:
2026-07-15 17:49:55 +08:00
parent da1730ce19
commit 97ef11a025
2 changed files with 24 additions and 9 deletions

View File

@@ -117,7 +117,9 @@ public class ScreenCaptureService extends Service {
} catch (Exception ignored) {} } catch (Exception ignored) {}
} }
int fps = Math.round(refreshRate); int fps = Math.round(refreshRate);
if (fps > 60) fps = 60; // 限制最大 60fps // 屏幕控制 30fps 已足够跟手,并显著降低 H264 硬编延迟(影响“跟手”体验)。
// 更高的帧率会加重编码缓冲与带宽压力,得不偿失。
if (fps > 30) fps = 30;
if (fps <= 0) fps = 30; if (fps <= 0) fps = 30;
Log.i(TAG, "Real resolution: " + realWidth + "x" + realHeight); Log.i(TAG, "Real resolution: " + realWidth + "x" + realHeight);

View File

@@ -39,6 +39,13 @@ public class WebRtcClient {
private static final String STREAM_ID = "screen_stream"; private static final String STREAM_ID = "screen_stream";
private static final String DATA_CHANNEL_LABEL = "control_channel"; private static final String DATA_CHANNEL_LABEL = "control_channel";
// 码率优化参数(单位 kbps。屏幕内容文字/边缘多)对码率敏感,
// 过低的下限会产生色块。提高下限可显著改善画质;
// 若被控端上行带宽较弱(如蜂窝网络),请适当下调 MIN_BITRATE_KBPS。
private static final int MIN_BITRATE_KBPS = 5000; // 带宽估计下限,不低于此值
private static final int START_BITRATE_KBPS = 12000; // 连接初始码率猜测
private static final int MAX_BITRATE_KBPS = 40000; // 带宽估计上限
private final Context context; private final Context context;
private final WebSocketClient wsClient; private final WebSocketClient wsClient;
private final String deviceId; private final String deviceId;
@@ -76,7 +83,7 @@ public class WebRtcClient {
this.eglBase = eglBase; this.eglBase = eglBase;
PeerConnectionFactory.InitializationOptions initOptions = PeerConnectionFactory.InitializationOptions initOptions =
PeerConnectionFactory.InitializationOptions.builder(context) PeerConnectionFactory.InitializationOptions.builder(context)
.setFieldTrials("WebRTC-H264HighProfile/Enabled/WebRTC-Video-HwAcceleration/Enabled/") .setFieldTrials("WebRTC-H264HighProfile/Enabled/WebRTC-Video-HwAcceleration/Enabled/WebRTC-FlexFEC-03/Enabled/")
.createInitializationOptions(); .createInitializationOptions();
PeerConnectionFactory.initialize(initOptions); PeerConnectionFactory.initialize(initOptions);
@@ -188,11 +195,11 @@ public class WebRtcClient {
peerConnection.addTrack(videoTrack, Collections.singletonList(STREAM_ID)); peerConnection.addTrack(videoTrack, Collections.singletonList(STREAM_ID));
} }
// 创建本地 DataChannel // 注意:DataChannel 由控制端Offer 方)创建并协商,
DataChannel.Init dcInit = new DataChannel.Init(); // 本端通过 PeerObserver.onDataChannel 回调接收(见下方注册),
dcInit.ordered = true; // 无需(也不应)再创建同名通道,否则会与控制端通道冲突。
dataChannel = peerConnection.createDataChannel(DATA_CHANNEL_LABEL, dcInit); // 控制端创建时已使用 ordered=false + maxRetransmits=0无序无重传
handleDataChannel(dataChannel); // 因此本端收到的所有指令均为最低延迟模式,无需额外配置。
// 设置远端 SDP (Offer) // 设置远端 SDP (Offer)
SessionDescription remoteSdp = new SessionDescription(SessionDescription.Type.OFFER, offerSdp); SessionDescription remoteSdp = new SessionDescription(SessionDescription.Type.OFFER, offerSdp);
@@ -302,6 +309,8 @@ public class WebRtcClient {
} }
private void handleDataChannel(DataChannel dc) { private void handleDataChannel(DataChannel dc) {
// 保存控制端建立的通道引用(替代原先本端自建的通道)。
this.dataChannel = dc;
dc.registerObserver(new DataChannel.Observer() { dc.registerObserver(new DataChannel.Observer() {
@Override @Override
public void onBufferedAmountChange(long previousAmount) { public void onBufferedAmountChange(long previousAmount) {
@@ -375,8 +384,12 @@ public class WebRtcClient {
} }
} }
if (isH264) { if (isH264) {
// 为 H264 注入码率优化参数 // 为 H264 注入码率优化参数
String bonus = ";x-google-start-bitrate=5000;x-google-max-bitrate=50000;x-google-min-bitrate=2000"; // 屏幕内容(文字/边缘)对码率敏感,过低的下限会产生色块;
// 提高下限可显著改善画质。若被控端上行带宽较弱,请适当下调 MIN。
String bonus = ";x-google-start-bitrate=" + START_BITRATE_KBPS
+ ";x-google-max-bitrate=" + MAX_BITRATE_KBPS
+ ";x-google-min-bitrate=" + MIN_BITRATE_KBPS;
if (!trimmedLine.contains("x-google-start-bitrate")) { if (!trimmedLine.contains("x-google-start-bitrate")) {
newSdp.append(trimmedLine).append(bonus).append("\r\n"); newSdp.append(trimmedLine).append(bonus).append("\r\n");
} else { } else {