feat: 支持手动切换采集帧率
在 Android、Web 及 Flutter 控制端新增帧率选择 UI,被控端按屏幕刷新率生成支持的帧率档位并上报,允许在保持分辨率不变的情况下仅切换帧率。 另附带更新信号服务器的数据库配置。
This commit is contained in:
@@ -48,4 +48,9 @@ message ControlMessage {
|
||||
int32 width = 12;
|
||||
int32 height = 13;
|
||||
int32 fps = 14;
|
||||
|
||||
// 15 预留给 Android 端的 stream_mode(Web 端暂未使用,编号保持对齐)。
|
||||
|
||||
// 被控端支持的帧率档位列表(REPORT_RESOLUTION 上报,按屏幕刷新率筛选,升序)。
|
||||
repeated int32 supported_fps = 16;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,10 @@ const resolutionPresets = [
|
||||
// 因此这里也必须用数字(不能用字符串 '0'),否则默认选中项与比较逻辑会类型不一致。
|
||||
const selectedResolution = ref(0);
|
||||
|
||||
// 帧率档位:默认常用档位,收到被控端上报的 supported_fps 后以上报列表为准。
|
||||
const fpsOptions = ref([15, 24, 30, 60]);
|
||||
const selectedFps = ref(0); // 0 表示尚未同步到被控端当前帧率
|
||||
|
||||
function press(code) {
|
||||
if (!store.dataChannelOpen) return;
|
||||
sendKey(code);
|
||||
@@ -39,12 +43,29 @@ function onResolutionChange() {
|
||||
}
|
||||
}
|
||||
|
||||
// 被控端上报当前实际采集分辨率时,把下拉框同步到对应预设(避免 UI 与实际不一致)。
|
||||
function onFpsChange() {
|
||||
if (!store.dataChannelOpen) return;
|
||||
const fps = Number(selectedFps.value);
|
||||
if (fps <= 0) return;
|
||||
// 仅切换帧率:分辨率沿用被控端最近上报的实际采集尺寸(0 表示原生)。
|
||||
const res = store.currentResolution;
|
||||
sendResolutionChange(res ? res.width : 0, res ? res.height : 0, fps);
|
||||
}
|
||||
|
||||
// 被控端上报当前实际采集分辨率/帧率时,同步下拉框(避免 UI 与实际不一致)。
|
||||
watch(() => store.currentResolution, (res) => {
|
||||
if (!res) return;
|
||||
const longEdge = Math.max(res.width, res.height);
|
||||
const preset = resolutionPresets.find((p) => p.width === longEdge);
|
||||
if (preset) selectedResolution.value = preset.width;
|
||||
|
||||
// 帧率档位以被控端上报为准(按屏幕刷新率筛选)
|
||||
if (Array.isArray(res.supportedFps) && res.supportedFps.length > 0) {
|
||||
fpsOptions.value = res.supportedFps;
|
||||
}
|
||||
if (res.fps > 0 && fpsOptions.value.includes(res.fps)) {
|
||||
selectedFps.value = res.fps;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -62,8 +83,19 @@ watch(() => store.currentResolution, (res) => {
|
||||
{{ p.label }}
|
||||
</option>
|
||||
</select>
|
||||
<label class="resolution-label">帧率:</label>
|
||||
<select
|
||||
class="resolution-select"
|
||||
v-model="selectedFps"
|
||||
:disabled="!store.dataChannelOpen"
|
||||
@change="onFpsChange"
|
||||
>
|
||||
<option v-if="selectedFps === 0" :value="0" disabled>--</option>
|
||||
<option v-for="f in fpsOptions" :key="f" :value="f">{{ f }}fps</option>
|
||||
</select>
|
||||
|
||||
<span class="resolution-current" v-if="store.currentResolution">
|
||||
当前: {{ store.currentResolution.width }}×{{ store.currentResolution.height }}
|
||||
当前: {{ store.currentResolution.width }}×{{ store.currentResolution.height }}@{{ store.currentResolution.fps }}fps
|
||||
</span>
|
||||
|
||||
<span class="record-sep"></span>
|
||||
|
||||
@@ -167,6 +167,8 @@ export class WebRtcController {
|
||||
width: msg.width | 0,
|
||||
height: msg.height | 0,
|
||||
fps: msg.fps | 0,
|
||||
// 被控端按屏幕刷新率筛选出的帧率档位(供帧率下拉框使用)
|
||||
supportedFps: Array.isArray(msg.supportedFps) ? msg.supportedFps.map((f) => f | 0) : [],
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user