2012-01-12 26 views
2

我正在嘗試使用QTKit將圖像列表轉換爲Quicktime影片。我已經想出瞭如何去做所有的事情,除了將幀速率提高到29.97。通過其他論壇和資源,招好像是用這樣的:QTMovie at 29.97 with QTMakeTime

QTTime frameDuration = QTMakeTime(1001, 30000) 

但是,使用這種方法,甚至是(1000,29970),我所有的努力仍處於30fps的製作影片。這個fps是使用Quicktime播放器時顯示的內容。

任何想法?有沒有其他的方式來設置整個電影創建後的幀頻?

下面是一些示例代碼:

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

回答

0

好,感謝你的代碼,我可以解決這個問題。我使用名爲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和時間表,你也可以這樣做:

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

這樣你可以看到更好的,如果你的代碼確實是需要的。

希望有幫助! 致以問候

+0

完美無瑕,效果很棒! 感謝您的幫助! – bchapman 2012-02-01 19:53:31

+0

非常歡迎! – guitarflow 2012-02-01 20:17:31

0

我從來沒有做過你想要做什麼,但我可以告訴你如何得到所期望的幀率我猜。 如果您詢問電影的當前時間信息,您總是會得到一個QTTime結構,其中包含timeScale和timeValue。 對於29.97 fps的視頻,您將獲得2997的timeScale(例如,請參見下文)。 這是每秒「單位」的數量。

因此,如果電影的播放位置當前正好在2秒鐘,那麼您將得到5994的時間值。 因此frameDuration爲100,因爲2997/100 = 29.97 fps。

QuickTime無法處理浮點值,因此您必須通過乘法將所有值轉換爲長整型值。順便說一句,你不必使用100,你也可以使用1000和時間尺度29970或200作爲幀持續時間和5994 timeScale。如果你從現有的剪輯中讀取時間信息,那麼你就可以告訴你什麼。 你寫道,這不適合你,但這是QuickTime如何在內部工作。 你應該再看看它!

問候

+0

工作了很多,試圖找出問題。我遇到的問題似乎是QTMovie的addImage。 QTTime可以使用QTMakeTime(1001,30000)產生29.97的持續時間。但是,當您將此持續時間提供給addImage時,會將其舍入爲1000/30000。 我創建了一些測試代碼,每次使用addImage時都會打印持續時間。每次持續時間增加1000,與1001. – bchapman 2012-02-01 02:21:55

+0

嗯,這很奇怪。我最近一直使用的29.97 fps電影的時間尺度爲2997,frameDuration爲100.在我看來,這比30000,1001的計算更容易理解,但理論上它應該是相同的。你介意分享一些代碼嗎?我很確定這個錯誤是在別的地方。最佳 – guitarflow 2012-02-01 09:50:54

+0

只需爲您添加一些示例代碼。謝謝你的幫助! – bchapman 2012-02-01 17:12:00