2011-07-26 16 views
76

Tôi đã xem xét xung quanh nhưng tôi không thể tìm thấy giao thức đại biểu cho số AVPlayer class. Đưa cái gì?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 Phát triển iPhone C

Tôi đang sử dụng phân lớp của nó, AVQueuePlayer, để phát một mảng gồm AVPlayerItems, mỗi được tải từ một URL. Có cách nào tôi có thể gọi một phương pháp khi một bài hát kết thúc chơi 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 phương thức khi bài hát STARTS phát, sau khi đệm không? Tôi đang cố gắng để có được một biểu tượng tải trong đó nhưng nó biến biểu tượng ra trước khi âm nhạc thực sự bắt đầu, mặc dù nó sau khi hành động [audioPlayer play].

Trả lời

1

Có rất nhiều thông tin trong tài liệu của Apple AVFoundation Programming Guide (tìm phần phát lại theo dõi). Dường như chủ yếu là thông qua KVO, do đó bạn có thể muốn ghi rõ điều đó nếu bạn không quá quen thuộc (có hướng dẫn cho điều đó đến Key Value Observing ProgrammingGuide.

+4

Cảm ơn, đầu tiên tôi nhận nó làm việc bằng cách giám sát thời gian qua KVO nhưng sau đó tôi thực hiện các AVPlayerItemDidPlayToEndTimeNotification vì nó sạch hơn và ít xử lý hơn. – Tyler

+0

Một chút pha trộn điên rồ của NSNotificationCenter, KVO và dựa trên khối trong đó. Làm cho tâm trí của bạn lên Apple! – CupawnTae

7

Có. 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ì vậy, về cơ bản, đó là nó

Disclaimer:. tôi đã viết rằng ở đây vì vậy tôi đã không kiểm tra xem mã là tốt cŨNG tôi không bao giờ sử dụng AVPlayer trước nhưng nó phải là về quyền

..
+0

@downvoter: xin vui lòng để lại một bình luận –

+0

Làm thế nào để loại bỏ @ "tỷ lệ" quan sát? –

+0

Tôi được cho biết trong 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 –

141

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 
} 
+0

Điều này là tốt, nhưng không xử lý tạm dừng. –

+1

Đảm bảo sử dụng 'itemDidFinishPlaying:', ví dụ: với ruột kết. Từ tài liệu 'NSNotificationCenter': _Phương thức được chỉ định bởi notificationSelector phải có một và chỉ một đối số (một ví dụ' NSNotification') ._ –

+0

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

1

Tôi đang sử dụng thế 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]; 

nơi _playingAudio là lớp tùy chỉnh của tôi với một số tài sản và timeObserverid Ivar.

1

Swift 3 - tôi thêm một người quan sát để AVPlayerItem mỗi khi tôi thêm một đoạn video để người chơi:

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

Rất cám ơn, thưa bạn. Câu trả lời đã làm các trick cho tôi :-) –