2015-01-07 19 views
9

Mam całą klasę AVPlayer, która strumieniuje plik audio. Trochę jest długa, więc nie mogę tutaj opublikować tego wszystkiego. Utknąłem na tym, jak zezwolić użytkownikowi na powtórne odtwarzanie pliku audio po zakończeniu jego słuchania. Kiedy zakończy się po raz pierwszy, poprawnie otrzymam powiadomienie AVPlayerItemDidPlayToEndTimeNotification. Kiedy je odtwarzam, natychmiast otrzymuję to samo powiadomienie, które blokuje mi ponowne odtwarzanie.Odtwarzanie AVPlayerItem/AVPlayer bez ponownej instalacji

Jak mogę zresetować tak, że AVPlayerItem nie myśli, że już odtworzył plik audio? Mogę zwolnić wszystko i skonfigurować go ponownie, ale uważam, że zmusiłoby to użytkownika do ponownego pobrania pliku audio, co jest bezsensowne i powolne.

Oto niektóre części zajęć, które moim zdaniem są istotne. Wynik, który otrzymam podczas próby odtworzenia pliku, wygląda następująco. Pierwsze dwie linie są dokładnie tym, czego oczekiwałbym, ale trzeci jest niespodzianką.

gra
No timer
odtwarzacz audio zakończyło Odtwarzanie audio

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

Wszelkie postępy w tej sprawie? Mam podobny problem (z wideo) Po przejściu AVPlayerItemDidPlayToEndTimeNotification nie można powtórzyć elementu. Moje bieżące obejście polega na utworzeniu nowego Item + Playera, ale to po prostu ponownie pobiera całą całość. – eyeballz

+0

@eyeballz - Nie. Na razie po prostu zwalniam to, a następnie ponownie instaluję. Nie jest to dobre rozwiązanie, ale na razie najlepsze, co mogę zrobić. Jeśli coś wymyślisz, opublikuj. – Alex

+0

Ok, mam to działa dla mnie, ale jego wideo nie jest audio. Problem z wideo wydawał się być taki, że musisz zachować PlayerLayer, ale nie masz warstwy tego rodzaju w dowolnym miejscu dla audio. – eyeballz

Odpowiedz

10

można wywołać metodę seekToTime gdy gracz otrzymał AVPlayerItemDidPlayToEndTimeNotification

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

Proponuję za pomocą AVQueueplayer. To jest głośno o 15:00 w wideo tutaj: https://developer.apple.com/videos/play/wwdc2016/503/

Jest to najlepsza opcja dla odtwarzania natywnego i jest omówione dlaczego.

+1

"Apple mówi, że XYZ jest najlepszy dla native" to całkiem minimalna odpowiedź. Podsumuj argumenty dołączonego filmu tutaj, najlepiej jak potrafisz. –

Powiązane problemy