AVAssetWriterInput и readyForMoreMediaData - PullRequest
6 голосов
/ 04 мая 2011

Обновляется ли готовая форма данных AVAssetWriterInput ForMoreMediaData в фоновом потоке? Если readyForMoreMediaData НЕТ, могу ли я заблокировать в основном потоке и подождать, пока значение не изменится на ДА?

Я использую AVAssetWriterInput, помещая в него данные (т. Е. Без использования requestMediaDataWhenReadyOnQueue), и я установил expectedMediaDataInRealTime, и в 99,9% времени я могу просто вызывать appendSampleBuffer (или appendPixelBuffer) для него так же быстро, как мое приложение генерировать кадры.

Это работает нормально, если вы не переводите устройство (iPhone 3GS) в спящий режим на 15 минут или около того в середине сеанса AVAssetWriter. После пробуждения устройства appendPixelBuffer иногда получает сообщение об ошибке: «Пиксельный буфер не может быть добавлен, когда readyForMoreMediaData имеет значение NO». Отсюда мой вопрос - как лучше ответить на readyForMoreMediaData = NO, и если я могу просто немного подождать в основном потоке, вот так:

while ( ![assetWriterInput readyForMoreMediaData] )
{
    Sleep for a few milliseconds
}

Ответы [ 3 ]

3 голосов
/ 22 июля 2012

Будьте осторожны, чтобы не просто заблокировать поток, вот что я делал до того, как это не сработало:

while (adaptor.assetWriterInput.readyForMoreMediaData == FALSE) {
  [NSThread sleepForTimeInterval:0.1];
}

Приведенный выше подход иногда не работает на моем iPad2.Это вместо того, чтобы исправить проблему:

while (adaptor.assetWriterInput.readyForMoreMediaData == FALSE) {
  NSDate *maxDate = [NSDate dateWithTimeIntervalSinceNow:0.1];
  [[NSRunLoop currentRunLoop] runUntilDate:maxDate];
}
0 голосов
/ 29 сентября 2018
        int waitTime = 300;
        while (weakSelf.input.readyForMoreMediaData == NO) {
            NSLog(@"readyForMoreMediaData is NO");
            NSTimeInterval waitIntervale = 0.001 * waitTime;
            NSDate *maxDate = [NSDate dateWithTimeIntervalSinceNow:waitIntervale];
            [[NSRunLoop currentRunLoop] runUntilDate:maxDate];
            waitTime += 200; // add 200ms every time
        }
0 голосов
/ 27 марта 2018

Не нашел ничего похожего, поэтому я оставил это здесь. Свифт 4 решение.Лучше использовать точную технику для решения этой проблемы.Например, используя NSCondition:

func startRecording() {
        // start recording code goes here 

    readyForMediaCondition = NSCondition()
    readyForMediaObservation = pixelBufferInput?.assetWriterInput.observe(\.isReadyForMoreMediaData, options: .new, changeHandler: { [weak self](_, change) in
        guard let isReady = change.newValue else {
            return
        }

        if isReady {
            self?.readyForMediaCondition?.lock()
            self?.readyForMediaCondition?.signal()
            self?.readyForMediaCondition?.unlock()
        }
    })
}

Далее:

func grabFrame(time: CMTime? = nil) {
    readyForMediaCondition?.lock()
    while !pixelBufferInput!.assetWriterInput.isReadyForMoreMediaData {
        readyForMediaCondition?.wait()
    }
    readyForMediaCondition?.unlock()

    // append your framebuffer here
}

Не забудьте аннулировать наблюдателя в конце

readyForMediaObservation?.invalidate()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...