优化ios视频bug
This commit is contained in:
parent
6b6a754cf9
commit
a6d53858f6
@ -61,21 +61,35 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
final actualRatio = _actualFps / targetFps;
|
||||
|
||||
// 更加保守和稳定的调整策略
|
||||
if (actualRatio < 0.4) {
|
||||
// 处理能力严重不足,大幅降低目标帧率
|
||||
state.targetFps = (targetFps * 0.6).round().clamp(15, 60);
|
||||
_startFrameProcessTimer();
|
||||
} else if (actualRatio < 0.6) {
|
||||
// 处理能力不足,中等幅度降低帧率
|
||||
state.targetFps = (targetFps * 0.8).round().clamp(15, 60);
|
||||
_startFrameProcessTimer();
|
||||
} else if (actualRatio > 1.8 && targetFps < 25) {
|
||||
// 处理能力充足,可以提高帧率
|
||||
state.targetFps = (targetFps * 1.15).round().clamp(15, 30);
|
||||
_startFrameProcessTimer();
|
||||
// iOS平台使用更保守的调整策略
|
||||
if (Platform.isIOS) {
|
||||
if (actualRatio < 0.25) {
|
||||
// iOS处理能力严重不足,大幅降低目标帧率
|
||||
state.targetFps = (targetFps * 0.6).round().clamp(15, 60);
|
||||
_startFrameProcessTimer();
|
||||
} else if (actualRatio < 0.45) {
|
||||
// iOS处理能力不足,中等幅度降低帧率
|
||||
state.targetFps = (targetFps * 0.8).round().clamp(15, 60);
|
||||
_startFrameProcessTimer();
|
||||
} else if (actualRatio > 2.5 && targetFps < 25) {
|
||||
// iOS处理能力充足,可以提高帧率
|
||||
state.targetFps = (targetFps * 1.05).round().clamp(15, 30);
|
||||
_startFrameProcessTimer();
|
||||
}
|
||||
} else {
|
||||
// Android平台原有逻辑
|
||||
if (actualRatio < 0.4) {
|
||||
state.targetFps = (targetFps * 0.6).round().clamp(15, 60);
|
||||
_startFrameProcessTimer();
|
||||
} else if (actualRatio < 0.6) {
|
||||
state.targetFps = (targetFps * 0.8).round().clamp(15, 60);
|
||||
_startFrameProcessTimer();
|
||||
} else if (actualRatio > 1.8 && targetFps < 25) {
|
||||
state.targetFps = (targetFps * 1.15).round().clamp(15, 30);
|
||||
_startFrameProcessTimer();
|
||||
}
|
||||
}
|
||||
// 注意:避免过于积极地提高帧率,这可能导致卡顿
|
||||
}
|
||||
}// 注意:避免过于积极地提高帧率,这可能导致卡顿
|
||||
}
|
||||
|
||||
// 回绕阈值,动态调整,frameSeq较小时阈值也小
|
||||
@ -139,7 +153,9 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
);
|
||||
|
||||
// 使用超时控制避免长时间等待
|
||||
final timeoutFuture = Future.delayed(const Duration(seconds: 3), () => null);
|
||||
// iOS平台使用更短的超时时间
|
||||
final timeoutSeconds = Platform.isIOS ? 2 : 3;
|
||||
final timeoutFuture = Future.delayed(Duration(seconds: timeoutSeconds), () => null);
|
||||
final decoderFuture = VideoDecodePlugin.initDecoder(config);
|
||||
|
||||
// 初始化解码器并获取textureId
|
||||
@ -163,9 +179,11 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
AppLog.log('初始化视频解码器错误: $e');
|
||||
state.isLoading.value = false;
|
||||
// 如果初始化失败,延迟后重试
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
// iOS平台使用更短的重试延迟
|
||||
final delaySeconds = Platform.isIOS ? 0.5 : 1;
|
||||
await Future.delayed(Duration(milliseconds: (delaySeconds * 1000).toInt()));
|
||||
if (!Get.isRegistered<TalkViewNativeDecodeLogic>()) {
|
||||
return; // 如果控制器已经被销毁,不再重试
|
||||
return;
|
||||
}
|
||||
_initVideoDecoder(); // 重试初始化
|
||||
}
|
||||
@ -292,7 +310,10 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
_stopFrameProcessTimer();
|
||||
|
||||
// 计算定时器间隔,确保以目标帧率处理帧
|
||||
final int intervalMs = max(16, min(40, (1000 / state.targetFps).round()));
|
||||
// iOS平台使用更精确的定时器间隔
|
||||
final int intervalMs = Platform.isIOS
|
||||
? max(16, min(33, (1000 / state.targetFps).round())) // iOS使用更严格的范围
|
||||
: max(16, min(40, (1000 / state.targetFps).round()));
|
||||
|
||||
// 创建新定时器
|
||||
state.frameProcessTimer = Timer.periodic(Duration(milliseconds: intervalMs), (timer) {
|
||||
@ -368,12 +389,22 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
final bufferLength = state.h264FrameBuffer.length;
|
||||
|
||||
// 更智能的帧率调整策略
|
||||
if (bufferLength > 50) {
|
||||
// 缓冲区过长,临时提高处理频率
|
||||
_temporarilyIncreaseProcessFrequency();
|
||||
} else if (bufferLength < 5) {
|
||||
// 缓冲区过短,降低处理频率节省资源
|
||||
_adjustFrameProcessFrequency((state.targetFps * 0.9).toDouble());
|
||||
// iOS平台优化:更积极的缓冲区管理
|
||||
if (Platform.isIOS) {
|
||||
if (bufferLength > 40) {
|
||||
// iOS缓冲区过长,临时提高处理频率
|
||||
_temporarilyIncreaseProcessFrequency();
|
||||
} else if (bufferLength < 3) {
|
||||
// iOS缓冲区过短,降低处理频率节省资源
|
||||
_adjustFrameProcessFrequency((state.targetFps * 0.95).toDouble());
|
||||
}
|
||||
} else {
|
||||
// Android平台原有逻辑
|
||||
if (bufferLength > 50) {
|
||||
_temporarilyIncreaseProcessFrequency();
|
||||
} else if (bufferLength < 5) {
|
||||
_adjustFrameProcessFrequency((state.targetFps * 0.9).toDouble());
|
||||
}
|
||||
}
|
||||
|
||||
// 查找最适合处理的帧
|
||||
@ -438,6 +469,8 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
|
||||
// 异步发送帧,添加超时处理
|
||||
try {
|
||||
// iOS平台使用更短的超时时间
|
||||
final timeoutMs = Platform.isIOS ? 15 : 20;
|
||||
await VideoDecodePlugin.sendFrame(
|
||||
frameData: frameData,
|
||||
frameType: pluginFrameType,
|
||||
@ -445,7 +478,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
timestamp: pts,
|
||||
splitNalFromIFrame: true,
|
||||
refIFrameSeq: frameSeqI,
|
||||
).timeout(const Duration(milliseconds: 20)); // 进一步缩短超时时间
|
||||
).timeout(Duration(milliseconds: timeoutMs)); // 进一步缩短超时时间
|
||||
|
||||
// 更新最后解码的I帧序号
|
||||
if (frameType == TalkDataH264Frame_FrameTypeE.I) {
|
||||
@ -462,7 +495,9 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
final durationMs = (endTime - startTime) / 1000.0;
|
||||
|
||||
// 性能监控 - 更宽松的阈值
|
||||
if (durationMs > 30) {
|
||||
// iOS平台使用更严格的性能监控
|
||||
final thresholdMs = Platform.isIOS ? 25 : 30;
|
||||
if (durationMs > thresholdMs) {
|
||||
AppLog.log('帧处理耗时过长: ${durationMs.toStringAsFixed(2)} ms, 缓冲区长度: ${state.h264FrameBuffer.length}');
|
||||
}
|
||||
}
|
||||
@ -482,7 +517,7 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
|
||||
_adjustFrameProcessFrequency(tempFps.toDouble());
|
||||
|
||||
// 3秒后恢复原频率
|
||||
// 2秒后恢复原频率
|
||||
_tempAdjustTimer = Timer(const Duration(seconds: 2), () {
|
||||
_adjustFrameProcessFrequency(originalFps.toDouble());
|
||||
_tempAdjustTimer = null;
|
||||
@ -1012,7 +1047,9 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
if (state.textureId.value != null) {
|
||||
try {
|
||||
// 极短超时时间,避免阻塞
|
||||
await VideoDecodePlugin.releaseDecoder().timeout(const Duration(milliseconds: 300));
|
||||
// iOS平台使用更短的超时时间
|
||||
final timeoutMs = Platform.isIOS ? 200 : 300;
|
||||
await VideoDecodePlugin.releaseDecoder().timeout(Duration(milliseconds: timeoutMs));
|
||||
state.textureId.value = null;
|
||||
} catch (e) {
|
||||
AppLog.log('释放解码器超时或失败: $e');
|
||||
@ -1022,7 +1059,9 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
}
|
||||
|
||||
// 最小化等待时间
|
||||
await Future.delayed(Duration(milliseconds: 2));
|
||||
// iOS平台使用更短的等待时间
|
||||
final delayMs = Platform.isIOS ? 0 : 1;
|
||||
await Future.delayed(Duration(milliseconds: delayMs));
|
||||
|
||||
// 创建新的解码器配置
|
||||
final config = VideoDecoderConfig(
|
||||
@ -1034,8 +1073,10 @@ class TalkViewNativeDecodeLogic extends BaseGetXController {
|
||||
// 初始化新解码器
|
||||
try {
|
||||
// 使用较短超时时间
|
||||
// iOS平台使用更短的超时时间
|
||||
final timeoutMs = Platform.isIOS ? 1000 : 1500;
|
||||
final textureId = await VideoDecodePlugin.initDecoder(config)
|
||||
.timeout(const Duration(milliseconds: 1500));
|
||||
.timeout(Duration(milliseconds: timeoutMs));
|
||||
|
||||
if (textureId != null) {
|
||||
state.textureId.value = textureId;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user