简体   繁体   English

如何使用 MPMoviePlayerController 或 AVPlayer 在 iOS 上播放没有文件扩展名的电影文件?

[英]How to play movie files with no file extension on iOS with MPMoviePlayerController or AVPlayer?

I want to play a movie in iOS 4.3 on the iPad.我想在 iPad 上的 iOS 4.3 中播放电影。 I've successfully used MPMoviePlayerController and AVPlayer to load files from a remote URL when the filename has a file extension.当文件名具有文件扩展名时,我已成功使用 MPMoviePlayerController 和 AVPlayer 从远程 URL 加载文件。 However, when I use a CDN that doesn't return the filename (just an un-guessable random name), neither MPMoviePlayerController or AVPlayer seem to be able to cope.但是,当我使用不返回文件名(只是一个不可猜测的随机名称)的 CDN 时,MPMoviePlayerController 或 AVPlayer 似乎都无法应对。

Is there a way to tell either player that it really is a movie of type x and it should just get on playing it?有没有办法告诉任何一个玩家它真的是一部 x 类型的电影,它应该继续播放它?

MPMoviePlayerController will return the following error from it's changed state notification: MPMoviePlayerController 将从它的状态更改通知中返回以下错误:

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

I know that file is a valid m4v file, as when I rename it all is fine.我知道该文件是一个有效的 m4v 文件,因为当我重命名它时一切正常。

File at tmp文件在 tmp

NSString* _filePath

Create symlink创建符号链接

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) {
        ...
    }
}
...

play video by slink通过slink播放视频

If the player can't guess the file format you need to check that the CDN sends the right mime type back.如果播放器无法猜测文件格式,您需要检查 CDN 是否发送回正确的 mime 类型。 My guess is that your CDN can't guess the mimetype correctly nor can the player.我的猜测是您的 CDN 无法正确猜测 mimetype,播放器也无法正确猜测。

In most cases this is due to how the CDN presents the HTTP header.在大多数情况下,这是由于 CDN 呈现 HTTP 标头的方式。 Check that the "Content-Type" header is set to a video format matching your content.检查“Content-Type”标题是否设置为与您的内容匹配的视频格式。

WebKit handle this by a Private AVURLAsset option: AVURLAssetOutOfBandMIMETypeKey , this option is used when you specify a MIME type in the HTML's video tag, WebKit 通过Private AVURLAsset 选项处理此问题: AVURLAssetOutOfBandMIMETypeKey ,当您在 HTML 的video标签中指定 MIME 类型时使用此选项,

You can use this option like:您可以使用此选项,例如:

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]];

Since it is a private key, you may want to obfuscate it if you plan to submit it to AppStore.由于它是一个私钥,如果您打算将其提交到 AppStore,您可能需要对其进行混淆。

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

If you have problems to get the ContentType of your connection you could cycle through the playable MIME types and create symbolic links to the actual file with the extension and check if they are playable.如果您在获取连接的 ContentType 时遇到问题,您可以循环播放可播放的 MIME 类型并创建指向具有扩展名的实际文件的符号链接,并检查它们是否可播放。 Like so:像这样:

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;
        }
    }

}

iPhone support video H.264, MPEG-4 in .mp4, .m4v, .mov formats and audio files in AAC, MP3, M4a, Apple lossless and Audible. iPhone 支持 .mp4、.m4v、.mov 格式的视频 H.264、MPEG-4 和 AAC、MP3、M4a、Apple 无损和 Audible 格式的音频文件。 You can use NSFileManager's -contentsOfDirectoryAtPath:error: method to get an array with the contents of a directory (as strings).Then you just do strings operations .您可以使用 NSFileManager 的 -contentsOfDirectoryAtPath:error: 方法来获取包含目录内容的数组(作为字符串)。然后您只需执行字符串操作。

Dylan is correct.迪伦是对的。

Both MPMoviePlayer and AVPlayer needs a file extension in order to play the file from URL otherwise an error message will be shown. MPMoviePlayer 和 AVPlayer 都需要文件扩展名才能从 URL 播放文件,否则将显示错误消息。 Better to use some kind of tricks.最好使用某种技巧。

Finally, I found the answer.终于,我找到了答案。

You should use AVURLAsset (the subclass of AVAsset) and set the MIMEType in the options input :您应该使用 AVURLAsset(AVAsset 的子类)并在选项输入中设置 MIMEType:

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

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

It's sort of a hack, but what you could do is run each name through a method that checks for a period with three characters after it.这有点像黑客,但您可以做的是通过一种方法来运行每个名称,该方法检查后面是否有三个字符的句点。 If not, just append .m4v automatically.如果没有,只需自动附加 .m4v。 Or get the MIME type and append an extension automatically based on the returned type.或者获取 MIME 类型并根据返回的类型自动附加扩展名。 If available.如果可供使用的话。 Look up documentation with NSString for more info.使用 NSString 查找文档以获取更多信息。 Good luck!祝你好运! Let me know if that helped.如果这有帮助,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM