QTKit, захват видео для прямой трансляции

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

С этой целью я пытаюсь записывать видео с iSight с помощью QTKit и постоянно сохранять его как серию крошечных видеофайлов. Однако запись получается не совсем непрерывной, с промежутками между файлами.

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

Пожалуйста, помогите мне, если вы знаете, как это делать.

Вот мой текущий код:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    QTCaptureSession *session = [[QTCaptureSession alloc] init];
    QTCaptureDevice *iSight = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeVideo];
    [iSight open:nil];
    QTCaptureDeviceInput *myInput = [QTCaptureDeviceInput deviceInputWithDevice:iSight];
    output = [[QTCaptureMovieFileOutput alloc] init] ; //ivar, QTCaptureFileOutput
    [output setDelegate:self];
    a = 0; //ivar, int
    fileName = @"/Users/dtv/filerecording_"; //ivar, NSString
    [session addOutput:output error:nil];
    [session addInput:myInput error:nil];
    [capview setCaptureSession:session]; //IBOutlet
    [session startRunning]; 
    [output setCompressionOptions:[QTCompressionOptions compressionOptionsWithIdentifier:@"QTCompressionOptionsSD480SizeH264Video"] forConnection:[[output connections] objectAtIndex:0]];
    [output recordToOutputFileURL:[NSURL fileURLWithPath:[NSString stringWithFormat:@"%@%i.mov", fileName, a]] bufferDestination:QTCaptureFileOutputBufferDestinationOldFile];
    NSTimer *tmr = [NSTimer timerWithTimeInterval:5 target:self selector:@selector(getMovieLength:) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:tmr forMode:NSDefaultRunLoopMode];
}

‐ (void) getMovieLength:(NSTimer *) t { a++; [output recordToOutputFileURL:[NSURL fileURLWithPath:[NSString stringWithFormat:@"%@%i.mov", fileName, a]] bufferDestination:QTCaptureFileOutputBufferDestinationOldFile]; }


person Ibolit    schedule 12.10.2011    source источник


Ответы (1)


Есть собственный механизм разорвать отснятый фильм на части. Использовать

[QTCaptureFileOutput setMaximumRecordedDuration:]

указать продолжительность произведения или

[QTCaptureFileOutput setMaximumRecordedFileSize:]

чтобы указать предельный размер файла.

Когда предел будет достигнут, будет вызван метод делегата:

[QTCaptureFileOutput_Delegate captureOutput: shouldChangeOutputFileAtURL: forConnections: dueToError:]

В этом методе вы можете установить новое имя файла:

[QTCaptureFileOutput recordToOutputFileURL:]

Это позволит вам довольно точно вырезать фрагменты записанного фильма.

Обратите внимание, что [QTCaptureFileOutput_Delegate captureOutput: didFinishRecordingToOutputFileAtURL: forConnections: dueToError:] будет вызываться немного позже после того, как фактически будет завершено перекодирование в файл. Если вы используете этот метод для установки нового файла, в финальном видео будут пробелы. Однако это не означает, что вам не нужно использовать этот метод. Этот метод будет указывать, когда фрагмент фильма будет готов к использованию.

Если вам нужна еще более точная резка, вы можете использовать

[QTCaptureFileOutput captureOutput: didOutputSampleBuffer: fromConnection:]

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

person Davyd Geyl    schedule 17.10.2011
comment
Спасибо. К сожалению, пока не могу это проверить. Приму, как только смогу это проверить. - person Ibolit; 18.10.2011
comment
Спасибо. Он действительно работает намного плавнее, чем раньше. Но все же не совсем гладко. Что это за конкретные знания, о которых вы упомянули? Не могли бы вы сказать мне, где я могу его найти? С уважением, Тимофей. - person Ibolit; 18.10.2011
comment
Что значит не совсем гладко? Он должен работать очень хорошо. Когда я сказал, что вам нужны более конкретные знания, я просто не знал, насколько глубоко вам нужно копаться в материалах quicktime. В большинстве случаев метода, который я описываю, достаточно, чтобы разбить отснятый фильм на части. Однако, если вам нужна более точная обрезка до одного кадра, вы можете использовать метод [QTCaptureFileOutput captureOutput: didOutputSampleBuffer: fromConnection:]. В этом случае вам необходимо получить данные из буфера и проанализировать их. Ничего особенного, из документации можно почерпнуть практически все. - person Davyd Geyl; 18.10.2011
comment
Я имел в виду, когда я просматриваю их все один за другим в VLC (и я играю их в правильном порядке), вы можете сказать, где заканчивается один файл и начинается следующий. Это может быть связано с тем, как работает VLC, хотя, я согласен, поэтому я попытаюсь просмотреть это, скажем, в iMovie. - person Ibolit; 20.10.2011
comment
Это еще одна проблема. Новый фильм не может быть воспроизведен сразу, требуется некоторое время для декодирования кадров. Для плавного воспроизведения фрагментов вам нужно добавить их одну за другой в новый файл QTMovie с помощью метода [QTMovie appendSelectionFromMovie:] и воспроизвести этот фильм. В этом случае промежутка не будет, потому что фильм заранее расшифровывает кадры. Не беспокойтесь о размере, фактические данные не будут скопированы, а будут ссылаться. Если вы сохраните этот фильм на диск, вы увидите, что файл фильма небольшой, если, конечно, вы не используете атрибут QTMovieFlatten. - person Davyd Geyl; 21.10.2011