MPMoviePlayerController 无法播放本地文件,出现错误 _itemFailedToPlayToEnd。

3

我有一个本地的iPhone兼容的MP4视频(我已经将视频转换为iPhone格式,并测试了将视频上传到web服务器并将其URL输入移动Safari,视频可以完美播放),我想使用MPMoviePlayerController播放。

这是我的代码:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Welcome" ofType:@"mp4"];
NSURL *fileURL = [NSURL URLWithString:filePath];
playerController = [[MPMoviePlayerController alloc] initWithContentURL:fileURL];
playerController.movieSourceType = MPMovieSourceTypeFile;
playerController.backgroundView.backgroundColor = [UIColor whiteColor];

playerController.view.translatesAutoresizingMaskIntoConstraints = YES;
playerController.scalingMode = MPMovieScalingModeAspectFill;
//[playerController.view setFrame:moviePlayerContainerView.frame];
[playerController.view setFrame:CGRectMake(0, 0, 200, 200)];
[moviePlayerContainerView addSubview:playerController.view];
playerController.contentURL = fileURL;
playerController.fullscreen = YES;
[playerController prepareToPlay];
[playerController play];

fileURL指向一个有效的文件:

(lldb) po fileURL
/var/mobile/Applications/73C97CC9-731E-4446-A53C-2A8CA30A2393/Tanisalim.app/Welcome.mp4
(lldb) p (BOOL)[[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:NO]
(BOOL) $0 = YES

当我尝试在模拟器上运行(无论是6.1还是7.1),它只会在框架中显示一个黑屏(如果全屏是NO),或者打开一个电影播放器视图控制器并永远停留在“加载...”状态。当我在设备上运行(iOS 7.1)时,行为相同,但我在控制台上得到以下错误:

_itemFailedToPlayToEnd: {
    kind = 1;
    new = 2;
    old = 0;
}

当我尝试直接从网页加载相同的视频文件进行流媒体播放时,它完美地工作:
//playerController.contentURL = fileURL;
playerController.contentURL = [NSURL URLWithString:@"http://mywebsite.com/Welcome.mp4"];

我尝试了不同的视频文件,但结果都一样。我做错了什么?

2个回答

9
我曾经遇到过完全相同的问题,但是在我的情况下,这个问题比较复杂。
  • 请确保使用-fileURLWithPath:而不是-URLWithString:来创建您的URL,就像@tagy22所提到的那样。在许多情况下,这似乎可以解决问题,但在我的情况下,我已经使用了文件URL,所以可能还有其他问题。
  • 请确保本地文件具有扩展名(例如“.mp4”)。MPMoviePlayerController不喜欢没有扩展名的文件。如果您需要存储没有扩展名的文件,则可以创建一个临时符号链接指向实际文件,并将该符号链接的文件URL提供给MPMoviePlayerController,而不是“真实”的文件。
  • 您的符号链接应位于iOS的Caches目录(~/Library/Caches)中的某个位置,否则可能无法正常工作。我试图让MPMoviePlayerController播放位于临时目录中的符号链接,在模拟器中可以工作,但在我的设备上无法工作。

创建指向实际视频文件的符号链接

NSError *error;
NSFileManager *manager = [NSFileManager defaultManager];
[manager createSymbolicLinkAtURL:linkPath withDestinationURL:actualFilePath error:&error];

谢谢,这对我有用 - 我保存和加载时必须添加“.mp4”。 - Alex Stone
谢谢你提醒我必须放在缓存目录下 - 我真的以为自己疯了(我太愚蠢了,还把符号链接创建在temp目录而不是caches目录里)。 - BarrettJ
@AlexStone 对我来说,符号链接创建返回true,但MPMoviePlayerViewController抛出错误“Error Domain=NSPOSIXErrorDomain Code=2" No such file or directory”。有什么线索吗?除了createSymbolicLinkAtURL方法的返回值之外,有没有确认符号链接存在的方法? - geekoraul
很难说,但我会检查符号链接创建和读取文件时的绝对路径是否相同,并确保两者都是文件URL。您还可以使用NSFileManager检查符号链接是否存在。 - Form

8

我曾遇到过类似的问题,可以很好地流式传输文件,但无法播放本地文件。以下更改解决了我的问题:

NSURL *fileURL = [NSURL URLWithString:filePath];

to:

NSURL *fileURL = [NSURL fileURLWithPath:filePath];

那确实是一个有价值的见解。 - matt
1
实际上,如果 OP 一开始就调用了 URLForResource:withExtension:,即提前获取 NSURL 而不是获取 NSString 并错误地转换为 NSURL,则整个问题本可以避免。 - matt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接