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

Xamarin iOS中AVAssetExportSession转MOV为MP4时视频末尾截断的解决方法

Fixing Truncated MP4 Exports in Xamarin iOS with AVAssetExportSession

I’ve run into this exact issue before—truncated video exports usually happen because the AVAsset isn’t fully loaded before we start the export process, or there’s a lack of proper error checking for the export session’s final status. Let’s walk through the fixes step by step:

Common Causes & Solutions

  • Incomplete Asset Loading: When you create an AVAsset from a file URL, it doesn’t immediately load all metadata (like full video duration). Starting the export too early can lead to the session using incomplete duration data, resulting in a truncated output.
  • Missing Export Status Checks: Your original code only waits for the export task to finish but doesn’t verify if it succeeded. A failed export might leave you with a partial file without warning.
  • Network Optimization Conflicts: The ShouldOptimizeForNetworkUse flag can sometimes cause unexpected truncation on certain video files, especially those with non-standard encoding.

Modified Working Code

Here’s your updated code incorporating these fixes:

var basePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
var inputFilePath = Path.Combine(basePath, Path.ChangeExtension(_vm.Model.AnswerName, "mov"));
var outputFilePath = Path.Combine(basePath, $"{_vm.Model.AnswerName}.mp4"); // Explicitly add .mp4 extension

// Create asset and wait for critical metadata to load fully
var asset = AVAsset.FromUrl(NSUrl.FromFilename(inputFilePath));
var loadStatus = asset.LoadValuesAsynchronously(new string[] { "tracks" }, out NSError loadError);

if (loadStatus != AVKeyValueStatus.Loaded)
{
    System.Diagnostics.Debug.WriteLine($"Failed to load asset metadata: {loadError?.LocalizedDescription}");
    return;
}

// Initialize export session and validate it
AVAssetExportSession exportSession = new AVAssetExportSession(asset, AVAssetExportSession.PresetHighestQuality);
if (exportSession == null)
{
    System.Diagnostics.Debug.WriteLine("Export session could not be created (unsupported preset or asset type)");
    return;
}

exportSession.OutputUrl = NSUrl.FromFilename(outputFilePath);
exportSession.OutputFileType = AVFileType.Mpeg4;
exportSession.ShouldOptimizeForNetworkUse = false; // Disable if truncation persists
exportSession.TimeRange = new CMTimeRange(CMTime.Zero, asset.Duration); // Explicitly set full video range

try
{
    await exportSession.ExportTaskAsync(); // Use await instead of Wait() to avoid deadlocks

    // Check export status and handle results
    switch (exportSession.Status)
    {
        case AVAssetExportSessionStatus.Completed:
            System.Diagnostics.Debug.WriteLine("Export completed successfully!");
            // Delete original MOV file only if export succeeded
            var fileHelper = new FileHelper();
            var originalMovPath = Path.Combine(basePath, Path.ChangeExtension(_vm.Model.AnswerName, "mov"));
            if (fileHelper.FileExists(originalMovPath))
            {
                fileHelper.DeleteFile(originalMovPath);
            }
            break;
        case AVAssetExportSessionStatus.Failed:
            System.Diagnostics.Debug.WriteLine($"Export failed: {exportSession.Error?.LocalizedDescription}");
            // Clean up partial output file
            if (File.Exists(outputFilePath)) File.Delete(outputFilePath);
            break;
        case AVAssetExportSessionStatus.Cancelled:
            System.Diagnostics.Debug.WriteLine("Export was cancelled");
            break;
    }
}
catch (Exception ex)
{
    System.Diagnostics.Debug.WriteLine($"Export exception: {ex.Message}");
    // Clean up partial output file
    if (File.Exists(outputFilePath)) File.Delete(outputFilePath);
}

Key Improvements

  • Explicit File Extension: Adding .mp4 to the output path avoids ambiguity with file type associations.
  • Async/Await: Replacing Wait() with await prevents potential deadlocks in async code.
  • Full Time Range: Explicitly setting TimeRange ensures the export session uses the complete video duration.
  • Comprehensive Error Handling: Checking the export session’s Status gives clear feedback on success or failure, plus cleanup of partial files when things go wrong.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:56:03