MPMoviePlayerControllerprepareToPlay 不适用于 HTTP 实时流媒体

发布于 2024-12-07 04:21:48 字数 4844 浏览 0 评论 0原文

我正在尝试使用模态视图控制器内的 MPMoviePlayerController 对象来播放 HTTP 实时流视频。如果我像这样运行代码,一切都会正常。我收到 MPMoviePlaybackStatePlaying 通知,然后视频开始播放。

- (void)viewDidLoad {
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self  selector:@selector(moviePlayerPlaybackStateDidChange:)  name:MPMoviePlayerPlaybackStateDidChangeNotification  object:nil];

    NSURL *url = [NSURL URLWithString:@"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"];
    self.moviePlayerController = [[[MPMoviePlayerController alloc] initWithContentURL:url] autorelease]; 
    self.moviePlayerController.view.frame = CGRectMake(0,0,320,416);
    self.moviePlayerController.controlStyle = MPMovieControlStyleNone;
    self.moviePlayerController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self.view addSubview:self.moviePlayerController.view];  
    self.moviePlayerController.fullscreen = NO;  
    [self.moviePlayerController play]; 
}

我更喜欢使用 prepareToPlay 方法,这样我就可以显示加载指示器,并获得更好的体验。但是,我似乎无法让这个工作。不会调用任何 MPMoviePlayerPlaybackStateDidChangeNotification,并且流不会播放。活动指示器就在那里永远旋转。

我已经确认 prepareToPlay 确实被调用,但此后似乎没有发生任何其他事情。我还确认此代码适用于本地电影文件。似乎 HTTP Live Streaming 失败了。谁能看到我做错了什么吗?

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.activityIndicator startAnimating];

    [[NSNotificationCenter defaultCenter] addObserver:self  selector:@selector(moviePlayerPlaybackStateDidChange:)  name:MPMoviePlayerPlaybackStateDidChangeNotification  object:nil];

    NSURL *url = [NSURL URLWithString:@"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"];
    self.moviePlayerController = [[[MPMoviePlayerController alloc] initWithContentURL:url] autorelease]; 

    [self registerForMovieNotifications]; 
}

- (void)registerForMovieNotifications {
    //movie is ready to play notifications
    if ([self.moviePlayerController respondsToSelector:@selector(loadState)]) {
        //this is a 3.2+ device
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerLoadStateChanged:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil];       
        self.moviePlayerController.movieSourceType = MPMovieSourceTypeStreaming;
        [self.moviePlayerController prepareToPlay];
    } else {
        //pre-3.2 device
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePreloadDidFinish:) name:MPMoviePlayerContentPreloadDidFinishNotification object:nil];
    }

    //movie has finished notification
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayBackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
}

- (void) moviePlayerPlaybackStateDidChange:(NSNotification*)notification {
    NSLog(@"playbackDidChanged");
    MPMoviePlayerController *moviePlayer = notification.object;
    MPMoviePlaybackState playbackState = moviePlayer.playbackState;
    if(playbackState == MPMoviePlaybackStateStopped) {
        NSLog(@"MPMoviePlaybackStateStopped");
    } else if(playbackState == MPMoviePlaybackStatePlaying) {
        NSLog(@"MPMoviePlaybackStatePlaying");
    } else if(playbackState == MPMoviePlaybackStatePaused) {
        NSLog(@"MPMoviePlaybackStatePaused");
    } else if(playbackState == MPMoviePlaybackStateInterrupted) {
        NSLog(@"MPMoviePlaybackStateInterrupted");
    } else if(playbackState == MPMoviePlaybackStateSeekingForward) {
        NSLog(@"MPMoviePlaybackStateSeekingForward");
    } else if(playbackState == MPMoviePlaybackStateSeekingBackward) {
        NSLog(@"MPMoviePlaybackStateSeekingBackward");
    }
}

//3.2+ devices
- (void)moviePlayerLoadStateChanged:(NSNotification*)notification {
    NSLog(@"load state changed");

    //unless state is unknown, start playback
    if ([self.moviePlayerController loadState] != MPMovieLoadStateUnknown) {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerLoadStateDidChangeNotification object:nil];

        self.moviePlayerController.view.frame = CGRectMake(0,0,320,416);
        self.moviePlayerController.controlStyle = MPMovieControlStyleNone;
        self.moviePlayerController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        [self.view addSubview:self.moviePlayerController.view];  
        self.moviePlayerController.fullscreen = NO;  
        [self.moviePlayerController play]; 
    }
}

//pre 3.2 devices
- (void) moviePreloadDidFinish:(NSNotification*)notification  {
    // Remove observer
    [[NSNotificationCenter  defaultCenter] removeObserver:self name:MPMoviePlayerContentPreloadDidFinishNotification object:nil];
    [self.moviePlayerController play];
}

I'm trying to play an HTTP live streaming video using a MPMoviePlayerController object, inside a modal view controller. If I run the code like this, everything works fine. I get a MPMoviePlaybackStatePlaying notification, and the video plays.

- (void)viewDidLoad {
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self  selector:@selector(moviePlayerPlaybackStateDidChange:)  name:MPMoviePlayerPlaybackStateDidChangeNotification  object:nil];

    NSURL *url = [NSURL URLWithString:@"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"];
    self.moviePlayerController = [[[MPMoviePlayerController alloc] initWithContentURL:url] autorelease]; 
    self.moviePlayerController.view.frame = CGRectMake(0,0,320,416);
    self.moviePlayerController.controlStyle = MPMovieControlStyleNone;
    self.moviePlayerController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self.view addSubview:self.moviePlayerController.view];  
    self.moviePlayerController.fullscreen = NO;  
    [self.moviePlayerController play]; 
}

I would prefer to use the prepareToPlay method, so that I can show a loading indicator, and for a nicer experience. However, I don't seem to be able to get this working. No MPMoviePlayerPlaybackStateDidChangeNotification ever gets called, and the stream doesn't play. The activity indicator just sits there spinning forever.

I've confirmed that prepareToPlay does get called, but nothing else seems to happen after that. I've also confirmed that this code works fine with a local movie file. It just seems to be with HTTP Live Streaming which fails. Can anyone see what I'm doing wrong?

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.activityIndicator startAnimating];

    [[NSNotificationCenter defaultCenter] addObserver:self  selector:@selector(moviePlayerPlaybackStateDidChange:)  name:MPMoviePlayerPlaybackStateDidChangeNotification  object:nil];

    NSURL *url = [NSURL URLWithString:@"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"];
    self.moviePlayerController = [[[MPMoviePlayerController alloc] initWithContentURL:url] autorelease]; 

    [self registerForMovieNotifications]; 
}

- (void)registerForMovieNotifications {
    //movie is ready to play notifications
    if ([self.moviePlayerController respondsToSelector:@selector(loadState)]) {
        //this is a 3.2+ device
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerLoadStateChanged:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil];       
        self.moviePlayerController.movieSourceType = MPMovieSourceTypeStreaming;
        [self.moviePlayerController prepareToPlay];
    } else {
        //pre-3.2 device
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePreloadDidFinish:) name:MPMoviePlayerContentPreloadDidFinishNotification object:nil];
    }

    //movie has finished notification
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayBackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
}

- (void) moviePlayerPlaybackStateDidChange:(NSNotification*)notification {
    NSLog(@"playbackDidChanged");
    MPMoviePlayerController *moviePlayer = notification.object;
    MPMoviePlaybackState playbackState = moviePlayer.playbackState;
    if(playbackState == MPMoviePlaybackStateStopped) {
        NSLog(@"MPMoviePlaybackStateStopped");
    } else if(playbackState == MPMoviePlaybackStatePlaying) {
        NSLog(@"MPMoviePlaybackStatePlaying");
    } else if(playbackState == MPMoviePlaybackStatePaused) {
        NSLog(@"MPMoviePlaybackStatePaused");
    } else if(playbackState == MPMoviePlaybackStateInterrupted) {
        NSLog(@"MPMoviePlaybackStateInterrupted");
    } else if(playbackState == MPMoviePlaybackStateSeekingForward) {
        NSLog(@"MPMoviePlaybackStateSeekingForward");
    } else if(playbackState == MPMoviePlaybackStateSeekingBackward) {
        NSLog(@"MPMoviePlaybackStateSeekingBackward");
    }
}

//3.2+ devices
- (void)moviePlayerLoadStateChanged:(NSNotification*)notification {
    NSLog(@"load state changed");

    //unless state is unknown, start playback
    if ([self.moviePlayerController loadState] != MPMovieLoadStateUnknown) {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerLoadStateDidChangeNotification object:nil];

        self.moviePlayerController.view.frame = CGRectMake(0,0,320,416);
        self.moviePlayerController.controlStyle = MPMovieControlStyleNone;
        self.moviePlayerController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        [self.view addSubview:self.moviePlayerController.view];  
        self.moviePlayerController.fullscreen = NO;  
        [self.moviePlayerController play]; 
    }
}

//pre 3.2 devices
- (void) moviePreloadDidFinish:(NSNotification*)notification  {
    // Remove observer
    [[NSNotificationCenter  defaultCenter] removeObserver:self name:MPMoviePlayerContentPreloadDidFinishNotification object:nil];
    [self.moviePlayerController play];
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

睡美人的小仙女 2024-12-14 04:21:48

我不知道为什么,但我能够通过将行 self.movi​​ePlayerController.controlStyle = MPMovieControlStyleNone; 移出 moviePlayerLoadStateChanged: 方法并移入来解决此问题viewDidLoad 方法。

任何人都知道为什么这会产生影响吗?

I don't know why, but I was able to solve this by moving the line self.moviePlayerController.controlStyle = MPMovieControlStyleNone; out of the moviePlayerLoadStateChanged: method, and into the viewDidLoad method.

Anyone have any ideas why this made a difference?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文