2017-06-06 2 views
2

Ich versuche, die URL, die in meinem Audio-Player ist zu einem AVAsset zu konvertieren, so dass ich in der Lage bin, die Audiospur nach meinem Geschmack zu manipulieren. (Ich möchte nur in der Lage sein, die Datei zu schneiden). Leider tritt ein Problem auf, bei dem das Asset nicht korrekt konvertiert wird. Wenn ich die Dauer der Audio-URL vor dem Konvertieren drucke, wird die Dauer korrekt ausgedruckt. Leider, wenn ich es in den AVAsset umwandle, heißt es, die Dauer ist 0. Was ist los? Jede Anleitung würde sehr geschätzt werden!Umwandlung der URL in AVAsset - Swift

func trimmingFunc() { 

     try? audioPlayer = AVAudioPlayer(contentsOf: audioURL!) 
     passingTime = audioPlayer.duration 
     audioPlayer.delegate = self 


     let currentDuration = audioPlayer.duration 
     print(currentDuration) //correctly prints duration 
     let filePath = URL(fileURLWithPath: (("\(String(describing: audioPlayer.url!))"))) 
     print(filePath) //correctly prints filePath 


     let currentAsset = AVAsset(url: filePath) 
     print(CMTimeGetSeconds(currentAsset.duration) //This is printing 0 

} 
+0

'Aufgrund der Art zeitgesteuerter audiovisueller Medien sind bei der erfolgreichen Initialisierung eines Assets einige oder alle Werte für seine Schlüssel möglicherweise nicht sofort verfügbar." (Https://developer.apple.com/documentation/avfoundation/ avasset) –

+0

also heißt das, ich müsste die Dauer berechnen & meine Audiodatei im Completion-Handler trimmen/manipulieren? B/C was ich aus mehreren Beispielen gesehen habe (nicht dass sie für mich funktionieren) ist, dass sie die Informationen vor dem Beendigungshandler berechnen. – AndrewS

+0

Sie können KVO verwenden ('[_currentAsset addObserver: self für KeyPath: @" duration "' + 'beobachten Sie ValueForKeyPath') –

Antwort

2

Laden einer AVAsset ist asynchroner Betrieb. Sie sollten warten, bis es vorbereitet ist. Die effizienteste Art zu warten ist KVO.

In Ihrer Klasse, es ViewController, AVAsset das Mitglied machen sein lassen und Ihre trimmingFunc irgendwo anrufen:

class ViewController: UIViewController { 

    var currentAsset: AVAsset? 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     self.trimmingFunc() 
    } 
.... 

In Ihrem trimmingFunc, abonnieren für Meldungen currentAsset:

func trimmingFunc() { 

    let audioURL = URL.init(fileURLWithPath: Bundle.main.path(forResource: "Be That Man", ofType: "mp3")!) 

    print("audioURL=\(audioURL)") 
    currentAsset = AVAsset(url: audioURL) 
    let options = NSKeyValueObservingOptions([.new, .old, .initial, .prior]) 
    currentAsset!.addObserver(self, forKeyPath: "duration", options: options, context: nil) 
} 

zu Empfangen Sie diese Benachrichtigungen, überschreiben Sie die Funktion von NSObject:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { 

    print("\(keyPath): \(change?[.newKey])") 

    print(CMTimeGetSeconds(currentAsset!.duration)) //This is printing 0 
} 

Also, wenn Sie Datei hatte "sein, dass Man.mp3" in Ressourcen, nach wenigen Millisekunden würden Sie duration = 202,945306122449

Voll Code von Viewcontroller ist here sehen.

+0

Warum würde dies als optional angezeigt werden? 'Optional (" Dauer "): Optional (<00000000 00000000 01000000 01000000 00000000 00000000>)' Meine Dauer endet bei 0 – AndrewS

+0

Die URL wird jedoch korrekt ausgedruckt – AndrewS

Verwandte Themen