2014-02-24 18 views
7

Arbeits Ich habe den folgenden Code:AVPlayer seekToTime: rückwärts nicht

AVPlayerItem *currentItem = [AVPlayerItem playerItemWithURL:soundURL]; 
[self.audioPlayer replaceCurrentItemWithPlayerItem:currentItem]; 
[self.audioPlayer play]; 

wo soundURL ein remoteURL ist. Es funktioniert gut. Die spielt die Musik perfekt. Ich habe einen Fortschrittsbalken und ich aktualisiere ihn basierend auf der aktuellen Zeit des Spielers.

Alles funktioniert gut. Mein Problem ist, wenn ich den Fortschrittsbalken nach vorne verschiebe, startet die audioplayer von der neuen Position, aber wenn ich die progressbar ziehen wird es nicht von der neuen Position in der Tat beginnt es von der vorherigen Position fortgesetzt. Hier ist meine Fortschrittsbalken ziehen Start und Stop-Code:

- (IBAction)progressBarDraggingStart:(id)sender 
{ 
    if (self.audioPlayer.rate != 0.0) 
    { 
      [self.audioPlayer pause]; 
    } 
} 

- (IBAction)progressBarDraggindStop:(id)sender 
{ 
    CMTime newTime = CMTimeMakeWithSeconds(self.progressBar.value, 1); 
    [self.audioPlayer seekToTime:newTime]; 
    [self.audioPlayer play]; 
} 

Kann mir jemand helfen, dieses Problem zu beheben?

+0

Haben Sie versucht, mit 'seekToTime: completionHandler:' oder 'seekToTime: toleranceBefore: toleranceAfter:'? – Corey

+0

@corey: Ja, ich habe beide versucht, aber kein Glück. Das Fertigstellungsflag completionHandler gibt false zurück. Wissen Sie, wie Sie warten müssen, bis das fertige Flag im Beendigungshandler wahr wird? –

Antwort

7

Ich schlage vor, ein paar Dinge zu tun. Zuerst, erhalten Sie den timescale Wert und übergeben Sie es an die CMTime Struktur. Zweitens, verwenden Sie die seekToTime:toleranceBefore:toleranceAfter:completionHandler: Methode für genauere Suche. Zum Beispiel würde der Code wie folgt aussehen:

- (IBAction)progressBarDraggindStop:(id)sender { 
    int32_t timeScale = self.audioPlayer.currentItem.asset.duration.timescale; 

    [self.audioPlayer seekToTime: CMTimeMakeWithSeconds(self.progressBar.value, timeScale) 
       toleranceBefore: kCMTimeZero 
        toleranceAfter: kCMTimeZero 
       completionHandler: ^(BOOL finished) { 
        [self.audioPlayer play]; 
       }]; 
} 
+0

Ich habe Ihren Code gerade jetzt und habe die folgende Ausnahme - "*** Beenden App aufgrund der nicht abgefangenen Ausnahme 'NSInvalidArgumentException', Grund: 'Ich suche nicht Zeit {INVALID}" –

+0

Was ist die' timeScale' Wert, den Sie bekommen? Versuchen Sie auch, den Wert "self.progressBar.value" und den Wert "CMTimeMakeWithSeconds" zu protokollieren. – Corey

+0

Hier sind die Werte: Zeitskala = 0, Progressbar Wert = 281.286560, CMTIme = (null) –

1

ich für dragging- Added completionHandler nach @ Corey Antwort unten Code verwende und es funktioniert super ohne Web-Service-Abhängigkeit:

- (void) sliderValueChanged:(id)sender { 
    if ([sender isKindOfClass:[UISlider class]]) { 
     UISlider *slider = sender; 

     CMTime playerDuration = self.avPlayer.currentItem.duration; 
     if (CMTIME_IS_INVALID(playerDuration)) { 
      return; 
     } 

     double duration = CMTimeGetSeconds(playerDuration); 
     if (isfinite(duration)) { 
      float minValue = [slider minimumValue]; 
      float maxValue = [slider maximumValue]; 
      float value = [slider value]; 

      double time = duration * (value - minValue)/(maxValue - minValue); 

      [self.avPlayer seekToTime:CMTimeMakeWithSeconds(time, NSEC_PER_SEC) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:^(BOOL finished) { 
       [self.avPlayer play]; 
      }]; 
     } 
    } 
}