Извлечь аудио из видео файла
Как я могу извлечь аудио из видео файла, не используя FFmpeg?
Я хочу использовать AVMutableComposition
а также AVURLAsset
для решения it.eg преобразования из.mov в.m4a файл.
2 ответа
Следующий код Swift 3 показывает, как извлечь аудио из файла фильма (.mov) и преобразовать его в аудио файл (.m4a) с помощью AVURLAsset
, AVMutableComposition
а также AVAssetExportSession
:
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)
}
}
}
}
Во всех мультимедийных форматах аудио кодируется отдельно от видео, а их кадры чередуются в файле. Таким образом, удаление видео из мультимедийного файла не требует никаких действий с кодировщиками и декодерами: вы можете написать синтаксический анализатор формата файла, который будет отбрасывать видео дорожку, без использования мультимедийных API на телефоне.
Чтобы сделать это без использования сторонней библиотеки, вам нужно написать парсер с нуля, который может быть простым или сложным в зависимости от формата файла, который вы хотите использовать. Например, FLV очень прост, поэтому вырезать трек из него очень просто (просто пройдите по потоку, определите начало кадра и удалите "0x09" = видеокадры). MP4 немного сложнее, его заголовок (MOOV) имеет иерархическую структуру, в которой у вас есть заголовки для каждой дорожки (атомы TRAK). Вам нужно отбросить видео TRAK, а затем скопировать чередующийся битовый атом (MDAT), пропуская все кластеры видеоданных при копировании.
Помимо ffmpeg вы можете использовать сторонние библиотеки. На ум приходит GPAC MP4BOX (лицензия LGPL). Если LGPL является проблемой, есть много коммерческих SDK, которые вы можете использовать.