QTMovie в 29,97 с QTMakeTime - PullRequest
       36

QTMovie в 29,97 с QTMakeTime

2 голосов
/ 12 января 2012

Я пытаюсь использовать QTKit, чтобы конвертировать список изображений в быстрый фильм. Я разобрался, как сделать все, кроме как получить частоту кадров до 29,97. С помощью других форумов и ресурсов уловка, похоже, использует что-то вроде этого:

QTTime frameDuration = QTMakeTime(1001, 30000)

Тем не менее, все мои попытки использовать этот метод или даже (1000, 29970) по-прежнему дают фильм со скоростью 30 кадров в секунду. Этот fps - то, что появляется при игре с Quicktime Player.

Есть идеи? Есть ли другой способ установить частоту кадров для всего фильма после его создания?

Вот пример кода:

NSDictionary *outputMovieAttribs = [NSDictionary dictionaryWithObjectsAndKeys:@"jpeg", QTAddImageCodecType, [NSNumber numberWithLong:codecHighQuality], QTAddImageCodecQuality, nil];
QTTime frameDuration = QTMakeTime(1001, 30000);
QTMovie *outputMovie = [[QTMovie alloc] initToWritableFile:@"/tmp/testing.mov" error:nil];
[outputMovie setAttribute:[NSNumber numberWithBool:YES] forKey:QTMovieEditableAttribute];
[outputMovie setAttribute:[NSNumber numberWithLong:30000] forKey:QTMovieTimeScaleAttribute];

if (!outputMovie) {
    printf("ERROR: Chunk: Could not create movie object:\n");
} else {
    int frameID = 0;
    while (frameID < [framePaths count]) {
        NSAutoreleasePool *readPool = [[NSAutoreleasePool alloc] init];
        NSData *currFrameData = [NSData dataWithContentsOfFile:[framePaths objectAtIndex:frameID]];
        NSImage *currFrame = [[NSImage alloc] initWithData:currFrameData];

        if (currFrame) {
            [outputMovie addImage:currFrame forDuration:frameDuration withAttributes:outputMovieAttribs];
            [outputMovie updateMovieFile];
            NSString *newDuration = QTStringFromTime([outputMovie duration]);
            printf("new Duration: %s\n", [newDuration UTF8String]);
            currFrame = nil;
        } else {
            printf("ERROR: Could not add image to movie");
        }
        frameID++;
        [readPool drain];
    }
}

NSString *outputDuration = QTStringFromTime([outputMovie duration]);
printf("output Duration: %s\n", [outputDuration UTF8String]);

Ответы [ 2 ]

0 голосов
/ 01 февраля 2012

Хорошо, благодаря вашему коду я смог решить проблему. Я использовал инструмент разработки под названием Atom Inpector, чтобы убедиться, что структура данных выглядит совершенно иначе, чем фильмы, с которыми я сейчас работаю. Как я уже сказал, я никогда не создавал фильм из изображений, как вы, но кажется, что это не тот путь, если вы хотите иметь фильм потом. QuickTime распознает клип как «Photo-JPEG», поэтому это не обычный файл фильма. Кажется, причина этого в том, что добавленные изображения НЕ добавляются в дорожку фильма, а просто где-то в фильме. Это также можно увидеть с инспектором атома. С «movieTimeScaleAttribute» вы устанавливаете timeScale, который не используется!

Чтобы решить эту проблему, я чуть-чуть изменил код.

NSDictionary *outputMovieAttribs = [NSDictionary dictionaryWithObjectsAndKeys:@"jpeg", 
                      QTAddImageCodecType, [NSNumber numberWithLong:codecHighQuality],
                      QTAddImageCodecQuality,[NSNumber numberWithLong:2997], QTTrackTimeScaleAttribute, nil];

QTTime frameDuration = QTMakeTime(100, 2997);
QTMovie *outputMovie = [[QTMovie alloc] initToWritableFile:@"/Users/flo/Desktop/testing.mov" error:nil];
[outputMovie setAttribute:[NSNumber numberWithBool:YES] forKey:QTMovieEditableAttribute];
[outputMovie setAttribute:[NSNumber numberWithLong:2997] forKey:QTMovieTimeScaleAttribute];

Все остальное без изменений. О, и кстати. Чтобы напечатать timeValue и timeScale, вы также можете сделать:

NSLog(@"new Duration timeScale : %ld timeValue : %lld \n", 
       [outputMovie duration].timeScale, [outputMovie duration].timeValue);

Таким образом, вы можете лучше видеть, если ваш код работает так, как вам нужно.

Надеюсь, это поможет! С наилучшими пожеланиями

0 голосов
/ 31 января 2012

Я никогда не делал то, что вы пытаетесь сделать, но я могу сказать вам, как получить желаемую частоту кадров, я думаю. Если вы «запрашиваете» у фильма текущую информацию о времени, вы всегда получаете структуру QTTime, которая содержит timeScale и timeValue. Для видео с частотой 29,97 кадров в секунду вы получите шкалу времени 2997 (например, см. Ниже). Это количество «единиц» в секунду.

Таким образом, если позиция воспроизведения фильма в настоящее время составляет ровно 2 секунды, вы получите значение timeValue 5994. Поэтому frameDuration составляет 100, потому что 2997/100 = 29,97 кадров в секунду.

QuickTime не может обрабатывать значения с плавающей запятой, поэтому вам нужно преобразовать все значения в длинное с помощью умножения. Кстати, вам не нужно использовать 100, вы также можете использовать 1000 и timeScale 29970, или 200 в качестве длительности кадра и 5994 timeScale. Это все, что я могу сказать вам по тому, что вы получаете, если вы читаете информацию о времени из уже существующих клипов. Вы написали, что это не сработало для вас, но именно так QuickTime работает внутри. Вы должны посмотреть на это снова!

С наилучшими пожеланиями

...