2015-11-23 6 views
5

Ich streame Audio mit AVPlayer. Es funktioniert gut. Aber jetzt muss ich einen Schieberegler machen, um Audio vorwärts und rückwärts zu bewegen, wie ein typischer Musik-Player. Ich habe die Funktion seekToTime benutzt, die gut mit der lokalen Audiodatei funktioniert. Aber wenn ich Lied von Web-URL streame, stoppt die Funktion Audio, wenn ich Schieberegler mit einem großen Bereich weiterleite.SeekToTime in AVPlayer stoppt die Wiedergabe von Streaming-Audio, wenn vorwärts

Meine Vermutung ist, dass der Song heruntergeladen wird und wenn ich Slider mit großer Reichweite vorwärts bewegen, dann kann das System die Song-Datenpakete für diese Zeit nicht heruntergeladen haben, so dass es Player stoppt.

Sagen wir, ich habe gerade einen Knopf gedrückt, um den Song zu streamen, aber jetzt verschiebe ich den Schieberegler sofort auf 0 bis 100 Sekunde. In diesem Fall funktioniert das System nicht und stoppt den Player. Wegen fehlender Datenpakete für diese Zeit.

Hat jemand wissen, wie man dieses Problem löst oder gibt es einen anderen Ansatz. Ich verwende SWIFT für die Entwicklung. Ich bin auch bereit, irgendeine Bibliothek zu benutzen, wenn es in swift funktionieren würde. Das ist meine Funktion:

func forward() { 
    timeGap = slider.value 
    let preferredTimeScale : Int32 = 1 
    let targetTime : CMTime = CMTimeMake(timeGap, preferredTimeScale) 

    player.seekToTime(targetTime, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero) 

} 

Vielen Dank im Voraus.

Antwort

8

Diese Antwort basiert auf diesem Text: https://stackoverflow.com/a/7195954/765298. Jeder Kredit sollte dorthin gehen, da dies nur eine schnelle Übersetzung ist.

Sie haben recht, wenn Sie weit nach vorne zu einem Teil suchen, der noch nicht gepuffert wurde, stoppt der Spieler. Die Sache puffert noch die Daten, aber startet nicht automatisch, wenn es fertig ist. Also, die verknüpfte Antwort auf rasche umformulieren:

So richten Sie Ihre Beobachter:

player.currentItem?.addObserver(self, forKeyPath: "playbackBufferEmpty", options: .New, context: nil) 
player.currentItem?.addObserver(self, forKeyPath: "playbackLikelyToKeepUp", options: .New, context: nil) 

Beachten Sie, dass, um der Lage sein, Werte zu beobachten, die übergebenen self Bedürfnisse von NSObject erben.

Und mit ihnen umgehen:

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { 

    guard keyPath != nil else { // a safety precaution 
     super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context) 
     return 
    } 

    switch keyPath! { 
     case "playbackBufferEmpty" : 
      if player.currentItem!.playbackBufferEmpty { 
       print("no buffer") 
       // do something here to inform the user that the file is buffering 
      } 

     case "playbackLikelyToKeepUp" : 
      if player.currentItem!.playbackLikelyToKeepUp { 
       self.player.play() 
       // remove the buffering inidcator if you added it 
      } 
    } 
} 

Sie können auch zur Zeit AVPlayerItem spielen Informationen über verfügbare Zeit reichen von der get (Sie kann es über player.currentItem acces können, wenn man es nicht selbst erstellt hat). Dadurch können Sie dem Benutzer anzeigen, welche Teile der Datei bereit sind.

Wie immer können Sie einige mehr in der Dokumentation lesen: AVPlayerItem und AVPlayer

Um mehr über Schlüssel-Wert-Beobachtung (KVO) zu lesen: here

+0

Ich habe bemerkt, dass, wenn ich ein Live-Video der Stream starten Puffer ist von Anfang an leer ('playbackBufferEmpty == true') und das playbackBufferEmpty-Flag ändert seinen Zustand niemals in false. Gibt es eine Möglichkeit, die Pufferung mit AVFoundation manuell zu starten? – svrs

Verwandte Themen