You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebRTC问题:仅iOS端出现笔记本发起的RecordRTC录制视频分割异常

问题描述

基于WebRTC的Web应用使用RecordRTC录制视频时,仅在笔记本端发起录制、iOS设备参与的场景下出现视频分割异常(存储后播放存在分割断层),Android设备录制功能运行正常。

排查步骤
  • 验证录制格式兼容性:在iOS设备上打印RecordRTC实际使用的MIME类型,确认是否为iOS Safari支持的MP4(H.264视频编码+AAC音频编码),而非WebM格式(iOS对WebM支持有限)。
  • 检查分片录制逻辑:当前代码设置了timeSlice:1000(每秒触发一次ondataavailable),需确认每次触发生成的Blob是否为完整的视频片段,以及合并逻辑是否导致格式混乱。
  • 测试无分片录制:暂时移除timeSlice参数,录制完整视频后保存,排查是否为分片触发逻辑导致的分割问题。
  • 查看iOS控制台日志:使用Safari开发者工具连接iOS设备,查看录制过程中的错误/警告信息,比如编码失败、媒体轨道中断等。
  • 确认Blob合并格式一致性:检查合并Blob时指定的MIME类型是否与实际录制的格式一致,避免格式不匹配导致解析错误。
潜在解决方案

1. 修正MIME类型配置

代码中先判断了支持的MIME类型并赋值给options,但初始化RecordRTC时硬写了mimeType: 'video/webm',覆盖了之前的兼容判断。需确保使用iOS支持的MP4格式:

// 初始化RecordRTC时直接使用之前判断好的options,不要硬写mimeType
remoteRecorder = RecordRTC(remoteStreamToBeRecorded, options);

2. 调整分片录制逻辑

若无需分片录制,直接移除timeSlice参数,改为在录制结束的onstop回调中处理完整Blob,避免多次分片合并导致的视频分割:

// 替换ondataavailable为onstop回调
remoteRecorder.onstop = function() {
    const blob = remoteRecorder.getBlob();
    if (blob && blob.size > 0) {
        const fileName = `video_${window.videoCounter}.mp4`;
        saveVideoToFile(blob, fileName);
        
        const reader = new FileReader();
        reader.readAsDataURL(blob);
        reader.onload = function(e) {
            if (window.videoCounter > 0) {
                saveVideoByteArraytoCloudNew(reader.result.toString(), window.videoCounter, WebReferenceNumber, surveyType);
                endCall();
            }
        };
        window.videoCounter++;
    }
};

3. 适配iOS Safari特性

  • iOS Safari的MediaRecorder对timeSlice的处理存在差异,若必须使用分片,建议将timeSlice设置为更大的值(如5000ms),且确保每次分片的Blob格式一致。
  • 避免在录制过程中频繁操作媒体轨道,确保iOS设备的摄像头权限稳定,网络无波动导致轨道中断。

4. 修复Blob合并逻辑

合并Blob时需使用录制实际的MIME类型,而非硬写video/mp4:

// 不要硬写type,使用录制Blob的type
const blob1 = new Blob(recordedBlobs, { type: recordedBlobs[0].type });
完整修正代码示例
var remoteStreamToBeRecorded = evt.stream;
var options;

// 检查并设置支持的MIME类型,优先iOS兼容的MP4
if (canRecord('video/mp4; codecs="avc1.42E01E, mp4a.40.2"')) {
    options = { 
        mimeType: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"',
        type: 'video',
        recorderType: MediaStreamRecorder,
        disableLogs: true,
        checkForInactiveTracks: false,
        bitsPerSecond: 128000,
        audioBitsPerSecond: 128000,
        videoBitsPerSecond: 128000,
        frameRate: 30,
        canvas: { width: 640, height: 480 }
    };
} else if (canRecord('video/webm; codecs="vp9, opus"')) {
    options = { 
        mimeType: 'video/webm; codecs="vp9, opus"',
        type: 'video',
        recorderType: MediaStreamRecorder,
        disableLogs: true,
        checkForInactiveTracks: false,
        bitsPerSecond: 128000,
        audioBitsPerSecond: 128000,
        videoBitsPerSecond: 128000,
        frameRate: 30,
        canvas: { width: 640, height: 480 }
    };
} else {
    console.error('RecordRTC不支持或MIME类型不受支持');
    alert('当前浏览器不支持RecordRTC');
    return;
}

remoteRecorder = RecordRTC(remoteStreamToBeRecorded, options);

// 录制结束时处理完整视频
remoteRecorder.onstop = function() {
    const blob = remoteRecorder.getBlob();
    if (!blob || blob.size <= 0) return;

    const fileName = `video_${window.videoCounter}.mp4`;
    saveVideoToFile(blob, fileName);

    const reader = new FileReader();
    reader.readAsDataURL(blob);
    reader.onload = function(e) {
        if (window.videoCounter > 0) {
            saveVideoByteArraytoCloudNew(reader.result.toString(), window.videoCounter, WebReferenceNumber, surveyType);
            endCall();
        }
    };

    window.videoCounter++;
};

if (remoteRecorder) {
    remoteRecorder.startRecording();
} else {
    console.error('远程录制器初始化失败');
}

内容的提问来源于stack exchange,提问作者user23489822

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 09:03:13