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")
}
})
})
}
我正在使用上面的代码从视频中获取音频,但它正在打印"无法正常工作"
我的audioPath是:
var outStr = NSBundle.mainBundle().pathForResource("cheeseburger", ofType: "m4a")
请帮我解决这个问题
由于
答案 0 :(得分:6)
我重写了 Swift 4.0 的答案,因为有几个API更改了前一个。
import AVFoundation
extension AVAsset {
// Provide a URL for where you wish to write
// the audio file if successful
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) -> ()) {
// Create an export session that will output an
// audio track (M4A file)
guard let exportSession = AVAssetExportSession(asset: self,
presetName: AVAssetExportPresetAppleM4A) else {
// This is just a generic error
let error = NSError(domain: "domain",
code: 0,
userInfo: nil)
failure(error)
return
}
exportSession.outputFileType = .m4a
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 {
// Create a new container to hold the audio track
let composition = AVMutableComposition()
// Create an array of audio tracks in the given asset
// Typically, there is only one
let audioTracks = tracks(withMediaType: .audio)
// Iterate through the audio tracks while
// Adding them to a new AVAsset
for track in audioTracks {
let compositionTrack = composition.addMutableTrack(withMediaType: .audio,
preferredTrackID: kCMPersistentTrackID_Invalid)
do {
// Add the current audio track at the beginning of
// the asset for the duration of the source AVAsset
try compositionTrack?.insertTimeRange(track.timeRange,
of: track,
at: track.timeRange.start)
} catch {
throw error
}
}
return composition
}
}
然后,您调用扩展,并依赖不同的闭包来处理成功和失败。此示例中的错误处理非常原始,因此您需要在实现时进行改进。
asset.writeAudioTrack(to: url, success: {
print("Success")
}) { (error) in
print(error.localizedDescription)
}
答案 1 :(得分:1)
来自我的项目( Swift 4.1 )
import AVFoundation
extension AVAsset {
func writeAudioTrackToURL(_ url: URL, completion: @escaping (Bool, Error?) -> ()) {
do {
let audioAsset = try self.audioAsset()
audioAsset.writeToURL(url, completion: completion)
} catch (let error as NSError){
completion(false, error)
}
}
func writeToURL(_ url: URL, completion: @escaping (Bool, Error?) -> ()) {
guard let exportSession = AVAssetExportSession(asset: self, presetName: AVAssetExportPresetAppleM4A) else {
completion(false, nil)
return
}
exportSession.outputFileType = .m4a
exportSession.outputURL = url
exportSession.exportAsynchronously {
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 = tracks(withMediaType: .audio)
for track in audioTracks {
let compositionTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
try compositionTrack?.insertTimeRange(track.timeRange, of: track, at: track.timeRange.start)
compositionTrack?.preferredTransform = track.preferredTransform
}
return composition
}
}
像这样使用
let url = Bundle.main.url(forResource: "video", withExtension: "m4v")!
let asset = AVURLAsset(url: url, options: nil)
let pathWhereToSave = "<#path#>"
asset.writeAudioTrackToURL(URL(fileURLWithPath: pathWhereToSave)) { (success, error) -> () in
if !success {
print(error)
}
}