完成按钮事件MPMoviePlayerController

29

我在iPhone上以全屏模式播放视频/音频文件。当视频/音频文件到达末尾时,会触发以下方法:

- (void) movieFinishedCallback:(NSNotification*) aNotification {
    MPMoviePlayerController *player = [aNotification object];

    [player stop];

    [[NSNotificationCenter defaultCenter] 
        removeObserver:self
        name:MPMoviePlayerPlaybackDidFinishNotification
        object:player];

    [player autorelease];
    [moviePlayer.view removeFromSuperview];

    NSLog(@"stopped?");
}

工作得很好!但是问题是当视频或音频文件仍在播放时,我按下“完成”按钮时就会出现问题。然后这个方法就不会触发了...

有人知道如何捕捉“完成”按钮被按下的事件吗?因为现在媒体播放器仍然停留在视图中,而没有消失。

7个回答

43

当我监听 MPMoviePlayerWillExitFullscreenNotification时,iPad 上它对我起作用。

[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(doneButtonClick:) 
                                             name:MPMoviePlayerWillExitFullscreenNotification 
                                           object:nil];

And 选择器方法:

-(void)doneButtonClick:(NSNotification*)aNotification{
    NSNumber *reason = [notification.userInfo objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];

    if ([reason intValue] == MPMovieFinishReasonUserExited) {
        // Your done button action here
    }
}

2
我的MPMovieplayer样式是全屏。现在点击“完成”按钮 - 视频只会暂停,而不会通知MPMoviePlayerWillExitFullscreenNotification。有什么想法吗? - ruyamonis346
值得注意的是,我不得不在我的视图控制器中创建一个属性才能使它正常工作... MPMoviePlayerController *moviePlayer = 是不起作用的。 - Magoo
@Rajneesh071 使用MPMoviePlayerPlaybackDidFinishNotification代替。 @Magoo 没有属性也可以工作(已在iOS 8.3上测试)。 - derpoliuk

21

检查通知userInfo字典中的枚举

NSNumber *reason = [notification.userInfo objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];

if ([reason intValue] == MPMovieFinishReasonUserExited) {

   // done button clicked!

}

所选答案已经集成了我的回答,请参考上文。


5
观察者是:MPMoviePlayerPlaybackDidFinishNotification。 - user523234

17

在iOS7和iOS8中成功测试

检查并删除早期的通知观察器(如果有)MPMoviePlayerPlaybackDidFinishNotification

- (void)playVideo:(NSString*)filePath
{
     // Pass your file path
        NSURL *vedioURL =[NSURL fileURLWithPath:filePath];
        MPMoviePlayerViewController *playerVC = [[MPMoviePlayerViewController alloc] initWithContentURL:vedioURL];

    // Remove the movie player view controller from the "playback did finish" notification observers
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:MPMoviePlayerPlaybackDidFinishNotification
                                                  object:playerVC.moviePlayer];

    // Register this class as an observer instead
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(movieFinishedCallback:)
                                                 name:MPMoviePlayerPlaybackDidFinishNotification
                                               object:playerVC.moviePlayer];

    // Set the modal transition style of your choice
    playerVC.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;

    // Present the movie player view controller
    [self presentViewController:playerVC animated:YES completion:nil];

    // Start playback
    [playerVC.moviePlayer prepareToPlay];
    [playerVC.moviePlayer play];
}

关闭控制器

- (void)movieFinishedCallback:(NSNotification*)aNotification
{
    // Obtain the reason why the movie playback finished
    NSNumber *finishReason = [[aNotification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];

    // Dismiss the view controller ONLY when the reason is not "playback ended"
    if ([finishReason intValue] != MPMovieFinishReasonPlaybackEnded)
    {
        MPMoviePlayerController *moviePlayer = [aNotification object];

        // Remove this class from the observers
        [[NSNotificationCenter defaultCenter] removeObserver:self
                                                        name:MPMoviePlayerPlaybackDidFinishNotification
                                                      object:moviePlayer];

        // Dismiss the view controller
        [self dismissViewControllerAnimated:YES completion:nil];
    }
}

你完成了!!!


2
[self dismissModalViewControllerAnimated:YES]; 更改为 [self dismissViewControllerAnimated:YES completion:nil]; 可以避免在 iOS 8 上出现“过时警告(deprecation warning)”。谢谢! - Gene Z. Ragan
发现为什么它不起作用了。您需要将removeObserver:playerVC更改为removeObserver:self。 - Zia

2

对于任何感兴趣的人,以下是Swift版本:

NSNotificationCenter.defaultCenter().addObserver(self, selector: "moviePlayerDoneButtonClicked:", name: MPMoviePlayerPlaybackDidFinishNotification, object: nil)

通知处理程序:

func moviePlayerDoneButtonClicked(note: NSNotification) {

    let reason = note.userInfo?[MPMoviePlayerPlaybackDidFinishReasonUserInfoKey]
    if (MPMovieFinishReason(rawValue: reason as! Int) == MPMovieFinishReason.UserExited) {
        self.exitVideo()
    }
}

2
@property (nonatomic, strong) MPMoviePlayerController *moviePlayer;

[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(doneButtonClick:) 
                                             name:MPMoviePlayerDidExitFullscreenNotification 
                                           object:nil];

- (void)doneButtonClick:(NSNotification*)aNotification
{
    if (self.moviePlayer.playbackState == MPMoviePlaybackStatePaused)
    {
        NSLog(@"done button tapped");
    }
    else
    {
        NSLog(@"minimize tapped");
    }
}

问题在于,如果用户暂停视频,然后点击“最小化”按钮,doneButtonClick: 逻辑就会出错。有人找到了一种方法来区分视频处于暂停状态时的“完成”和“最小化”吗? - jbolter

1

0

苹果的文档在这个问题上非常糟糕。它建议监听 MPMoviePlayerDidExitFullscreenNotification(或 WillExit...),而不是 MPMoviePlayerDidFinishNotification,因为当用户点击“完成”时,后者不会触发。这完全不正确!我刚刚在 Xcode 6.0 上使用 iPad 模拟器(iOS 7.1 + 8.0)进行了测试,只有 MPMoviePlayerDidFinishNotification 在点击“完成”时被触发。

向 user523234 表示赞赏,他在上面的评论中说得对。

注册以下观察者:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(playbackStateChanged:)
                                        name:MPMoviePlayerPlaybackDidFinishNotification
                                           object:_mpc];

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