IOS电影播放器播放一次视频后的未知加载状态MPMoviePlayerController

IOS电影播放器播放一次视频后的未知加载状态MPMoviePlayerController,ios,objective-c,mpmovieplayercontroller,mpmovieplayer,Ios,Objective C,Mpmovieplayercontroller,Mpmovieplayer,我试图弄明白为什么在我播放了一次视频后,我会看到一个闪烁的黑屏。我发现当加载状态为MPMovieLoadStatePlayable时,就不会出现黑屏,视频可以顺利播放。但是,一旦加载状态变为MPMovieLoadStateUnknown,视频播放完毕后。我注意到,当加载状态未知时,会出现闪烁的黑屏,可能是因为它必须首先调用prepareToPlay 以下是我如何设置视频: - (void)setVideo:(PFObject *)aVideo { video = aVideo;

我试图弄明白为什么在我播放了一次视频后,我会看到一个闪烁的黑屏。我发现当加载状态为MPMovieLoadStatePlayable时,就不会出现黑屏,视频可以顺利播放。但是,一旦加载状态变为MPMovieLoadStateUnknown,视频播放完毕后。我注意到,当加载状态未知时,会出现闪烁的黑屏,可能是因为它必须首先调用prepareToPlay

以下是我如何设置视频:

- (void)setVideo:(PFObject *)aVideo {
    video = aVideo;

    if(self.moviePlayer) {
        self.moviePlayer = nil;
    }

    // Get the profile image
    PFUser *user = [self.video objectForKey:kFTPostUserKey];
    PFFile *profilePictureSmall = [user objectForKey:kFTUserProfilePicSmallKey];
    NSString *authorName = [user objectForKey:kFTUserDisplayNameKey];

    // Get the video file
    PFFile *videoFile = [video objectForKey:kFTPostVideoKey];
    NSURL *url = [NSURL URLWithString:videoFile.url];
    self.moviePlayer = [[MPMoviePlayerController alloc] init];
    [self.moviePlayer.view setFrame:CGRectMake(0.0f,0.0f,320.0f,320.0f)];
    [self.moviePlayer setControlStyle:MPMovieControlStyleNone];
    [self.moviePlayer setScalingMode:MPMovieScalingModeAspectFill];
    [self.moviePlayer setMovieSourceType:MPMovieSourceTypeFile];
    [self.moviePlayer setContentURL:url];
    [self.moviePlayer requestThumbnailImagesAtTimes:@[ @0.1f, @1.0f ] timeOption:MPMovieTimeOptionExact];
    [self.moviePlayer setShouldAutoplay:NO];
    [self.moviePlayer.view setBackgroundColor:[UIColor clearColor]];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(movieFinishedCallBack)
                                             name:MPMoviePlayerPlaybackDidFinishNotification
                                           object:self.moviePlayer];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(moviePlayerStateChange:)
                                             name:MPMoviePlayerPlaybackStateDidChangeNotification
                                           object:self.moviePlayer];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(loadStateDidChange:)
                                             name:MPMoviePlayerLoadStateDidChangeNotification
                                           object:self.moviePlayer];

}
以下是功能:

- (void)didTapVideoPlayButtonAction:(UIButton *)sender{
    [self.playButton setHidden:YES];
    [self.moviePlayer prepareToPlay];
    [self.moviePlayer requestThumbnailImagesAtTimes:@[ @0.1f, @1.0f ] timeOption:MPMovieTimeOptionExact];
    [self.moviePlayer play];
}

-(void)movieFinishedCallBack{
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                name:MPMoviePlayerPlaybackDidFinishNotification
                                              object:self.moviePlayer];

}

-(void)loadStateDidChange:(NSNotification *)notification{

    //NSLog(@"loadStateDidChange: %@",notification);

    if (self.moviePlayer.loadState == MPMovieLoadStatePlayable) {
        NSLog(@"loadState... MPMovieLoadStatePlayable");
    }

    if (self.moviePlayer.loadState == MPMovieLoadStatePlaythroughOK) {
        NSLog(@"loadState... MPMovieLoadStatePlaythroughOK");
    }

    if (self.moviePlayer.loadState == MPMovieLoadStateStalled) {
        NSLog(@"loadState... MPMovieLoadStateStalled");
    }

    if (self.moviePlayer.loadState == MPMovieLoadStateUnknown) {
       NSLog(@"loadState... MPMovieLoadStateUnknown");
       //[self.moviePlayer prepareToPlay];
    }
}

-(void)moviePlayerStateChange:(NSNotification *)notification{

    //NSLog(@"moviePlayerStateChange: %@",notification);

    if (self.moviePlayer.playbackState == MPMoviePlaybackStatePlaying){
        [self.imageView addSubview:self.moviePlayer.view];
    }

    if (self.moviePlayer.playbackState == MPMoviePlaybackStateStopped){
        NSLog(@"moviePlayer... Stopped");
        [self.playButton setHidden:NO];
        //[self.moviePlayer.view removeFromSuperview];
        [self.moviePlayer prepareToPlay];
    }

    if (self.moviePlayer.playbackState == MPMoviePlaybackStatePaused){
        NSLog(@"moviePlayer... Paused");
        [self.moviePlayer stop];
    }

    f (self.moviePlayer.playbackState == MPMoviePlaybackStateInterrupted){
        NSLog(@"moviePlayer... Interrupted");
        [self.moviePlayer stop];
    }

    if (self.moviePlayer.playbackState == MPMoviePlaybackStateSeekingForward){
        NSLog(@"moviePlayer... Forward");
    }

    if (self.moviePlayer.playbackState == MPMoviePlaybackStateSeekingBackward){
        NSLog(@"moviePlayer... Backward");
    }
}
我认为解决方案是,从声明中调用prepareToPlay: if(self.moviePlayer.loadState==MPMovieLoadStateUnknown)


我试过了,但这并没有让球员做好上场的准备。有什么想法/建议/帮助吗

视频可以播放一次,但以后不能再播放这一事实并不是MPMoviePlayerController的内置功能-我从来没有使用过MPMoviePlayerController这样的功能-所以你应该寻找其他可能发生的事情,以破坏你的MPMoviePlayerController的状态,例如将其
contentURL
更改为错误值(这通常是导致
MPLoadStateUnknown
的原因)。我想到两件事:

  • 我注意到,配置MPMoviePlayerController的方法不是普通的方法;事实上,它是属性的setter(
    video
    )。这可能与问题有关,因为这意味着每次任何代码在任何地方显示
    video=/…
    时,您都在运行此方法,这意味着拆下整个电影播放器并制作一个新的。现在假设其他地方的某个代码显示
    video=nil
    或其他一些错误值。这肯定会使您的movie player视图变黑并阻止进一步播放。我建议中断此方法以查看是否发生这种情况。然后设置更好的体系结构:setter应该只设置属性,而不是更多。电影播放器的配置应该只发生一次,并且需要以其自己的方法进行

  • 请注意,如果您意外地在MPMoviePlayerController上生成了多个。有一条法律规定,“只能有一个”——如果另一个MPMoviePlayerController出现并调用
    prepareToPlay
    ,则所有其他MPMoviePlayerController都将被禁用


(最后,尽管这不是问题的直接根源,但请注意,您确定的加载状态不正确。您使用的是相等,但这很容易失败,因为加载状态是位掩码;您必须使用逻辑和来比较掩码。)

首先,这个代码是错误的:
self.moviePlayer.loadState==/…
这不是确定加载状态的方式!加载状态是位掩码。您必须对特定掩码使用按位和,并检查零或非零。至于实际问题,
MPMovieLoadStateUnknown
通常意味着文件不正确在URL处找到。你能显示更多关于如何确定内容URL的信息吗?我添加了该函数。我正在传递一个包含视频的PFObject,并将视频文件设置为如下PFFile*videoFile=[video objectForKey:kFTPostVideoKey];视频存储在parse上,下面是一个示例URL,非常有启发性。您正在做一件非常奇怪的事情:整个方法是
video
属性的setter。这意味着每次任何代码在任何地方说
video=/…
时,您都在拆除整个电影播放器并制作一个新的。现在支持ose其他地方的一些代码会显示
video=nil
或其他不好的值。这肯定会使您的电影播放器视图变黑并阻止进一步播放。我建议中断此方法以查看是否发生这种情况。然后设置更好的体系结构:setter只需设置属性,而不需要更多。您完全正确关于黑屏的原因,我将重新设计设计,以确保我不会创建多个MPMoviePlayer。谢谢!太棒了!很高兴我能为您指出正确的方向。