29

我想在 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 文件,因为当我重命名它时一切正常。

4

8 回答 8

9

文件在 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播放视频

于 2013-05-08T14:58:09.537 回答
5

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

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

于 2012-03-31T11:44:08.383 回答
4

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

您可以使用此选项,例如:

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

于 2018-02-02T09:11:30.213 回答
1

迪伦是对的。

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

于 2012-03-09T09:11:38.747 回答
1

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

于 2011-09-22T09:30:37.783 回答
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

于 2020-07-01T06:18:04.090 回答
1

如果您在获取连接的 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;
        }
    }

}
于 2016-08-26T12:46:13.083 回答
0

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

于 2011-08-13T08:42:43.987 回答