【问题标题】:How to play movie files with no file extension on iOS with MPMoviePlayerController or AVPlayer?如何使用 MPMoviePlayerController 或 AVPlayer 在 iOS 上播放没有文件扩展名的电影文件?
【发布时间】:2011-07-26 23:28:45
【问题描述】:

我想在 iPad 上播放 iOS 4.3 中的电影。当文件名具有文件扩展名时,我已成功使用 MPMoviePlayerController 和 AVPlayer 从远程 URL 加载文件。但是,当我使用不返回文件名(只是一个不可猜测的随机名称)的 CDN 时,MPMoviePlayerController 或 AVPlayer 似乎都无法应对。

有没有办法告诉任何一个播放器它确实是 x 类型的电影,它应该继续播放它?

MPMoviePlayerController 将从其状态更改通知中返回以下错误:

{
    MPMoviePlayerPlaybackDidFinishReasonUserInfoKey = 1;
    error = "Error Domain=MediaPlayerErrorDomain Code=-12847 \"This movie format is not supported.\" UserInfo=0x5b60030 {NSLocalizedDescription=This movie format is not supported.}";
}

我知道该文件是有效的 m4v 文件,因为当我重命名它时一切正常。

【问题讨论】:

  • +1 提出好问题 - 希望有人想出办法来实现这一点......
  • 没有一个理想的解决方案,但我发现了一些可能对某些人有帮助的东西 - 如果您确保内容类型标题正确,那么如果没有文件扩展名,视频就会播放。因此,要在 MPMoviePlayerController 中播放视频,您需要 要么 正确的文件扩展名 正确的 mime 类型。我使用有效的文件扩展名和不正确的内容类型对其进行了测试,它仍然可以播放。
  • 嗨@Michael,你解决这个问题了吗?我现在也在尝试,我可以知道它是如何工作的吗?
  • @Santo 如果您对私有 API 感到满意,请在下面查看我的答案

标签: iphone ios mpmovieplayercontroller avplayer


【解决方案1】:

终于,我找到了答案。

您应该使用 AVURLAsset(AVAsset 的子类)并在选项输入中设置 MIMEType:

let mimeType = "video/mp4; codecs=\"avc1.42E01E, mp4a.40.2\""
let urlAsset = AVURLAsset(url: url, options["AVURLAssetOutOfBandMIMETypeKey": mimeType])

来源 -> https://stackoverflow.com/a/54087143/6736184

【讨论】:

  • 在这种情况下,这个问题可能是重复的。如果您认为网站上已经存在此解决方案,您可以标记 OPs 问题
【解决方案2】:

WebKit 通过 Private AVURLAsset 选项处理此问题:AVURLAssetOutOfBandMIMETypeKey,当您在 HTML 的 video 标记中指定 MIME 类型时使用此选项,

你可以像这样使用这个选项:

NSString * mimeType = @"video/mp4";

// or even with codecs
mimeType = @"video/mp4; codecs=\"avc1.42E01E, mp4a.40.2\"";

// create asset
AVURLAsset * asset = [[AVURLAsset alloc] initWithURL:url options:@{@"AVURLAssetOutOfBandMIMETypeKey": mimeType}];

// create AVPlayer with AVURLAsset
AVPlayer * player = [AVPlayer playerWithPlayerItem:[AVPlayerItem playerItemWithAsset:asset]];

由于它是私钥,如果您打算将其提交到 AppStore,您可能需要对其进行混淆处理。

WebKit 源代码可以在这里找到: https://opensource.apple.com/source/WebCore/WebCore-7604.1.38.1.6/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm.auto.html

【讨论】:

    【解决方案3】:

    如果您在获取连接的 ContentType 时遇到问题,您可以循环浏览可播放的 MIME 类型并创建指向带有扩展名的实际文件的符号链接,并检查它们是否可播放。像这样:

    NSLog(@"linked path: %@",[videoURL absoluteString]);
    NSString* linkedPath;
    AVURLAsset* asset;
    NSFileManager *filemgr = [NSFileManager defaultManager];
    
    for (NSString* string in [AVURLAsset audiovisualMIMETypes]) {
    
        if ([string containsString:@"video/"]) {
    
            NSLog(@"Trying: %@",string);
    
            linkedPath = [[videoURL absoluteString] stringByAppendingPathExtension:[string stringByReplacingOccurrencesOfString:@"video/" withString:@""]];
            NSLog(@"linked path: %@",linkedPath);
    
            if (![filemgr fileExistsAtPath:linkedPath]) {
                NSError *error = nil;
                [filemgr createSymbolicLinkAtURL:[NSURL URLWithString:linkedPath] withDestinationURL:videoURL error:&error];
                if (error) {
                   NSLog(@"error %@",error.localizedDescription);
                }
            }
    
           asset = [AVURLAsset assetWithURL:[NSURL URLWithString:linkedPath]];
            if ([asset isPlayable]) {
                NSLog(@"Playable");
                break;
            }else{
                NSLog(@"Not Playable");
                asset = nil;
            }
        }
    
    }
    

    【讨论】:

    • 我在上面的代码中加入了这行代码,解决了我的问题,NSString *slink = [_filePath stringByAppendingPathExtension:@"mp4"];
    • 基本上,上面的代码将不带扩展名的“myfilename”转换为类似的东西,“myfilename.mp4”和“myfilename.m4v”和“myfilename.3gpp”和“myfilename.3gpp2”等等.所有这些创建的符号链接可以在同一目录或不同目录中。
    【解决方案4】:

    文件在 tmp

    NSString* _filePath
    

    创建符号链接

    NSFileManager *filemgr = [NSFileManager defaultManager];
    NSString *slink = [_filePath stringByAppendingPathExtension:@"m4v"];
    if (![filemgr fileExistsAtPath:slink]) {
        NSError *error = nil;
        [filemgr createSymbolicLinkAtPath:[_filePath stringByAppendingPathExtension:@"m4v"] withDestinationPath: _filePath error: &error];
        if (error) {
            ...
        }
    }
    ...
    

    通过slink播放视频

    【讨论】:

    • 小心。当应用进入后台时,SymbolicLink 将被删除 :(
    • 这仅适用于本地文件。该问题询问没有文件扩展名的远程 URL。
    【解决方案5】:

    如果播放器无法猜测文件格式,您需要检查 CDN 是否发回了正确的 mime 类型。我的猜测是您的 CDN 无法正确猜测 mimetype,播放器也无法正确猜测。

    在大多数情况下,这是由于 CDN 呈现 HTTP 标头的方式。 检查“Content-Type”标头是否设置为与您的内容匹配的视频格式。

    【讨论】:

    • 我的服务器返回内容类型 video/mp4,我的文件也是一个有效的 H.264 编码的 mp4 文件,但 AVPlayer 没有文件扩展名就无法播放。这是 Swift 3 五年后的事了。还有什么问题吗?
    【解决方案6】:

    迪伦是正确的。

    MPMoviePlayer 和 AVPlayer 都需要文件扩展名才能从 URL 播放文件,否则将显示错误消息。最好使用一些技巧。

    【讨论】:

    • 正如我在上面所说的那样,严格来说这并不正确 - 如果您的文件具有正确的 mime 类型,那么它将起作用。
    • 这不是真的 - 我经常播放没有任何文件名的视频。
    【解决方案7】:

    iPhone 支持 .mp4、.m4v、.mov 格式的视频 H.264、MPEG-4 以及 AAC、MP3、M4a、Apple 无损和 Audible 格式的音频文件。 您可以使用 NSFileManager 的 -contentsOfDirectoryAtPath:error: 方法来获取包含目录内容(作为字符串)的数组。然后您只需执行字符串操作。

    【讨论】:

    • 问题询问远程 URL。
    【解决方案8】:

    这有点像 hack,但您可以做的是通过一种方法运行每个名称,该方法检查其后有三个字符的句点。如果没有,只需自动附加 .m4v 即可。或者获取 MIME 类型并根据返回的类型自动附加扩展名。如果可供使用的话。使用 NSString 查找文档以获取更多信息。祝你好运!让我知道这是否有帮助。

    【讨论】:

      猜你喜欢
      • 2020-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-09
      • 1970-01-01
      • 2011-04-27
      • 1970-01-01
      相关资源
      最近更新 更多