从videoAVFoundation中提取audio

func extractAudioFromVideo(videoUrl:NSURL, audioPath:String){ //2 var asset = AVURLAsset(URL: videoUrl, options: nil) asset.loadValuesAsynchronouslyForKeys(NSArray(object: "tracks") as [AnyObject], completionHandler: { () -> Void in var audioTrack = asset.tracksWithMediaType(AVMediaTypeAudio)[0] as! AVAssetTrack var audioComposition = AVMutableComposition() var audioCompositionTrack:AVMutableCompositionTrack! audioCompositionTrack = audioComposition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID()) audioCompositionTrack.insertTimeRange(audioTrack.timeRange, ofTrack: audioTrack, atTime: CMTimeMake(0, 1), error: nil) var exportSession = AVAssetExportSession(asset: audioComposition, presetName: AVAssetExportPresetAppleM4A) var toFileUrl = NSURL(fileURLWithPath: audioPath) exportSession.outputURL = toFileUrl exportSession.outputFileType = "com.apple.m4a-audio" exportSession.exportAsynchronouslyWithCompletionHandler({ () -> Void in if exportSession.status == AVAssetExportSessionStatus.Completed { println("Succes") }else{ println("not working") } }) }) } 

我使用上面的代码从video获取audio,但它打印“不工作”

我的audiopath是:

var outStr = NSBundle.mainBundle().pathForResource("cheeseburger", ofType: "m4a")

请在这件事上给予我帮助

谢谢

以下是基于Anton的答案,但已经更新了Swift 3.0

 extension AVAsset { func writeAudioTrack(to url: URL, success: @escaping () -> (), failure: @escaping (Error) -> ()) { do { let asset = try audioAsset() asset.write(to: url, success: success, failure: failure) } catch { failure(error) } } private func write(to url: URL, success: @escaping () -> (), failure: @escaping (Error) -> ()) { guard let exportSession = AVAssetExportSession(asset: self, presetName: AVAssetExportPresetAppleM4A) else { let error = NSError(domain: "domain", code: 0, userInfo: nil) failure(error) return } exportSession.outputFileType = AVFileTypeAppleM4A exportSession.outputURL = url exportSession.exportAsynchronously { switch exportSession.status { case .completed: success() case .unknown, .waiting, .exporting, .failed, .cancelled: let error = NSError(domain: "domain", code: 0, userInfo: nil) failure(error) } } } private func audioAsset() throws -> AVAsset { let composition = AVMutableComposition() let audioTracks = tracks(withMediaType: AVMediaTypeAudio) for track in audioTracks { let compositionTrack = composition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid) do { try compositionTrack.insertTimeRange(track.timeRange, of: track, at: track.timeRange.start) } catch { throw error } compositionTrack.preferredTransform = track.preferredTransform } return composition } } 

要调用它,您将需要创build一个URL目标,并为要创build的文件指定m4a的文件扩展名。

 let asset = AVAsset(url: url) let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("audio.m4a") 

然后,你叫扩展,并依靠不同的closures来处理成功和失败。 在这个例子中的error handling是非常原始的,所以你在实现它时会想要改进它。

 asset.writeAudioTrack(to: url, success: { print("Success") }) { (error) in print(error.localizedDescription) } 

从我的项目

 extension AVAsset { func writeAudioTrackToURL(URL: NSURL, completion: (Bool, NSError?) -> ()) { do { let audioAsset = try self.audioAsset() audioAsset.writeToURL(URL, completion: completion) } catch (let error as NSError){ completion(false, error) } catch { print("\(self.dynamicType) \(__FUNCTION__) [\(__LINE__)], error:\(error)") } } func writeToURL(URL: NSURL, completion: (Bool, NSError?) -> ()) { guard let exportSession = AVAssetExportSession(asset: self, presetName: AVAssetExportPresetAppleM4A) else { completion(false, nil) return } exportSession.outputFileType = AVFileTypeAppleM4A exportSession.outputURL = URL exportSession.exportAsynchronouslyWithCompletionHandler { switch exportSession.status { case .Completed: completion(true, nil) case .Unknown, .Waiting, .Exporting, .Failed, .Cancelled: completion(false, nil) } } } func audioAsset() throws -> AVAsset { let composition = AVMutableComposition() let audioTracks = tracksWithMediaType(AVMediaTypeAudio) for track in audioTracks { let compositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid) do { try compositionTrack.insertTimeRange(track.timeRange, ofTrack: track, atTime: track.timeRange.start) } catch { throw error } compositionTrack.preferredTransform = track.preferredTransform } return composition } } 

像这样使用

 let url = NSBundle.mainBundle().URLForResource("video", withExtension: "m4v")! let asset = AVURLAsset(URL: url, options: nil) asset.writeAudioTrackToURL(NSURL(fileURLWithPath: pathTo)) { (success, error) -> () in if !success { print(error) } }