AVPlayer 대리인이 없습니까? 노래 재생이 끝나면 추적하는 방법은 무엇입니까? Objective C iPhone 개발


84

주위를 둘러 보았지만 .NET Framework에 대한 위임 프로토콜을 찾을 수 없습니다 AVPlayer class. 무엇을 제공합니까?

나는 각각 URL에서로드 된 AVQueuePlayer배열을 재생하기 위해 하위 클래스를 사용하고 AVPlayerItems있습니다. 노래 재생이 끝나면 메서드를 호출 할 수있는 방법이 있습니까? 특히 대기열 끝에 있습니까?

그리고 그것이 가능하지 않다면, 버퍼링 후 노래가 재생되기 시작할 때 메서드를 호출 할 수있는 방법이 있습니까? 나는 거기에 로딩 아이콘을 가져 오려고하는데, 그것이 [audioPlayer play]액션 이후에도 음악이 실제로 시작되기 전에 아이콘이 꺼진다 .

답변:


152

예, AVPlayer 클래스에는 AVAudioPlayer와 같은 위임 프로토콜이 없습니다. AVPlayerItem에 대한 알림을 구독해야합니다. AVPlayer에서 전달하는 것과 동일한 URL을 사용하여 AVPlayerItem을 만들 수 있습니다 -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
}

1
itemDidFinishPlaying:예를 들어 콜론과 함께 사용하십시오 . 에서 NSNotificationCenter문서 : notificationSelector로 지정하는 방법은 오직 하나의 인수 (의 인스턴스가 있어야합니다 NSNotification).
Rudolf Adamkovič 2013

@RudolfAdamkovic 메모 주셔서 감사합니다-그에 따라 내 대답을 편집했습니다.
arexx

8

예. 플레이어의 상태 또는 비율에 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"관찰자를 제거하는 방법?
Saumil Shah

나는 편집에서 확실히 비율을 관찰해야한다고 들었다. 적응
Daij-Djan

4
이 접근 방식의 문제점은 일시 중지가 음악의 끝이라고 생각한다는 것입니다. 일시 정지 속도는 끝날 때처럼 0입니다.
C6Silver

5

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
}

1

Apple docs AVFoundation Programming Guide 에 많은 정보가 있습니다 (모니터링 재생 섹션을 찾으십시오). 주로 KVO를 통해 이루어지는 것으로 보이므로 너무 익숙하지 않은 경우이를 다듬고 싶을 수 있습니다 ( Key Value Observing ProgrammingGuide에 대한 가이드가 있습니다.


4
감사합니다. 먼저 KVO를 통해 시간을 모니터링하여 작동했지만 AVPlayerItemDidPlayToEndTimeNotification이 더 깨끗하고 프로세서 집약적이지 않기 때문에 구현했습니다.
Tyler

1
NSNotificationCenter, KVO 및 블록 기반이 약간 섞여 있습니다. Apple을 마음에 새기십시오!
CupawnTae

1

나는 이것을 사용하고 있으며 작동합니다.

_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내 사용자 정의 클래스는 일부 속성으로하고 timeObserver있다 id바르.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.