【问题标题】:Xaml MediaElement does not play .mov video from internetXaml MediaElement 不播放来自 Internet 的 .mov 视频
【发布时间】:2016-10-13 18:55:41
【问题描述】:

我想播放来自互联网的实时视频流,提供MediaElement xaml 控件的 URL。如果视频是.mp4,一切正常。但如果视频是在 iphone 上拍摄并保存为 .movMediaElement 什么都不会显示,只会触发 loading 事件。 (下载完成后约 5 分钟触发其他事件) 这里MediaElement初始化:

MediaElement media = new MediaElement();
media.MediaFailed += Media_MediaFailed;
media.PartialMediaFailureDetected += Media_PartialMediaFailureDetected;
media.MediaOpened += Media_MediaOpened;
media.DownloadProgressChanged += Media_DownloadProgressChanged;
media.Loading += Media_Loading;
media.MediaEnded += Media_MediaEnded;
media.Source = new Uri(URL);

如果通过HttpClient手动下载视频,然后将Stream.AsRamdomAccessStream()提供给MediaElement,视频会立即开始播放。 MediaElement 似乎不支持 .mov/quicktime 视频的直播。这是真的吗?

【问题讨论】:

    标签: c# xaml video-streaming uwp


    【解决方案1】:

    很遗憾,内置的MediaElement 控件不支持mov

    mov 视频类型是 Apple Inc. 针对 QuickTime 播放器的专有格式,这意味着它可能永远不会被原生支持。

    支持的格式和编解码器的完整列表是here on MSDN

    编辑:看来MediaElement控件实际上可以使用PC上安装的编解码器直接播放不支持的格式,包括mov

    【讨论】:

    • 但是我可以用MediaElement播放本地mov视频,以及预下载的mov视频。唯一的问题是直播。还是说不支持流式传输?
    • 哦,我错过了。在那种情况下,我不太确定...mov 只是mp4 周围的压缩,所以MediaElement 可能可以使用PC 上安装的编解码器播放它,但无法播放它流式传输。我还认为在 Phone 或 Xbox 上,mov 根本不会播放,即使从文件中也不会播放,不是吗?
    • 我没有在手机上查看 xbox,因为我只写桌面客户端,但看起来你是对的。此外,我在 chrome 浏览器中通过 html5 打开 mov 视频时遇到问题,但这个发现是另一个问题。
    【解决方案2】:

    真正的问题在于容器原子的顺序。如解释here

    为了立即开始播放电影文件,它包含在“moov”原子中的元数据对播放器来说是最重要的。如果电影文件 atom 的顺序如前所述,一切都按预期工作......但大多数视频编辑器(ffmpeg、quicktime、flash 视频)以错误的顺序生成 atom(如右图所示):最后使用“moov”原子.

    并提供解决方案:

    唯一的解决方案是修复这些文件并重新排列里面的原子。可以这样做:

    • Oldskool 方式使用 FFMPEG 的 qt-faststart.c 中的一些 C 代码。代码移动文件顶部的“moov”原子,并通过添加适当的偏移量来更新所有“stco”子原子指针。
    • 使用 iOS AV Foundation 框架和几行 Objective-C(你也可以从 MOV 转换为 MP4,因为 Android 无法读取 MOV):

      #import <AVFoundation/AVAsset.h>
      #import <AVFoundation/AVAssetExportSession.h>
      #import <AVFoundation/AVMediaFormat.h>
      
      + (void) convertVideoToMP4AndFixMooV: (NSString*)filename toPath:(NSString*)outputPath
      {    
      
      NSURL *url = [NSURL fileURLWithPath:finename];    
      AVAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
      
      
      AVAssetExportSession *exportSession = [AVAssetExportSession
                                         exportSessionWithAsset:avAsset
                                         presetName:AVAssetExportPresetPassthrough];
      
      exportSession.outputURL = [NSURL fileURLWithPath:outputPath];
      exportSession.outputFileType = AVFileTypeAppleM4V;   
      
      
      // This should move the moov atom before the mdat atom,
      // hence allow playback before the entire file is downloaded
      exportSession.shouldOptimizeForNetworkUse = YES;     
      
      
      [exportSession exportAsynchronouslyWithCompletionHandler:
      ^{
          if (AVAssetExportSessionStatusCompleted == exportSession.status) {} 
            else if (AVAssetExportSessionStatusFailed == exportSession.status) {
                NSLog(@"AVAssetExportSessionStatusFailed");
            } 
            else 
            {
                NSLog(@"Export Session Status: %d", exportSession.status);
            }
       }];
      }
      

    由于我也在开发 iOS 客户端,这解决了我的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-18
      • 1970-01-01
      • 2011-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多