ios 没有 AVPlayer 代表?歌曲播放完毕后如何追踪?Objective C iPhone开发

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6837002/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:53:03  来源:igfitidea点击:

No AVPlayer Delegate? How to track when song finished playing? Objective C iPhone development

iosobjective-ciphoneavplayeravplayerviewcontroller

提问by Tyler

I've looked around but I can't find a delegate protocol for the AVPlayer class. What gives?

我环顾四周,但找不到AVPlayer class. 是什么赋予了?

I'm using its subclass, AVQueuePlayer, to play an array of AVPlayerItems, each loaded from a URL. Is there any way I can call a method when a song finishes playing? Notably at the end of the queue?

我正在使用它的子类 ,AVQueuePlayer来播放 的数组AVPlayerItems,每个都从一个 URL 加载。有什么方法可以在歌曲播放完毕后调用方法吗?特别是在队列的末尾?

And if that's not possible, is there any way I could call a method when the song STARTS playing, after buffering? I'm trying to get a loading icon in there but it turns the icon off before the music actually begins, even though it's after the [audioPlayer play]action.

如果这是不可能的,有什么办法可以在歌曲开始播放时在缓冲后调用方法吗?我试图在那里获得一个加载图标,但它在音乐真正开始之前关闭了图标,即使它是在[audioPlayer play]动作之后。

回答by arexx

Yes, the AVPlayer class does not have a delegate protocol like the AVAudioPlayer. You need to subscribe to notifications on an AVPlayerItem. You can create an AVPlayerItem using the same URL that you would otherwise pass to -initWithURL:on AVPlayer.

是的,AVPlayer 类没有像 AVAudioPlayer 那样的委托协议。您需要订阅 AVPlayerItem 上的通知。您可以使用-initWithURL:在 AVPlayer 上传递的相同 URL 创建一个AVPlayerItem。

-(void)startPlaybackForItemWithURL:(NSURL*)url {

    // First create an AVPlayerItem
    AVPlayerItem* playerItem = [AVPlayerItem playerItemWithURL:url];

    // Subscribe to the AVPlayerItem's DidPlayToEndTime notification.
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];

    // Pass the AVPlayerItem to a new player
    AVPlayer* player = [[[AVPlayer alloc] initWithPlayerItem:playerItem] autorelease];

    // Begin playback
    [player play]

} 

-(void)itemDidFinishPlaying:(NSNotification *) notification {
    // Will be called when AVPlayer finishes playing playerItem
}

回答by Daij-Djan

Yes. Add a KVO observer to the player's status or rate:

是的。将 KVO 观察者添加到玩家的状态或速率:

- (IBAction)go {
   self.player = .....
   self.player.actionAtItemEnd = AVPlayerActionStop;
   [self.player addObserver:self forKeyPath:@"rate" options:0 context:0]; 
}

- (void)stopped {
    ...
    [self.player removeObserver:self]; //assumes we are the only observer
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if (context == 0) {
        if(player.rate==0.0) //stopped
            [self stopped];
    }
    else
        [super observeVal...];
}

So basically, that's it.

所以基本上,就是这样。

Disclaimer: I wrote that in here so I didn't check if the code was good. ALSO I never used AVPlayer before but it should be about right.

免责声明:我在这里写的,所以我没有检查代码是否好。另外我以前从未使用过 AVPlayer,但它应该是正确的。

回答by budidino

Swift 3- I add an observer to AVPlayerItemevery time I add a video to the player:

Swift 3-AVPlayerItem每次向播放器添加视频时,我都会添加一个观察者:

func playVideo(url: URL) {
  let playerItem = AVPlayerItem(asset: AVURLAsset(url: someVideoUrl))
  NotificationCenter.default.addObserver(self, selector: #selector(playerItemDidPlayToEndTime), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: playerItem)
  self.player.replaceCurrentItem(with: playerItem)
  self.player.play()
}

func playerItemDidPlayToEndTime() {
  // load next video or something
}

回答by Paul.s

There is a lot of information in the Apple docs AVFoundation Programming Guide(look for the monitoring playback section). It appears to be mainly through KVO so you may wish to brush up on that if you are not too familiar (there is a guide for that to Key Value Observing ProgrammingGuide.

Apple docs AVFoundation Programming Guide(查找监控播放部分)中有很多信息。它似乎主要是通过 KVO 实现的,因此如果您不太熟悉,您可能希望重温它(有一个指南可以用于Key Value Observing ProgrammingGuide

回答by Timur Mustafaev

I'm using this one, and it works:

我正在使用这个,它有效:

_player = [[AVPlayer alloc]initWithURL:[NSURL URLWithString:_playingAudio.url]];
CMTime endTime = CMTimeMakeWithSeconds(_playingAudio.duration, 1);
timeObserver = [_player addBoundaryTimeObserverForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:endTime]] queue:NULL usingBlock:^(void) {
    [_player removeTimeObserver:timeObserver];
    timeObserver = nil;
    //TODO play next sound
}];
[self play];

where _playingAudiois my custom class with some properties and timeObserveris idivar.

_playingAudio我的具有某些属性的自定义类在哪里,并且timeObserveridivar。