2015-01-07 45 views
9

我有一個AVPlayer類,所有設置流的音頻文件。這有點長,所以我不能在這裏發佈整個事情。我堅持的是如何讓用戶在完成一次收聽後重播音頻文件。當它第一次完成時,我正確地收到通知AVPlayerItemDidPlayToEndTimeNotification。當我去重放它時,我立即收到相同的通知,阻止我重播它。重播AVPlayerItem/AVPlayer無需重新下載

如何重置此設置使AVPlayerItem不認爲它已經播放過音頻文件?我可以重新分配所有內容並重新設置它,但我相信這會強制用戶再次下載音頻文件,這是毫無意義和緩慢的。

以下是我認爲相關的一些類的部分。嘗試重播文件時得到的輸出如下所示。前兩行是我期望的,但第三行是一個驚喜。

播放
沒有計時器
音頻播放器播放完畢音頻

- (id) initWithURL : (NSString *) urlString 
{ 
    self = [super init]; 
    if (self) { 
     self.isPlaying = NO; 
     self.verbose = YES; 

     if (self.verbose) NSLog(@"url: %@", urlString); 
     NSURL *url = [NSURL URLWithString:urlString]; 

     self.playerItem = [AVPlayerItem playerItemWithURL:url]; 
     self.player = [[AVPlayer alloc] initWithPlayerItem:self.playerItem]; 

     [self determineAudioPlayTime : self.playerItem]; 

     self.lengthOfAudioInSeconds = @0.0f; 

     [self.player addObserver:self forKeyPath:@"status" options:0 context:nil]; 

     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.playerItem]; 
    } 

    return self; 
} 

// this is what gets called when the user clicks the play button after they have 
// listened to the file and the AVPlayerItemDidPlayToEndTimeNotification has been received 
- (void) playAgain { 
    [self.playerItem seekToTime:kCMTimeZero]; 
    [self toggleState]; 
} 

- (void) toggleState { 
    self.isPlaying = !self.isPlaying; 

    if (self.isPlaying) { 
     if (self.verbose) NSLog(@"is playing"); 
     [self.player play]; 

     if (!timer) { 
      NSLog(@"no timer"); 
      CMTime audioTimer = CMTimeMake(0, 1); 
      [self.player seekToTime:audioTimer]; 

      timer = [NSTimer scheduledTimerWithTimeInterval:1.0 
                target:self 
                selector:@selector(updateProgress) 
                userInfo:nil 
                repeats:YES]; 
     } 

    } else { 
     if (self.verbose) NSLog(@"paused"); 
     [self.player pause]; 
    } 
} 

-(void)itemDidFinishPlaying:(NSNotification *) notification { 
    if (self.verbose) NSLog(@"audio player has finished playing audio"); 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"audioFinished" object:self]; 
    [timer invalidate]; 
    timer = nil; 
    self.totalSecondsPlayed = [NSNumber numberWithInt:0]; 
    self.isPlaying = NO; 
} 
+0

這方面的進展如何?我面臨類似的問題(儘管有視頻) AVPlayerItemDidPlayToEndTimeNotification通過後,您無法重放該項目。我目前的解決方法是創建一個新的Item + Player,但是這只是重新下載整個事情。 – eyeballz

+0

@eyeballz - 不。暫時,我只是釋放它,然後重新實例化。幾乎不是一個好的解決方案,但是現在我可以做的最好。如果你想出點東西,請發帖。 – Alex

+0

好吧,我得到它爲我工作,但其視頻不音頻。視頻問題似乎是你必須保持PlayerLayer,但你沒有任何地方的音頻層。 – eyeballz

回答

10

可以調用seekToTime方法時,您的播放器收到AVPlayerItemDidPlayToEndTimeNotification

func itemDidFinishPlaying() { 
    self.player.seekToTime(kCMTimeZero) 
    self.player.play() 
} 
-1

我建議使用AVQueueplayer。這是在15:00在這裏的視頻講話:https://developer.apple.com/videos/play/wwdc2016/503/

這是原生重播的最佳選擇,並討論了爲什麼。

+1

「Apple說XYZ最適合本地人」是一個相當簡單的答案。請儘可能地總結鏈接的視頻的論點。 –

相關問題