Записывайте видео с помощью AVAssetWriter: первые кадры черные

Я записываю видео (пользователь также может переключаться только на звук) с AVAssetWriter, Я начинаю запись при запуске приложения. Но первые кадры черные (или очень темные). Это также происходит, когда я переключаюсь с аудио на видео. Это похоже на AVAssetWriter и / или AVAssetWriterInput еще не готовы к записи. Как я могу избежать этого?

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

func start_new_record(){
    do{
        try self.file_writer=AVAssetWriter(url: self.file_url!, fileType: AVFileTypeMPEG4)
        if video_on{
            if file_writer.canAdd(video_writer){
                file_writer.add(video_writer)
            }
        }
        if file_writer.canAdd(audio_writer){
            file_writer.add(audio_writer)
        }
    }catch let e as NSError{
        print(e)
    }
}

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!){
    guard is_recording else{
        return
    }

    guard CMSampleBufferDataIsReady(sampleBuffer) else{
        print("data not ready")
        return
    }

    guard let w=file_writer else{
        print("video writer nil")
        return
    }

    if w.status == .unknown && start_recording_time==nil{
        if (video_on && captureOutput==video_output) || (!video_on && captureOutput==audio_output){
            print("START RECORDING")
            file_writer?.startWriting()
            start_recording_time=CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
            file_writer?.startSession(atSourceTime: start_recording_time!)
        }else{
            return
        }
    }

    if w.status == .failed{
        print("failed /", w.error ?? "")
        return
    }

    if captureOutput==audio_output{
        if audio_writer.isReadyForMoreMediaData{
            if !video_on || (video_on && video_written){
                audio_writer.append(sampleBuffer)
                //print("write audio")
            }
        }else{
            print("audio writer not ready")
        }
    }else if video_output != nil && captureOutput==video_output{
        if video_writer.isReadyForMoreMediaData{
            video_writer.append(sampleBuffer)
            if !video_written{
                print("added 1st video frame")
                video_written=true
            }
        }else{
            print("video writer not ready")
        }
    }
}

3 ответа

Решение

Хорошо, глупая ошибка...

При запуске приложения я запускаю AVCaptureSession, добавить входы, выходы и т. д. И я просто звонил start_new_record немного раньше commitConfiguration был вызван на мою сессию захвата.

По крайней мере, мой код может быть полезен для некоторых людей.

SWIFT 4

РЕШЕНИЕ № 1:

Я решил эту проблему, вызвав file_writer?.StartWriting() как можно скорее после запуска приложения. Затем, когда вы хотите начать запись, выполните file_writer?.StartSession (atSourceTime:...).

Когда вы закончите запись и вызовите finishRecording, когда вы получите обратный вызов, который говорит, что он завершен, снова установите новый сеанс записи.

РЕШЕНИЕ № 2:

Я решил эту проблему, добавив полсекунды к времени запуска при вызове AVAssetWriter.startSession, например так:

start_recording_time = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
let startingTimeDelay = CMTimeMakeWithSeconds(0.5, 1000000000)
let startTimeToUse = CMTimeAdd(start_recording_time!, startingTimeDelay)

file_writer?.startSession(atSourceTime: startTimeToUse)

Это для будущих пользователей...

Ничто из вышеперечисленного не сработало для меня, а затем я попытался изменить предустановку камеры на среднюю, которая работала нормально.

Другие вопросы по тегам