AVAssetWriter обрабатывает аудио из файла в реальном времени и аудио из AVCaptureSession

Я пытаюсь создать файл MOV с двумя аудиодорожками и одной видеодорожкой, и я пытаюсь сделать это без AVAssetExportSession или AVComposition, так как я хочу, чтобы итоговый файл был готов почти сразу после завершения AVCaptureSession. Экспорт после сеанса захвата может занять всего несколько секунд, но не в случае 5-минутного сеанса захвата. Похоже, это должно быть возможно, но мне кажется, что я всего в шаге от него:

Есть источник №1 - видео и аудио, записанные через AVCaptureSession (обрабатываются через AVCaptureVideoDataOutput и AVCaptureAudioDataOutput).

Есть источник №2 - аудиофайл, прочитанный с помощью AVAssetReader. Здесь я использую AVAssetWriterInput и requestMediaDataWhenReadyOnQueue. Я вызываю setTimeRange для его AVAssetReader от CMTimeZero до продолжительности актива, и это правильно отображается как 27 секунд при выходе из системы.

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

Важным моментом является то, что аудиофайл работает сам по себе, используя все тот же код AVAssetWriter. Если я настрою свой AVAssetWriter на вывод файла WAVE и воздержусь от добавления входов записи из # 1 (сеанс захвата), я завершу свой сеанс записи, когда сэмплы аудио из файла будут исчерпаны. Аудиофайл имеет определенный размер и воспроизводится правильно.

После добавления всех трех входов записи и типа файла, установленного на AVFileTypeQuickTimeMovie, процесс requestMediaDataOnQueue для аудио из файла по-прежнему читает те же данные. Результирующий файл mov показывает три дорожки, два аудио, одно видео, а продолжительность захваченного аудио и видео не идентичны по длине, но они, очевидно, сработали, и видео воспроизводится с обоими неповрежденными. Однако третья дорожка (вторая звуковая дорожка) имеет нулевую продолжительность.

Кто-нибудь знает, возможно ли все это решение и почему продолжительность звуковой дорожки из файла равна нулю, когда она находится в файле MOV? Если бы у меня был четкий способ микшировать две звуковые дорожки, я бы, но для одной, AVAssetReaderAudioMixOutput принимает два AVAssetTrack, и я, по сути, хочу смешать AVAssetTrack с захваченным звуком, и они не управляются и не читаются одинаково .

Я также считал, что QuickTime Movie не принимает определенные аудиоформаты, но я стараюсь передать один и тот же словарь настроек вывода как в audio AVAssetWriterInputs, так и захваченный звук воспроизводится и сообщает о его продолжительности (и от -файл звук воспроизводится в файле WAV с теми же настройками вывода), поэтому я не думаю, что это проблема.

Спасибо.


person Cloov    schedule 07.11.2017    source источник


Ответы (1)


Я обнаружил, что причина в следующем:

Я правильно использую временную метку презентации входящих данных сеанса захвата (в настоящий момент я использую PTS видеоданных), чтобы начать сеанс записи (startSessionAtSourceTime), и это означало, что метка времени аудиоданных, считываемых из файла, имела неправильная временная метка - вне временного диапазона, который был продиктован сеансу AVAssetWriter. Поэтому мне пришлось дополнительно обработать данные из аудиофайла, изменив информацию о времени, используя CMSampleBufferCreateCopyWithNewTiming.

CMTime bufferDuration = CMSampleBufferGetOutputDuration(nextBuffer);
CMSampleBufferRef timeAdjustedBuffer;
CMSampleTimingInfo timingInfo;
timingInfo.duration = bufferDuration;
timingInfo.presentationTimeStamp = _presentationTimeUsedToStartSession;
timingInfo.decodeTimeStamp = kCMTimeInvalid;

CMSampleBufferCreateCopyWithNewTiming(kCFAllocatorDefault, nextBuffer, 1, &timingInfo, &timeAdjustedBuffer);
person Cloov    schedule 07.11.2017
comment
Но разве это не делает ваши аудио PTS sBuffers имеющими ВСЕ одинаковые pts (_presentationTimeUsedToStartSession)? каждый новый аудиобуфер будет иметь одинаковый PTS нет? не должно ли оно увеличиваться? - person omarojo; 30.11.2018