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

Xamarin原生聊天APP:iOS视频无法在Android播放及转码失败求助

解决Xamarin iOS端视频转码失败导致Picker卡顿的问题

咱们先理清楚核心问题:你现在要在iOS端发送视频前转码成Android兼容的格式,替代服务器转码,但现有代码执行时Picker卡在快照界面,转码失败,日志显示Export failed: The operation could not be completed,还有调试相关的System.NotSupportedException(这个大概率是调试器的问题,不是转码本身的核心错误)。

问题根源分析

  1. 转码预设选择错误:你用了AVAssetExportSessionPreset.Passthrough,这个预设是直接复制原视频流,不做任何转码,等于没解决Android兼容的问题,而且如果原视频的容器或编码和你设置的AVFileType.Mpeg4不匹配,就会导致转码失败。
  2. UI操作线程问题:你在ExportAsynchronously的回调里直接调用Picker.DismissViewControllerAsync(true),但这个回调是在后台线程执行的,UI操作必须在主线程,这可能导致Picker卡顿。
  3. 临时文件路径处理:虽然你用了临时路径,但直接创建NSUrl的方式可能存在格式问题,影响文件写入权限。

修复后的代码示例

// 初始化Picker时,直接指定兼容的视频质量,去掉Passthrough预设
Picker = new UIImagePickerController() 
{ 
    SourceType = type, 
    MediaTypes = UIImagePickerController.AvailableMediaTypes(type), 
    VideoQuality = UIImagePickerControllerQualityType.Medium, 
    VideoMaximumDuration = 120f 
};

// 选择视频后的处理逻辑
var srcUrl = e.Info[UIImagePickerController.MediaURL] as NSUrl;
AVUrlAsset avAsset = new AVUrlAsset(srcUrl, null); // 用null代替空NSDictionary,简化参数
string[] compatiblePresets = AVAssetExportSession.ExportPresetsCompatibleWithAsset(avAsset);

// 选择Android兼容的预设,比如MediumQuality(会自动转码为H.264+AAC的MP4)
if (compatiblePresets.Contains(AVAssetExportSessionPreset.MediumQuality.GetConstant().ToString())) 
{
    AVAssetExportSession exportSession = new AVAssetExportSession(avAsset, AVAssetExportSessionPreset.MediumQuality);
    
    // 生成符合iOS要求的临时文件路径
    string destFileName = $"{Guid.NewGuid()}.mp4";
    string destPath = Path.Combine(Path.GetTempPath(), destFileName);
    exportSession.OutputUrl = NSUrl.FromFilename(destPath); // 用FromFilename确保路径格式正确
    exportSession.OutputFileType = AVFileType.Mpeg4;
    exportSession.ShouldOptimizeForNetworkUse = true;

    exportSession.ExportAsynchronously(() => {
        // 所有UI操作必须回到主线程执行
        InvokeOnMainThread(() => {
            switch (exportSession.Status) {
                case AVAssetExportSessionStatus.Failed:
                    Console.WriteLine(@"Export failed: " + exportSession.Error.LocalizedDescription);
                    Picker.DismissViewControllerAsync(true);
                    break;
                case AVAssetExportSessionStatus.Cancelled:
                    Console.WriteLine(@"Export canceled");
                    Picker.DismissViewControllerAsync(true);
                    break;
                case AVAssetExportSessionStatus.Completed:
                    // 转码成功,获取本地路径并发送
                    var localPath = exportSession.OutputUrl.Path;
                    SendMedia(localPath, ChatMessageType.Video);
                    Picker.DismissViewControllerAsync(true);
                    break;
                default:
                    Picker.DismissViewControllerAsync(true);
                    break;
            }
        });
    });
}

关键修改点说明

  • 替换转码预设:把Passthrough换成MediumQuality,这个预设会将视频转码为Android默认播放器完全兼容的H.264编码+AAC音频的标准MP4格式,从根源解决跨平台播放问题。
  • 主线程处理UI:用InvokeOnMainThread包裹所有UI操作(包括关闭Picker),避免后台线程操作UI导致的卡顿或异常。
  • 优化路径创建:用NSUrl.FromFilename替代直接实例化NSUrl,确保路径格式符合iOS文件系统要求,避免写入权限问题。
  • 明确状态分支:单独处理Completed状态,让逻辑更清晰,避免误判转码结果。

额外建议

  • 转码开始前可以显示一个加载提示(比如ActivityIndicator),让用户知道正在处理视频,提升交互体验。
  • 测试不同来源的视频(比如系统相机录制、第三方APP拍摄的视频),确保所有场景下都能成功转码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:14:18