【问题标题】:No AVPlayer Delegate? How to track when song finished playing? Objective C iPhone development没有 AVPlayer 代表?如何跟踪歌曲何时播放完毕? Objective C iPhone 开发
【发布时间】:2011-07-26 21:45:56
【问题描述】:

我环顾四周,但找不到AVPlayer class 的委托协议。什么给了?

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

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

【问题讨论】:

    标签: ios objective-c iphone avplayer avplayerviewcontroller


    【解决方案1】:

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

    -(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
    }
    

    【讨论】:

    • 请务必使用itemDidFinishPlaying:,例如带冒号。来自NSNotificationCenter 文档:notificationSelector 指定的方法必须只有一个参数(NSNotification 的实例)。
    • @RudolfAdamkovic 感谢您的注意 - 我已经相应地编辑了我的答案。
    【解决方案2】:

    是的。为玩家的状态或速率添加一个 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...];
    }
    

    基本上,就是这样。

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

    【讨论】:

    • 如何删除@"rate"观察者?
    • 我在编辑中被告知我需要确定观察速率。适应
    • 这种方法的一个问题是它会认为停顿是音乐的结束。暂停时的速率与结束时一样为零。
    【解决方案3】:

    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
    }
    

    【讨论】:

      【解决方案4】:

      Apple 文档AVFoundation Programming Guide 中有很多信息(查找监控回放部分)。它似乎主要是通过 KVO 实现的,所以如果您不太熟悉,可能需要复习一下(Key Value Observing ProgrammingGuide 有相关指南。

      【讨论】:

      • 谢谢,首先我通过 KVO 监控时间让它工作,但后来我实现了 AVPlayerItemDidPlayToEndTimeNotification,因为它更干净且处理器密集度更低。
      • NSNotificationCenter、KVO 和基于块的疯狂组合。下定决心,Apple!
      【解决方案5】:

      我正在使用这个,它可以工作:

      _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];
      

      _playingAudio 是我的自定义类,其中包含一些属性,timeObserverid ivar。

      【讨论】:

        猜你喜欢
        • 2017-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多