You need to enable JavaScript to run this app. Xamarin C# iOS端通过AVAsset将.mov转码为.mp4报错问题求助
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin C# iOS端通过AVAsset将.mov转码为.mp4报错问题求助

iOS端视频转码路径错误及AVFoundation -11800报错修复方案

核心根因

  • 路径拼接错误:通过MediaGallery选中的媒体文件不会默认存储在Environment.SpecialFolder.Personal目录下,自行拼接路径会导致找不到文件,File.Exists(input)直接返回false
  • 转码预设不兼容:使用AVAssetExportSession.PresetPassthrough预设不会做编码转换,仅直接拷贝原文件流,如果原.mov采用了ProRes、ALAC等MP4容器不兼容的编码格式,就会触发-11800通用错误
  • 异步逻辑漏洞:原生ConvertVideo方法标记为async Task但未等待导出完成就返回,上层调用会误认为转码已完成,出现时序问题

修复步骤

1. 修复共享层路径获取逻辑

不要自行拼接输入路径,直接读取MediaPicker返回的文件全路径:

try
{
    MediaPickResult pickresult = await MediaGallery.PickAsync(1, MediaFileType.Video);
    if (pickresult != null)
    {
        foreach (var video in pickresult.Files)
        {
            string guid = Guid.NewGuid().ToString();
            blobupload.BlobID = guid + ".mp4";
            // 直接使用Picker返回的全路径,不要自行拼接
            string input = video.FullPath;
            string output = Path.Combine(AzureStorage.localpath, guid + ".mp4");
            
            if (File.Exists(input))
            {
                await IVideoConverter.ConvertVideo(input, output);
            }
            else
            {
                System.Diagnostics.Debug.WriteLine($"视频文件不存在,路径:{input}");
            }
        }
    }
}
catch (Exception ex)
{
    System.Diagnostics.Debug.WriteLine($"选择视频异常:{ex.Message}");
}

2. 修复iOS原生转码逻辑

替换兼容预设、补全异步等待逻辑和异常校验:

public async Task ConvertVideo(string inputpath, string outputpath)
{
    // 前置校验输入文件
    if (!File.Exists(inputpath))
        throw new FileNotFoundException("输入视频文件不存在", inputpath);
    
    // 清空已存在的输出文件,避免覆盖报错
    if (File.Exists(outputpath))
        File.Delete(outputpath);

    AVAsset asset = AVAsset.FromUrl(NSUrl.FromFilename(inputpath));
    if (asset == null)
        throw new InvalidOperationException("无法加载视频为AVAsset");

    // 自动匹配兼容的H264编码预设,保证输出MP4安卓可播放,不再使用Passthrough
    var supportPresets = AVAssetExportSession.GetCompatibleExportPresets(asset, new[] { 
        AVAssetExportSession.PresetH264_1920x1080,
        AVAssetExportSession.PresetMediumQuality 
    });
    var exportPreset = supportPresets.FirstOrDefault() ?? AVAssetExportSession.PresetMediumQuality;

    AVAssetExportSession export = new AVAssetExportSession(asset, exportPreset);
    if (export == null)
        throw new InvalidOperationException("无法创建视频导出会话");

    export.OutputUrl = NSUrl.FromFilename(outputpath);
    export.OutputFileType = AVFileType.Mpeg4;
    export.ShouldOptimizeForNetworkUse = true;

    // 将回调式异步转为Task等待,保证方法返回时转码真实完成
    var tcs = new TaskCompletionSource<bool>();
    export.ExportAsynchronously(() =>
    {
        if (export.Error != null)
        {
            tcs.TrySetException(new NSErrorException(export.Error));
            System.Diagnostics.Debug.WriteLine($"导出失败:{export.Error.LocalizedDescription}");
        }
        else if (export.Status == AVAssetExportSessionStatus.Completed)
        {
            tcs.TrySetResult(true);
        }
        else
        {
            tcs.TrySetException(new InvalidOperationException($"导出失败,状态码:{export.Status}"));
        }
    });

    await tcs.Task;
}

补充注意事项

  • 若应用适配iOS14及以上版本,需要确认已经申请了相册读取权限,否则选中的文件会出现无权访问的问题
  • 导出预设可以根据业务对清晰度的要求调整,要求文件更小可以用PresetLowQuality,要求更高清晰度可以用PresetH264_3840x2160

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 17:45:04