Possiedo una classe AVPlayer che esegue il flusso di un file audio. È un po 'lungo, quindi non posso pubblicare tutto qui. Quello su cui sono bloccato è come consentire all'utente di riprodurre il file audio dopo aver finito di ascoltarlo una volta. Quando termina la prima volta, ricevo correttamente una notifica AVPlayerItemDidPlayToEndTimeNotification
. Quando vado a riprodurlo, ricevo immediatamente la stessa notifica, che mi impedisce di riprodurlo.Riproduzione di AVPlayer/AVPlayer senza nuovo download
Come posso resettare questo in modo che AVPlayerItem
non pensi di aver già riprodotto il file audio? Potrei deallocare tutto e riprogettarlo, ma credo che costringerebbe l'utente a scaricare di nuovo il file audio, che è inutile e lento.
Ecco alcune parti della classe che ritengo rilevanti. L'output che ottengo quando si tenta di riprodurre il file è simile a questo. Le prime due linee sono esattamente ciò che mi aspetterei, ma la terza è una sorpresa.
sta giocando
nessun timer
lettore audio ha terminato la riproduzione di 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;
}
Qualche progresso su questo? Sto affrontando un problema simile (con un video però) Dopo aver passato AVPlayerItemDidPlayToEndTimeNotification non è possibile riprodurre l'elemento. La mia soluzione attuale è quella di creare un nuovo Item + Player, ma questo ridistribuisce l'intera cosa – eyeballz
@eyeballz - No. Per il momento, sto solo rinfacciandolo e poi riprendendo. Difficilmente una buona soluzione, ma è il meglio che posso fare per ora. Se trovi qualcosa, per favore pubblica. – Alex
Ok, ho funzionato per me, ma il suo video non è audio. Il problema con il video sembrava essere il fatto che devi tenere anche il PlayerLayer, ma non hai un livello di questo tipo per l'audio. – eyeballz