从video文件中提取audio
如何从video文件中提取audio而不使用FFmpeg ?
我想使用AVMutableComposition
和AVURLAsset
来解决它从.mov到.m4a文件的转换。
下面的Swift 3代码演示了如何使用AVURLAsset
, AVMutableComposition
和AVAssetExportSession
从电影文件( .mov )中提取audio并将其转换为audio文件( .m4a ):
import UIKit import AVFoundation class ViewController: UIViewController { @IBAction func extractAudioAndExport(_ sender: UIButton) { // Create a composition let composition = AVMutableComposition() do { let sourceUrl = Bundle.main.url(forResource: "Movie", withExtension: "mov")! let asset = AVURLAsset(url: sourceUrl) guard let audioAssetTrack = asset.tracks(withMediaType: AVMediaTypeAudio).first else { return } let audioCompositionTrack = composition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid) try audioCompositionTrack.insertTimeRange(audioAssetTrack.timeRange, of: audioAssetTrack, at: kCMTimeZero) } catch { print(error) } // Get url for output let outputUrl = URL(fileURLWithPath: NSTemporaryDirectory() + "out.m4a") if FileManager.default.fileExists(atPath: exportUrl.path) { try? FileManager.default.removeItem(atPath: outputUrl.path) } // Create an export session let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetPassthrough)! exportSession.outputFileType = AVFileTypeAppleM4A exportSession.outputURL = outputUrl // Export file exportSession.exportAsynchronously { guard case exportSession.status = AVAssetExportSessionStatus.completed else { return } DispatchQueue.main.async { // Present a UIActivityViewController to share audio file guard let outputURL = exportSession.outputURL else { return } let activityViewController = UIActivityViewController(activityItems: [outputURL], applicationActivities: []) self.present(activityViewController, animated: true, completion: nil) } } } }
在所有多媒体格式中,audio与video分开编码,并且它们的帧在文件中交错。 因此,从多媒体文件中删除video不需要对编码器和解码器进行任何修改:您可以编写文件格式parsing器来放弃video轨道,而无需在手机上使用多媒体API。
要做到这一点,而不使用第三方库,您需要从头开始编写parsing器,根据您希望使用的文件格式,这可能很简单或很难。 例如,FLV是非常简单的,所以剥离一个轨道是非常容易的(只是越过stream,检测帧开始,并删除'0x09'=video帧)。 MP4有点复杂,它的标题(MOOV)有一个分层的结构,其中你有每个轨道(TRAKprimefaces)的标题。 您需要删除videoTRAK,然后复制交错比特streamprimefaces(MDAT),以便在复制时跳过所有video数据群集。
除了ffmpeg之外,还有第三方库可以使用。 想到的是GPAC MP4BOX(LGPL许可证)。 如果LGPL是一个问题,那么可以使用大量的商业SDK。