AVAssetReaderOutput copyNextSampleBuffer зависает при кодировании видео с аудио на устройстве

После реализации решения по кодированию видео (со звуком) в этом вопросе Кодирование видео с использованием AVAssetWriter - АВАРИИ, я обнаружил, что код корректно работает в симуляторе iPhone. К сожалению, некоторые видео не могут кодировать звук при работе на реальном iPhone 5 (и других устройствах).

Например, видео, сгенерированные из примера кода RosyWriter WWDC 2011 (https://developer.apple.com/library/IOS/samplecode/RosyWriter/Introduction/Intro.html) кодировать не полностью, поскольку функция -[AVAssetReaderOutput copyNextSampleBuffer] никогда не возвращается.

Видеобуферы приходят корректно, но как только пытается скопировать первый аудио CMSampleBufferRef, вызов зависает. Когда я пробую это на видео из других источников, например, записанных в родном приложении iOS Camera, звук импортируется правильно.

Эта ветка, https://groups.google.com/forum/#!topic/coreaudio-api/F4cqCu99nUI отмечает зависание функции copyNextSampleBuffer при использовании с AudioQueues и предлагает выполнять операции в одном потоке. Я пытался хранить все в отдельном потоке, в основном потоке, но не повезло.

Кто-нибудь еще сталкивался с этим и имел возможное решение?

РЕДАКТИРОВАТЬ: кажется, что дорожки видео, созданные с помощью RosyWriter, перевернуты по сравнению с видео из собственного приложения «Камера», т. е. аудиопоток как поток 0, а видеопоток как поток 1.

Stream #0:0(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 60 kb/s
Metadata:
  creation_time   : 2013-10-28 16:13:05
  handler_name    : Core Media Data Handler
Stream #0:1(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1920x1080, 8716 kb/s, 28.99 fps, 29.97 tbr, 600 tbn, 1200 tbc
Metadata:
  rotate          : 90
  creation_time   : 2013-10-28 16:13:05
  handler_name    : Core Media Data Handler

Не уверен, что это имеет значение для AVAssetReader.


person jlw    schedule 28.11.2013    source источник
comment
Вы когда-нибудь находили решение для этого? Я испытываю ту же проблему. Я реконструировал RosyWriter для записи своих собственных видео, и когда я пытаюсь кодировать/экспортировать их позже, они «иногда» терпят неудачу. Очень очень непоследовательно..   -  person Sti    schedule 20.09.2014
comment
Похоже, проблема заключалась в том, как AVFoundation кодировал звуковую дорожку. Это исправлено в iOS8. Я добавлю ответ.   -  person jlw    schedule 20.09.2014
comment
Есть ли последние разработки по этому вопросу?   -  person pearl7721    schedule 04.03.2020


Ответы (4)


Я все еще сталкивался с этой проблемой на iOS 9.3.2, и проблема, которая разрешила ее, заключалась в том, чтобы убедиться, что AVAssetReaderAudioMixOutput* изначально был установлен с параметрами, а не nil при вызове -[AVAssetReaderAudioMixOutput assetReaderAudioMixOutputWithAudioTracks].

Пример:

NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                    [NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
                                    [NSNumber numberWithFloat:44100.0], AVSampleRateKey,
                                    [NSNumber numberWithInt:16], AVLinearPCMBitDepthKey,
                                    [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
                                    [NSNumber numberWithBool:NO], AVLinearPCMIsFloatKey,
                                    [NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey,
                                    nil];

// create an AVAssetReaderOutput for the audio tracks
NSArray* audioTracks = [asset tracksWithMediaType:AVMediaTypeAudio];
AVAssetReaderAudioMixOutput* _audioReaderOutput = [AVAssetReaderAudioMixOutput assetReaderAudioMixOutputWithAudioTracks:audioTracks audioSettings:outputSettings];

Это предотвратило зависание последующих вызовов -[AVAssetReaderOutput copyNextSampleBuffer], когда они в противном случае делали это.

person Dan G    schedule 27.07.2016

Проверьте временной диапазон на звуковых дорожках, используя что-то вроде этого:

NSLog(@"audioTrack timeRange: %lld, %lld", audioTrack.timeRange.start.value, audioTrack.timeRange.duration.value);

Пустые временные диапазоны (0, 0) могут привести к зависанию функции copyNextSampleBuffer().

person John Lemberger    schedule 17.01.2014
comment
Спасибо за предложение, но у меня есть видео с непустым временным диапазоном, которые все еще не работают. - person jlw; 17.01.2014
comment
Вы проверяли каждую отдельную дорожку в видеофайле? - person John Lemberger; 18.01.2014
comment
да. В видеофайле есть только одна видеодорожка и одна звуковая дорожка, и обе они имеют непустые временные диапазоны. - person jlw; 18.01.2014

Это была ошибка AVFoundation в iOS7. Теперь это исправлено в iOS8.

person jlw    schedule 20.09.2014
comment
Хорошо, что это исправлено в iOS8, но для тех из нас, кто хочет поддерживать более ранние iOS-версии, это все еще проблема :( У меня тоже в файлах Аудио как первый поток, видео как второй. Вы нашли если это имело какое-либо значение для ошибки? - person Sti; 20.09.2014
comment
Не уверен, связано ли это с ошибкой, но видео, которые правильно записываются в iOS8, теперь имеют сначала видеопоток, а затем аудиопоток. - person jlw; 22.09.2014
comment
Кто-нибудь нашел обходной путь для этой проблемы? Есть ли способ изменить порядок потоков при настройке AssetWriter? Мне бы очень хотелось иметь возможность повторно обрабатывать видео, которое я записал ранее, — также в iOS 7. - person Frank Schlegel; 16.05.2015
comment
Я проверил это на iOS8 на своем iPhone 5, и это НЕ РАБОТАЕТ. Отлично работает на симуляторе (НЕ на iPhone 5). Возможно, это работает на iPhone 6? - person etayluz; 29.07.2015
comment
Я вижу, что copyNextBuffer иногда зависает и на iOS 9.3.3. Для меня это время от времени происходит с AVAssetReaderAudioMixOutput с активом, который имеет 5 звуковых дорожек, все с непустыми временными диапазонами. Кто-нибудь еще это видит? - person Greg; 26.07.2016
comment
Еще проблема на iOS 13, новое железо. - person xaphod; 23.10.2019

Это аппаратная проблема. Я тестировал это на симуляторе, iPhone5 и iPhone 6. Проблема возникает на 100% с некоторыми видеофайлами, но ТОЛЬКО на iPhone 5. За iPhone 5S ничего сказать не могу. iOS8 НЕ решает эту проблему. Исправление может заключаться в том, чтобы ограничить доступ пользователей iPhone 5 к определенным функциям. Другой обходной путь заключается в том, чтобы пользователь выбирал видео из своей фотопленки, тем самым применяя к нему специальное сжатие Apple — и превращая это видео в формат, с которым может работать аппаратное обеспечение iPhone 5.

person etayluz    schedule 30.07.2015
comment
Возникающие спустя годы на всевозможных устройствах. - person xaphod; 21.10.2019