我正在开发一款应用程序,让我可以通过iPhone远程在iPad上播放不同的视频。我一直在关注视频播放器的苹果示例,但我遇到了一些麻烦。视频播放得很好,我可以从各种视频播放,但在它们之间切换几次会崩溃,我在调试器中得到这个:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An AVPlayerItem cannot be associated with more than one instance of AVPlayer'
*** First throw call stack:
(0x380da8bf 0x37c261e5 0x30acbcb5 0x30abc1f7 0x30ac3bf3 0x30c93d55 0x30c95f7b 0x380ad2dd 0x380304dd 0x380303a5 0x37e07fcd 0x31bb0743 0x25e5 0x257c)
这是我用来创建播放器的代码:
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentOfURL:movieURL];
if (player) {
[self setMoviePlayerController:player];
[self installMovieNotificationObservers];
[player setContentURL:movieURL];
[player setMovieSourceType:sourceType];
[self applyUserSettingsToMoviePlayer];
[self.view addSubview:self.backgroundView];
[player.view setFrame:self.view.bounds];
[player.view setBackgroundColor = [UIColor blackColor];
[self.view addSubview:player.view];
}
当前电影停止时,我使用:
[[self moviePlayerController] stop];
MPMoviePlayerController *player = [self moviePlayerController];
[player.view removeFromSuperview];
[self removeMovieNotificationHandlers];
[self setMoviePlayerController:nil];
编辑: 所以我现在发现每次尝试切换视频时都会发生这种情况。奇怪的!我几乎把头发拉了出来。
答案 0 :(得分:7)
解决这个问题的原因是在执行setContentURL之前停止了MPMoviePlayerController。
MPMoviePlayerController *streamPlayer;
[streamPlayer stop];
[streamPlayer setContentURL:[NSURL URLWithString:selectedStation]];
答案 1 :(得分:1)
在上面的实现中,ARC不知道MPMoviePlayerController已经完成并且需要被释放。
在.h文件中定义MPMoviePlayerController,并通过@property(和@synthesize)访问它。
@property (strong, nonatomic) MPMoviePlayerController * moviePlayerController;
然后取你的分配和结果init并将其分配给它。即。
self.moviePlayerController = [[MPMoviePlayerController alloc] initWithContentOfURL:movieURL];
答案 2 :(得分:1)
你应该保留moviePlayerController,如果你想播放另一个视频,只需使用
[self.moviePlayerController setContentURL:movieURL];
然后在你的通知回调中:
- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
self.moviePlayer = nil;
[self initanothermovieplayerandplay];
}
请不要从通知中心删除通知处理程序,只在VC的dealloc方法中执行此操作。
现在让我们在电影播放完成后添加一些淡入淡出:
- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
[UIView animateWithDuration:1
delay: 0.0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
// one second to fade out the view
self.moviePlayer.view.alpha = 0.0;
}
completion:^(BOOL finished){
self.moviePlayer = nil;
[self initanothermovieplayerandplay];
}
}
答案 3 :(得分:1)
我有完全相同的问题。 没有什么问题,我猜你的代码:) 只是一个破碎的视频文件是我的问题。 将* .mov类型更改为m4a例如修复它。也许您播放的一个或多个文件已损坏? 尝试找出导致崩溃的文件,以及如果你可以尝试在播放时快速向后快速向前移动其中一个文件的播放位置 - 这应该会导致几次尝试崩溃。 这就是我发现坏文件的方式。顺便说一句,我所有的坏文件都是用Snapz Pro X制作的电影.mov。
答案 4 :(得分:0)
不确定是否是这种情况,但是我们遇到了很多问题,因为MPMoviePlayer是一个单一的地方。
我们所做的是,我们实现了自己的MoviePlayer
包装器,它可以从UIView中使用(实际上我们只有一个UIView MoviePlayerView
的子类来显示电影)并确保只有{{1的一个实例存在。代码是这样的(它包含一些特殊的东西,我们需要以我们想要的方式显示预览/拇指等等。你应该清理以及一些发布语句):
MPMoviePlayerController
答案 5 :(得分:0)
...
player = [[MPMoviePlayerController alloc] initWithContentURL: [NSURL URLWithString:...
...
但我没有给手机上网(wi-fi):)
答案 6 :(得分:0)
我遇到了同样的问题。我的解决方案是使用prepareToPlay:
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentOfURL:movieURL];
if (player) {
[player prepareToPlay];
//...
}
答案 7 :(得分:0)
由于许多不同的原因,似乎抛出了这个错误,但我发现的原因是,如果按特定顺序调用方法,MPMoviePlayerController类就会出现问题。来自IRC频道:
“显然,如果你调用prepareToPlay WHILE设置源类型和 不设置视图会导致此崩溃“
所以我通过确保调用prepareToPlay:
LAST(或倒数第二个,最后一个为play:
)来解决这个问题。
这也很奇怪,因为我的原始代码在iOS 5.1中运行,但是当我开始使用iOS 6.0 sdk时,这个问题突然出现了。它可能是MPMoviePlayerController代码中的一个错误,因此我将在其上提交雷达报告,因为在设置视图/设置之前调用prepareToPlay:
sourceFileType
不应该抛出异常(或至少是一个看似与实际错误无关的异常)