2011-05-11 85 views
4

關於逐幀動畫(如frame by frame animation和其他類似問題),有幾個SO問題,但是我覺得我的是不同的,所以在這裏。iOS逐幀動畫,通過腳本

這是部分來自ios體驗很少的人的設計問題。

我不確定「逐幀」是我想要做什麼的正確描述,請讓我描述一下。基本上,我有一個動畫電影的「劇本」,我想播放這個劇本。
這個腳本是一個描述一組場景的json文件。在每個場景中都有一些元素,例如背景圖片,演員的位置列表和背景聲音片段。此外,對於每個演員和背景,都有一個表示它的圖像文件。 (這有點複雜 - 每個演員都有一個「行爲」,比如它如何閃爍,他如何說話等等)。所以我的工作就是按照給定的腳本來引用演員和背景,並且在每一幀中,將演員放在他們指定的位置,繪製正確的背景並播放聲音文件。
電影可能被暫停,向前或向後擦拭,類似於YouTube的電影播放器​​功能。
我所看到的大多數涉及逐幀動畫的問題與我的要求不同(我稍後會列出更多要求)。他們通常建議使用動畫圖像UIImageView的財產。這對於動畫按鈕或複選框是很好的,但他們都假設需要播放一組簡短和預定義的圖像。
如果我要使用動畫圖像,我必須預先創建所有圖像,而我的純粹猜測是它不會縮放(想想一分鐘30fps,您會得到60 * 30 = 1800圖像。此外,在這種情況下,磨砂和暫停/打法能力看起來很有挑戰性)。

所以我正在尋找正確的方法來做到這一點。我的直覺和我正在學習的更多,是有可能有三到四種主要方式來實現這一點。

  1. 通過使用核心動畫和定義「關鍵點」和動畫轉換b/w這些關鍵點。例如,如果一個演員需要在時間點t1處於點A並且在時間點t2處於點B,那麼我只需要對其進行動畫處理即可。在過去,我在ActionScript中做了類似的事情,這很好,但是實施清理操作並保持每個步驟的同步性尤其具有挑戰性,所以我不是那種方法的忠實粉絲。想象一下,你必須在動畫中間實現一個暫停,或者在動畫的中間拖動。這是可行的,但不愉快。
  2. 設置一個定時器,比如每秒30次,並在每個tick上查詢模型(模型是腳本json文件以及演員和背景的描述),並繪製此時需要繪製的內容。使用Quartz 2D的API和drawRect。這可能是一種簡單的方法,但我沒有足夠的經驗來說明它將在不同的設備上運行得如何,可能是CPU方面,這一切都取決於我需要在每個tick上進行的計算量以及ios繪製一切所需的努力。我沒有預感。
  3. 與2相似,但使用OpenGL繪製。我更喜歡2 b/c的API更容易,但也許資源明智的OpenGL更合適。
  4. 使用我以前從未使用過的遊戲框架,例如cocos2d,但似乎可以解決或多或少相似的問題。他們似乎有一個很好的API,所以如果我能找到他們回答的所有要求,我會很高興。

頂上我剛剛描述的要求(播放短片給它的「腳本」文件和演員,背景和聲音的描述),還有另外一組的要求 -

  • 的電影需要在全屏模式或部分屏幕模式(其中屏幕的其他控件專用於其他控件)播放
  • 我開始使用iphone自然是一個ipad應該遵循。
  • 我希望能夠爲本地手機使用創建此電影的縮略圖(將其顯示在我的應用程序中的圖庫中)。縮略圖可能只是電影的第一幀。
  • 我希望能夠將結果「導出」爲電影,這些內容可以輕鬆上傳到YouTube或Facebook。

因此,這裏最大的問題是我想到的任何建議的1-4實現(或其他你可能會建議的)能否以某種方式導出這樣的電影。
如果所有四個電影導出任務失敗,那麼我有一個替代的想法。另一種方法是使用運行ffmpeg的服務器,該服務器接受所有電影圖像的包(我必須在電話中將它們繪製出來,並按照它們的順序將它們上傳到服務器),然後服務器將編譯所有圖像與他們的配樂到一部電影。
顯然爲了簡單起見,我寧願做這個服務器少,即能夠從iPhone導出電影,但如果這太多問,那麼最後的要求是至少能夠導出集所有圖像(電影中的關鍵幀),因此我可以將它們打包並上傳到服務器。

電影的長度應該是一兩分鐘。我希望這個問題不會太長,而且很明確......

謝謝!

回答

1

寫得很好的問題。爲了您的視頻導出需要,請查看AVFoundation(可從iOS 4獲得)。如果我要實現這個,我會嘗試#1或#4。我認爲#1可能是最快嘗試,但這可能是因爲我沒有任何使用cocos2d的經驗。我認爲你可以暫停和磨礪CoreAnimation:檢查它採用的CAMediaTiming協議。

+0

謝謝,AVFoundation很有用,一直在研究它。如何實施這些動畫的更普遍的問題仍然對任何想要刺激它的人開放。 – Ran 2011-05-12 14:56:17

0

然,你有很多選擇。您不會找到一個「完整的解決方案」,但可以利用現有的庫來跳過一堆實施和性能問題。你當然可以嘗試在OpenGL中構建這個東西,但是我的建議是你可以採用另一種方法。我建議你根據你的json設置在設備上逐幀渲染整個「視頻」。這基本上歸結爲設置你的場景元素,然後確定每個元素的位置[0,1,2],其中每個數字表示在某個幀速率下幀(15,20或24 FPS將足夠多) 。首先,請查看我的library for non-trivial iOS animations,其中您將找到一個名爲AVOfflineComposition的類,它執行「comp items並保存到磁盤上的文件」步驟。很明顯,這個類沒有做你需要的所有東西,但它是創建N個元素的基本邏輯並將結果寫入視頻文件的一個很好的起點。創建一個comp的要點是,所有讀取設置並將對象放置在comp中特定位置的代碼都可以在脫機模式下運行,最後得到的結果是一個視頻文件。將這一點與將所有這些元素保存在內存中所涉及的所有細節進行比較,然後根據所有內容的運行速度更快或更慢地前進。

下一步將創建1個音頻文件,該文件的長度是所有已填充幀的「電影」的長度,並使其包含特定時間的任何聲音。這基本上意味着在運行時混合音頻並將結果保存到輸出文件,以便AVAudioPlayer可以輕鬆播放結果。你可以看看我爲這種類型寫的一些非常簡單的PCM mixer code。但是,您可能需要考慮一個更完整的音頻引擎,如theamazingaudioengine

一旦你有一個音頻文件和一個電影文件,這些可以一起播放,並使用AVAnimatorMedia類很容易保持同步。看一下AVSync源代碼的例子,它顯示了播放視頻和顯示電影的緊密同步的例子。

您可以使用AVAssetWriterConvertFromMaxvid類實現您的最後一項要求,它會實現讀取.mvid電影文件的邏輯,並使用iPhone或iPad上的h.264編碼器硬件將其編碼爲h.264編碼視頻。使用這段代碼,你不需要編寫一個基於ffmpeg的服務器模塊。此外,這無法正常工作,因爲將所有未壓縮的視頻上傳到服務器需要很長時間。您需要將視頻壓縮到h.264,然後才能從應用上傳或通過電子郵件發送。