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

Swift实现MOV转MP4报错Unsupported value for standard codec求助

解决iOS端MOV转MP4时的"Unsupported value for standard codec"异常

我开发的Flutter应用需要将视频上传至服务器,但iOS设备拍摄的MOV格式视频无法在Edge浏览器中播放。尝试用Swift代码将MOV转换为MP4时出现报错:

Error : Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Unsupported value for standard codec'

原代码片段:

let myArgs = args as? [String: Any]
let movpath = myArgs?["movpath"] as? String
let mp4Path = myArgs?["mp4path"] as? String
let movurl = URL(fileURLWithPath: movpath!)
let mp4url = URL(fileURLWithPath: mp4Path!)
let avAsset = AVURLAsset(url: movurl, options: nil)

//Create Export session
let exportSession = AVAssetExportSession(asset: avAsset, presetName: AVAssetExportPresetPassthrough)

// exportSession = AVAssetExportSession(asset: composition, presetName: mp4Quality)

exportSession!.outputURL = mp4url
exportSession!.outputFileType = AVFileType.mp4
exportSession!.shouldOptimizeForNetworkUse = true
var start = CMTimeMakeWithSeconds(0.0,preferredTimescale:  0)
var range = CMTimeRangeMake(start:start, duration: avAsset.duration)
exportSession!.timeRange = range

exportSession!.exportAsynchronously {
    result(exportSession!.outputURL)
}

问题原因及修复方案

核心错误原因

使用AVAssetExportPresetPassthrough预设时,原MOV文件的编码格式(如ProRes或苹果专属编码)无法直接封装进MP4容器,编码器不兼容导致抛出异常;同时CMTimeMakeWithSeconds传入的preferredTimescale为0,属于非法参数,会引发时间范围配置错误。

具体修复步骤

  1. 替换导出预设:将AVAssetExportPresetPassthrough替换为支持MP4的编码预设,比如AVAssetExportPresetHighestQuality或AVAssetExportPresetMediumQuality,这类预设会自动将视频转码为MP4兼容的H.264/H.265编码。
  2. 修复时间刻度参数:CMTimeMakeWithSeconds的preferredTimescale需传入合法值(如AVFoundation常用的600),不能为0。
  3. 添加安全判断:移除强制解包操作,通过可选绑定避免空值崩溃;同时增加导出结果状态判断,处理失败场景。

修复后的代码:

guard let myArgs = args as? [String: Any],
      let movpath = myArgs["movpath"] as? String,
      let mp4Path = myArgs["mp4path"] as? String else {
    result(nil)
    return
}

let movurl = URL(fileURLWithPath: movpath)
let mp4url = URL(fileURLWithPath: mp4Path)
let avAsset = AVURLAsset(url: movurl, options: nil)

// 使用兼容MP4的编码预设
guard let exportSession = AVAssetExportSession(asset: avAsset, presetName: AVAssetExportPresetHighestQuality) else {
    result(nil)
    return
}

exportSession.outputURL = mp4url
exportSession.outputFileType = .mp4
exportSession.shouldOptimizeForNetworkUse = true

// 修复时间刻度参数,使用合法值600
let start = CMTimeMakeWithSeconds(0.0, preferredTimescale: 600)
let range = CMTimeRangeMake(start: start, duration: avAsset.duration)
exportSession.timeRange = range

exportSession.exportAsynchronously {
    // 处理导出结果
    switch exportSession.status {
    case .completed:
        result(exportSession.outputURL)
    case .failed, .cancelled:
        print("导出失败: \(exportSession.error?.localizedDescription ?? "未知错误")")
        result(nil)
    default:
        result(nil)
    }
}

补充说明

  • 若需精准控制编码参数(如指定H.264编码),可使用AVAssetWriter替代AVAssetExportSession,但实现复杂度更高。
  • 导出前需确保目标路径的MP4文件不存在,否则会导出失败,可提前删除目标文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:35:19