Không có đại biểu AVPlayer? Làm thế nào để theo dõi khi bài hát kết thúc chơi? Mục tiêu C phát triển iPhone


84

Tôi đã xem xét xung quanh nhưng không thể tìm thấy giao thức ủy quyền cho AVPlayer class. Đưa cái gì?

Tôi đang sử dụng lớp con của nó AVQueuePlayer, để chơi một mảng AVPlayerItems, mỗi lớp được tải từ một URL. Có cách nào tôi có thể gọi một phương thức khi một bài hát phát xong không? Đáng chú ý là ở cuối hàng đợi?

Và nếu điều đó là không thể, có cách nào tôi có thể gọi một phương thức khi bài hát STARTS đang phát, sau khi đệm không? Tôi đang cố gắng lấy biểu tượng đang tải ở đó nhưng nó tắt biểu tượng trước khi nhạc thực sự bắt đầu, mặc dù đó là sau [audioPlayer play]hành động.

Câu trả lời:


152

Có, lớp AVPlayer không có giao thức đại biểu như AVAudioPlayer. Bạn cần đăng ký nhận thông báo trên AVPlayerItem. Bạn có thể tạo một AVPlayerItem bằng cách sử dụng cùng một URL mà bạn sẽ chuyển đến -initWithURL:trên AVPlayer.

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

1
Hãy chắc chắn sử dụng itemDidFinishPlaying:, ví dụ: với dấu hai chấm. Từ NSNotificationCentertài liệu: Phương thức được chỉ định bởi notificationSelector phải có một và chỉ một đối số (ví dụ của NSNotification).
Rudolf Adamkovič

@RudolfAdamkovic Cảm ơn bạn đã lưu ý - Tôi đã chỉnh sửa câu trả lời của mình cho phù hợp.
arexx

8

Đúng. Thêm người quan sát KVO vào trạng thái hoặc tỷ lệ của người chơi:

- (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...];
}

Về cơ bản, đó là nó.

Tuyên bố từ chối trách nhiệm: Tôi đã viết điều đó ở đây nên tôi không kiểm tra xem mã có tốt không. CŨNG tôi chưa bao giờ sử dụng AVPlayer trước đây nhưng nó sẽ đúng.


Làm thế nào để loại bỏ trình quan sát @ "rate"?
Saumil Shah

Tôi đã được nói trong một bản chỉnh sửa rằng tôi cần phải quan sát tỷ lệ chắc chắn. thích nghi
Daij-Djan

4
Một vấn đề với cách tiếp cận này là nó sẽ nghĩ rằng một khoảng dừng là kết thúc của âm nhạc. Tỷ lệ khi tạm dừng bằng 0 như khi kết thúc.
C6Silver

5

Swift 3 - Tôi thêm một người quan sát AVPlayerItemmỗi khi tôi thêm video vào trình phát:

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
}

1

Có rất nhiều thông tin trong Hướng dẫn lập trình AVFoundation của Apple docs (tìm phần theo dõi phát lại). Nó dường như chủ yếu thông qua KVO, vì vậy bạn có thể muốn tìm hiểu về điều đó nếu bạn không quá quen thuộc (có một hướng dẫn cho điều đó đối với Key Value Observing ProgrammingGuide .


4
Cảm ơn, đầu tiên tôi đã làm cho nó hoạt động bằng cách theo dõi thời gian thông qua KVO nhưng sau đó tôi đã triển khai AVPlayerItemDidPlayToEndTimeNotification vì nó sạch hơn và ít tốn bộ xử lý hơn.
Tyler

1
Một chút hỗn hợp điên rồ của NSNotificationCenter, KVO và dựa trên khối trong đó. Hãy quyết tâm lên Apple!
CupawnTae

1

Tôi đang sử dụng cái này và nó hoạt động:

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

đâu _playingAudiolà lớp tùy chỉnh của tôi với một số thuộc tính và timeObserveridivar.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.