Как я могу добавить к записанному файлу MPEG4 AAC? - PullRequest
5 голосов
/ 01 марта 2011

Я записываю аудио на iPhone, используя AVAudioRecorder со следующими настройками:

NSMutableDictionary *recordSettings = [[NSDictionary alloc] initWithObjectsAndKeys:
       [NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
       [NSNumber numberWithFloat:44100.0], AVSampleRateKey,
       [NSNumber numberWithInt:1], AVNumberOfChannelsKey,
       [NSNumber numberWithInt:12800], AVEncoderBitRateKey,
       [NSNumber numberWithInt:16], AVLinearPCMBitDepthKey,
       [NSNumber numberWithInt: AVAudioQualityHigh],  AVEncoderAudioQualityKey,
       nil];

(я могу быть гибким в большинстве этих настроек, но мне нужно использовать MPEG4 AAC.)

Я сохраняю аудио в файл.

Пользователь должен иметь возможность вернуться позже и продолжить запись в тот же файл. Кажется, нет возможности сделать это напрямую с AVAudioRecorder, поэтому вместо этого я записываю в новый файл и объединяю их.

В данный момент я добавляю файлы, используя AVMutableComposition и AVMutableCompositionTrack как здесь , но это действительно медленно для более длинных записей, так что это нереально.

Я думаю, что было бы намного быстрее, если бы я мог удалить заголовок из второго файла, добавить аудиоданные в первый файл, а затем изменить заголовок объединенного файла, чтобы отразить новую продолжительность. Поскольку я знаю, что оба файла были созданы с одинаковыми настройками, я полагаю, что остальные данные в заголовках должны быть идентичны.

К сожалению, я не могу найти информацию о том, в каком формате находятся заголовки, или есть ли возможность объединить файлы таким образом.

Итак, мои вопросы:

  • Какой формат заголовка файла MPEG-4 AAC при создании на iPhone?
  • Могу ли я объединить два аудиофайла, поиграв с заголовками вот так?
  • Есть ли лучший способ добавления двух аудиофайлов MPEG-4 AAC практически мгновенно?

Ответы [ 2 ]

3 голосов
/ 21 марта 2011

Хотя мы просим AVAudioRecorder записывать в формате MPEG4-AAC, он всегда создает файл .caf (Core Audio Format). Однако это всего лишь формат оболочки, и фактические аудиоданные, которые он содержит, находятся в формате AAC.

В конце концов, добавление файлов сводилось к управлению побайтовыми файлами .caf. Спецификация для файлов Core Audio Format: здесь . Сначала было немного утомительно переваривать этот документ и соответственно обрабатывать файлы, но оказалось, что спецификация очень ясная и полная, поэтому она не была слишком обременительной.

Как поясняется в спецификации, файлы .caf состоят из кусков с четырехбайтовыми именами в начале. Для файлов AAC всегда есть чанк desc и чанк kuki. Поскольку мы знаем, что наши два исходных файла находятся в одном и том же формате, мы можем скопировать эти куски без изменений в выходной файл.

Есть также блок pakt и блок data. Мы не можем гарантировать, в каком порядке они будут во входных файлах. Может существовать или не быть фрагмент free - но он содержит только отступы 0x00, поэтому нам не нужно копировать его в выходной файл.

Чтобы объединить чанки pakt, нам нужно проверить заголовки чанков и создать новый чанк pakt, чьи поля mNumberPackets и mNumberValidFrames являются суммами полей во входных файлах. mPrimingFrames и mRemainderFrames всегда равны нулю - они актуальны только для потокового мультимедиа. Большая часть блоков pakt (т.е. фактических данных таблицы пакетов) может быть просто объединена.

Аналогично для блоков data: поля mChunkSize необходимо суммировать, а затем можно объединить большую часть данных.

Будьте внимательны при чтении данных из всех двоичных числовых полей в этих файлах: файлы с прямым порядком байтов, но iPhone с прямым порядком байтов.

Для дополнительной оценки вы можете также рассмотреть возможность удаления сегментов звука из файла или вставки одного аудиофайла в середину другого. Это немного сложнее, так как вам нужно проанализировать содержимое блока pakt. Опять же, это случай следования спецификации: есть хорошее описание того, как размеры пакетов хранятся в целых числах переменной длины, поэтому вам придется проанализировать их, чтобы найти, сколько байтов занимает каждый пакет в блоке data, и рассчитать их позиции соответственно.

В целом, это намного сложнее, чем я надеялся. Может быть, есть библиотека с открытым исходным кодом, которая сделает все это за вас, но я не смог ее найти.

Тем не менее, обработка необработанных файлов, таких как эта, слепа по сравнению с использованием AVMutableComposition и AVMutableCompositionTrack, как в первоначальном вопросе - вставка записи продолжительностью в один час в другую такой же длины занимает около двух секунд.

Удачи!

1 голос
/ 09 июня 2011

Я нашел способ, который был намного быстрее реализовать:

  1. Используйте AVAudioRecorder и используйте расширение «m4a» для временного файла, однако вы также можете использовать «caf», если хотите, но это не нужно.

  2. Измените код здесь , чтобы использовать AVAssetExportPresetPassthrough и exportSession.outputFileType = AVFileTypeQuickTimeMovie и имя файла «audioJoined.mov». Используйте ваш недавно записанный временный m4a и существующий файл m4a. Это дает вам мгновенное соединение (без перекомпрессии) и производит «mov».

Примечание. К сожалению, AVAudioPlayer не может воспроизвести «mov», поэтому следующий шаг - преобразовать его во что-нибудь воспроизводимое. Однако, если вы просто собираетесь поделиться файлом где-нибудь, вы можете пропустить следующий шаг, так как mov отлично воспроизводится на Mac в Quicktime. Его также можно воспроизводить в iTunes, синхронизировать с iPhone и воспроизводить в приложении iPod.

  1. Преобразование mov назад в m4a с помощью [[AVAssetExportSession alloc] initWithAsset: movFileAsset presetName: AVAssetExportPresetAppleM4A], @ "audioJoined.m4a" для имени файла и exportSession.outputFileType = AVFileTypeAppleMA. Опять же, это мгновенно. Я предполагаю, что экспортер умнее в этой ситуации, когда он начинает с актива mov, а не актива AVMutableComposition.

Я использую эту технику в приложении, которое может возобновить запись после остановки записи и воспроизведения файла, или даже после перезапуска приложения, довольно круто.

...