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

iPhone端Safari/Chrome无法播放跨端上传的HTML5视频,报NotSupportedError

iOS端视频播放NotSupportedError问题排查与修复

问题描述

开发了两段脚本:一段录制视频并上传至Bubble服务器,另一段通过上传后的URL播放视频。该功能在多数平台浏览器正常,但iPhone的Safari/Chrome浏览器存在异常:视频可成功上传,但播放时抛出NotSupportedError。仅iPhone浏览器上传的视频能在iPhone端正常播放,Mac/Windows上传的视频无法在iPhone端播放,问题出在上传或播放的细节处理上。

原脚本代码

脚本1:录制并上传视频

let mediaRecorder;
let cameraView;
let recordedChunks = []; // 存储流数据的数组
instance.data.streamWebcam = await getCamera();
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = function (e) {
    if (e.data.size > 0) {
        recordedChunks.push(e.data);
    }
};
mediaRecorder.onstop = function () {
    const blob = new Blob(recordedChunks, {
        type: 'video/mp4'
    });
    var reader = new FileReader();
    reader.readAsDataURL(blob);
    reader.onloadend = function () {
        var filename = 'video_' + (new Date()).getTime() + '.mp4';
        var base64data = reader.result;
        var uploadData = base64data.substr(base64data.indexOf(',') + 1);
        context.uploadContent(filename, uploadData, function (err, url) { // 上传至Bubble数据库
            URL.revokeObjectURL(blob); 
        });
    }
};
cameraView = document.createElement('video'); // 创建视频元素
cameraView.srcObject = instance.data.streamWebcam;
cameraView.style.width = '100%';
cameraView.style.height = '100%';
cameraView.style.overflow = 'hidden';
cameraView.style.objectFit = 'cover';
cameraView.style.display = 'block';
cameraView.muted = true;
cameraView.autoplay = true;
cameraView.playsInline = true;
cameraView.onloadedmetadata = function (e) {
    cameraView.play(); // 加载后播放视频
};
instance.canvas.append(cameraView); // 添加元素到画布
mediaRecorder.start(200);

脚本2:通过URL播放视频

let playerVideo = document.createElement('video');
playerVideo.type = 'video/mp4'
playerVideo.style.overflow = 'hidden';
playerVideo.style.objectFit = 'cover';
playerVideo.style.display = 'block';
playerVideo.src = playerVideoUrl + "#t=0.001";
playerVideo.controls = field_showControls;
playerVideo.autoplay = autoplayValue;
playerVideo.muted = true;
playerVideo.playsInline = true;
playerVideo.style.width = '100%';
playerVideo.style.height = '100%';
instance.canvas.append(playerVideo);
playerVideo.play();

问题根源

iOS的Safari/Chrome对视频编码有严格限制,仅支持H.264(Baseline/Main/High profile)+ AAC音频的MP4格式。而Mac/Windows平台的MediaRecorder默认可能生成VP8/VP9等非兼容编码的MP4容器(虽后缀为mp4,但编码不被iOS识别),导致播放时抛出格式不支持错误。

修复方案

1. 上传阶段:强制指定iOS兼容的编码格式

修改MediaRecorder初始化参数,明确指定兼容的MIME类型,确保生成的视频编码符合iOS要求:

// 替换原mediaRecorder初始化代码
const options = {
  mimeType: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"' // H.264 Baseline + AAC
};
// 检查浏览器是否支持该编码,不支持则降级为默认MP4
mediaRecorder = MediaRecorder.isTypeSupported(options.mimeType) 
  ? new MediaRecorder(stream, options) 
  : new MediaRecorder(stream, { mimeType: 'video/mp4' });

2. 上传阶段:优化Blob上传方式(可选)

原脚本将Blob转Base64上传,可能增加体积和潜在编码问题。若Bubble的uploadContent支持直接上传Blob,建议简化流程:

// 替换原mediaRecorder.onstop代码
mediaRecorder.onstop = function () {
  const blob = new Blob(recordedChunks, { type: 'video/mp4' });
  const filename = 'video_' + (new Date()).getTime() + '.mp4';
  // 直接上传Blob(需确认Bubble API支持)
  context.uploadContent(filename, blob, function (err, url) {
    URL.revokeObjectURL(blob);
  });
};

3. 播放阶段:优化iOS播放逻辑

  • 移除URL末尾的#t=0.001,避免iOS片段播放兼容问题
  • 监听canplay事件再触发播放,避免过早调用导致错误
  • 添加错误监听便于排查
// 替换原脚本2代码
let playerVideo = document.createElement('video');
playerVideo.type = 'video/mp4';
playerVideo.style.overflow = 'hidden';
playerVideo.style.objectFit = 'cover';
playerVideo.style.display = 'block';
playerVideo.src = playerVideoUrl; // 移除#t=0.001
playerVideo.controls = field_showControls;
playerVideo.autoplay = autoplayValue;
playerVideo.muted = true;
playerVideo.playsInline = true;
playerVideo.style.width = '100%';
playerVideo.style.height = '100%';

// 添加错误监听
playerVideo.onerror = (e) => console.error('视频播放错误:', e.error);
// 等待视频可播放后再触发自动播放
playerVideo.addEventListener('canplay', () => {
  if (autoplayValue) {
    playerVideo.play().catch(err => console.error('自动播放失败:', err));
  }
});

instance.canvas.append(playerVideo);

4. 验证视频编码(可选)

用ffmpeg工具检查上传后的视频编码,确认是否为iOS兼容格式:

ffmpeg -i 上传后的视频URL或本地文件路径

输出中需包含Video: h264和Audio: aac,否则说明编码指定未生效,需调整MediaRecorder参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 13:03:18