Извлечь аудио из видеофайла

Как я могу извлечь аудио из видеофайла без использования FFmpeg?

Я хочу использовать AVMutableComposition и AVURLAsset для его решения, например. преобразование из файла .mov в файл .m4a.


person Tripti Kumar    schedule 11.07.2012    source источник
comment
Насколько я знаю, AVFoundation на iOS ничего не знает о том, как декодировать или открывать .flv файлы, поэтому этот вопрос не стоит начинать с самого начала. Вот почему вам нужно использовать стороннюю библиотеку, такую ​​​​как ffmpeg или что-то еще, чтобы открыть файл .flv и преобразовать его во что-то, что вы можете правильно использовать.   -  person Michael Dautermann    schedule 12.07.2012
comment
Я отредактирую пример, так как не думал об этом... но мое требование остается прежним... :(   -  person Tripti Kumar    schedule 12.07.2012


Ответы (2)


В следующем коде Swift 5/iOS 12.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: AVMediaType.audio).first else { return }
            guard let audioCompositionTrack = composition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: kCMPersistentTrackID_Invalid) else { return }
            try audioCompositionTrack.insertTimeRange(audioAssetTrack.timeRange, of: audioAssetTrack, at: CMTime.zero)
        } catch {
            print(error)
        }

        // Get url for output
        let outputUrl = URL(fileURLWithPath: NSTemporaryDirectory() + "out.m4a")
        if FileManager.default.fileExists(atPath: outputUrl.path) {
            try? FileManager.default.removeItem(atPath: outputUrl.path)
        }

        // Create an export session
        let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetPassthrough)!
        exportSession.outputFileType = AVFileType.m4a
        exportSession.outputURL = outputUrl

        // Export file
        exportSession.exportAsynchronously {
            guard case exportSession.status = AVAssetExportSession.Status.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)
            }
        }
    }

}
person Imanou Petit    schedule 25.04.2017

Во всех мультимедийных форматах аудио кодируется отдельно от видео, а их кадры чередуются в файле. Таким образом, удаление видео из мультимедийного файла не требует возни с кодировщиками и декодерами: вы можете написать анализатор формата файла, который будет удалять видеодорожку, не используя мультимедийные API на телефоне.

Чтобы сделать это без использования сторонней библиотеки, вам нужно написать синтаксический анализатор с нуля, что может быть простым или сложным в зависимости от формата файла, который вы хотите использовать. Например, FLV очень прост, поэтому удалить из него дорожку очень просто (просто пройдитесь по потоку, определите начало кадра и отбросьте «0x09» = видеокадры). MP4 немного сложнее, его заголовок (MOOV) имеет иерархическую структуру, в которой у вас есть заголовки для каждой из дорожек (атомы TRAK). Вам нужно отбросить видео TRAK, а затем скопировать чередующийся атом битового потока (MDAT), пропуская все кластеры видеоданных при копировании.

Помимо ffmpeg, вы можете использовать сторонние библиотеки. На ум приходит GPAC MP4BOX (лицензия LGPL). Если LGPL является проблемой, существует множество коммерческих SDK, которые вы можете использовать.

person onon15    schedule 24.07.2012
comment
Спасибо за ваш ответ .. +1 за него .. но если бы вы могли помочь мне с частью кодирования .. это было бы большим подспорьем :) - person Tripti Kumar; 24.07.2012
comment
Извините... MOV (похожий на MP4) - сложный формат файла, написание такого парсера - это как минимум день или два программирования, поэтому я не могу вам с этим помочь. Я предполагаю, что ваша первоначальная идея попытаться сделать это с помощью AVMutableComposition - лучший способ (он должен делать то же самое) - в основном файл M4A почти похож на MOV без звуковой дорожки, поэтому откройте MOV как AVMutableComposition и выполните removeTrack может сделать трюк ... - person onon15; 24.07.2012
comment
@ onon15 - (+1) У меня есть файл с 1 аудио TRAK и 1 видео TRAK (aac, h264), как мне отличить сэмплы в атоме 'mdat'? Спасибо! - person avishic; 08.08.2012
comment
Это не так просто, как вы ожидаете, но и не сложно, как только вы освоитесь. Вы не можете получить его из самого MDAT. Смещения фрагментов данных, принадлежащих каждой дорожке, хранятся в таблице STCO (или CO64) внутри TRAK>MDIA>MINF>STBL. Длина каждого фрагмента — это еще один расчет, который вам нужно выполнить для информации в файле STBL. См. эту ссылку. - person onon15; 09.08.2012