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")
}
})
})
}
I am using above code to get audio from video, but it is printing "not working"
my audioPath is:
var outStr = NSBundle.mainBundle().pathForResource("cheeseburger", ofType: "m4a")
Please help me with this
Thanks
I have re-written the answer for Swift 4.0 since several API changes broke the previous one.
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
}
}
Then, you call the extension, and rely on the different closures to process successes and failures. The error handling in this example is extremely primitive, so you will want to improve that when implementing it.
asset.writeAudioTrack(to: url, success: {
print("Success")
}) { (error) in
print(error.localizedDescription)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With