繁体   English   中英

QTMovie在29.97时带有QTMakeTime

[英]QTMovie at 29.97 with QTMakeTime

我正在尝试使用QTKit将图像列表转换为QuickTime电影。 我已经弄清楚了如何做所有事情,除了使帧频达到29.97。 通过其他论坛和资源,这个窍门似乎正在使用这样的方法:

QTTime frameDuration = QTMakeTime(1001, 30000)

但是,我使用此方法进行的所有尝试,甚至(1000,29970)仍会以30fps的速度生成电影。 使用Quicktime播放器播放时会显示此fps。

有任何想法吗? 一旦创建了整个电影,还有其他方法来设置其帧频吗?

这是一些示例代码:

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]);

我从未做过您要尝试做的事情,但是我可以告诉您如何获得所需的帧率。 如果“询问”电影的当前定时信息,则始终会得到一个QTTime结构,其中包含timeScale和timeValue。 对于29.97 fps的视频,您将获得2997的timeScale(例如,参见下文)。 这是每秒的“单位”数量。

因此,如果影片的播放位置当前正好是2秒,则timeValue值为5994。因此frameDuration为100,因为2997/100 = 29.97 fps。

QuickTime无法处理浮点值,因此您必须通过乘法将所有值转换为长值。 顺便说一句,您不必使用100,也可以使用1000和timeScale为29970,或200为帧持续时间和5994 timeScale。 如果您从已有的剪辑中读取时序信息,那么我所能告诉的就是这些。 您写道这对您而言并不奏效,但这就是QuickTime在内部工作的方式。 您应该再次调查!

最好的祝福

好的,感谢您的代码,我可以解决问题。 我使用了名为Atom Inpector的开发工具来查看数据结构,这与我目前正在使用的电影完全不同。 就像我说过的那样,我从来没有像您那样从影像中制作电影,但是如果您以后要制作电影,似乎这不是要走的路。 QuickTime将该剪辑识别为“ Photo-JPEG”,而不是普通的电影文件。 造成这种情况的原因似乎是,添加的图片并未添加到电影轨道中,而只是添加到电影中的某个位置。 这也可以在Atom Inspector中看到。 使用“ 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);

这样,您可以更好地查看您的代码是否按需进行。

希望有帮助! 最好的祝福

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM