簡體   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