feat: 支持手动切换采集帧率

在 Android、Web 及 Flutter 控制端新增帧率选择 UI,被控端按屏幕刷新率生成支持的帧率档位并上报,允许在保持分辨率不变的情况下仅切换帧率。

另附带更新信号服务器的数据库配置。
This commit is contained in:
TongTongStudio
2026-07-31 03:26:40 +08:00
parent c3602493dd
commit 362b9f238a
23 changed files with 483 additions and 13 deletions

View File

@@ -56,6 +56,10 @@ final class ControllerViewModel: NSObject, ObservableObject {
@Published var statsText: String = ""
@Published var streamMode: StreamMode = .webrtc
@Published var selectedResolution: ResolutionOption = ResolutionOption.all[0]
/// 帧率档位:默认常用档位,收到被控端上报的 supported_fps 后以上报列表为准
@Published var fpsOptions: [Int] = [15, 24, 30, 60]
/// 被控端当前采集帧率(0 表示尚未收到上报)
@Published var currentFps: Int = 0
/// 远端视频宽高比(宽/高),用于让触控层与画面精确对齐
@Published var videoAspect: CGFloat = 9.0 / 16.0
@Published var showAuthSheet: Bool = false
@@ -82,6 +86,9 @@ final class ControllerViewModel: NSObject, ObservableObject {
private var pendingAuthValue: String = ""
/// 是否为本端主动切换串流模式(避免上报回环再次发送)
private var suppressStreamModeSend = false
/// 被控端最近上报的实际采集尺寸(仅切帧率时保持分辨率不变,0 表示原生)
private var lastReportedWidth: Int32 = 0
private var lastReportedHeight: Int32 = 0
override init() {
super.init()
@@ -138,6 +145,10 @@ final class ControllerViewModel: NSObject, ObservableObject {
statsText = ""
streamMode = .webrtc
selectedResolution = ResolutionOption.all[0]
fpsOptions = [15, 24, 30, 60]
currentFps = 0
lastReportedWidth = 0
lastReportedHeight = 0
videoAspect = 9.0 / 16.0
}
@@ -192,6 +203,14 @@ final class ControllerViewModel: NSObject, ObservableObject {
webRTCClient?.requestResolutionChange(width: option.width, height: option.height, fps: 0)
}
/// 仅切换帧率:分辨率沿用被控端最近上报的实际采集尺寸(0 表示原生)
func selectFps(_ fps: Int) {
guard fps > 0, fps != currentFps else { return }
webRTCClient?.requestResolutionChange(width: lastReportedWidth,
height: lastReportedHeight,
fps: Int32(fps))
}
func toggleStreamMode(_ selfCodecOn: Bool) {
let newMode: StreamMode = selfCodecOn ? .selfCodec : .webrtc
guard newMode != streamMode else { return }
@@ -441,10 +460,17 @@ extension ControllerViewModel: WebRTCClientDelegate {
func webRTCClient(didReportResolution width: Int, height: Int) {
guard width > 0, height > 0 else { return }
lastReportedWidth = Int32(width)
lastReportedHeight = Int32(height)
if streamMode == .webrtc {
videoAspect = CGFloat(width) / CGFloat(height)
}
}
func webRTCClient(didReportFps fps: Int, supportedFps: [Int]) {
if fps > 0 { currentFps = fps }
if !supportedFps.isEmpty { fpsOptions = supportedFps }
}
}
// MARK: - RTCVideoViewDelegate(WebRTC 模式下画面尺寸变化)