ios - 从视频 AVFoundation 中提取音频

标签 ios swift avfoundation

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")
            }
        })

    })

}

我正在使用上面的代码从视频中获取音频,但它正在打印“不工作”

我的音频路径是:

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

请帮帮我

谢谢

最佳答案

我已经重写了 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)
}

关于ios - 从视频 AVFoundation 中提取音频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31879470/

相关文章:

ios - UIPinchGestureRecognizer 仅用于捏合

ios - AVAudioSession 播放时录音奇怪的问题

ios - 构建阶段脚本在 Xcode 10 中创建所需文件之前运行

ios7 - iOS 7 背景音频,AudioSession

cocoa-touch - CMTime 的时间刻度部分是多少?

ios - NSString 比较 @""== nil

ios - 证书和 faSTLane 文件应该在 XCode 项目中提交给 git 吗?

ios - UIPageViewController 从子 UIViewController 上的控件过渡

ios - 无法使用 jsonExport 和 Codeables 解码 json

ios - 将视频的音频转换为 AAC