iOS逐帧动画,脚本
关于逐帧动画有一些SO问题(例如逐帧动画和其他类似的问题),但我觉得我的不同所以这里有。
这部分是来自ios经验非常少的人的设计问题。
我不确定“逐帧”是对我想要做的正确描述,所以让我来描述一下。 基本上,我有一个动画电影的“剧本”,我想播放这个剧本。
此脚本是一个描述一组场景的json文件。 在每个场景中都有一些元素,例如背景图像,具有位置的演员列表和背景声音剪辑。 此外,对于每个演员和背景,都有一个代表它的图像文件。 (它有点复杂 – 每个演员都有一个“行为”,例如它如何眨眼,他如何谈话等)。 所以我的工作是遵循给定的脚本引用演员和背景以及每一帧,将演员放在他们指定的位置,绘制正确的背景并播放声音文件。
类似于youtube的电影播放器function,电影可能会暂停,向前或向后擦除。
我所看到的大多数涉及逐帧动画的问题都有不同的要求(我稍后会列出更多要求)。 他们通常建议使用UIImageView的 animationImages属性。 这对于设置按钮或复选框的动画效果很好,但它们都假设需要播放一组简短且预定义的图像。
如果我要使用animationImages,我必须预先创建所有图像,我的纯粹猜测是它不会缩放(想想一分钟30fps,你得到60 * 30 = 1800张图像。加上在这种情况下,擦洗和暂停/播放能力似乎具有挑战性)。
所以我正在寻找正确的方法来做到这一点。 我的直觉,而且我正在学习的更多内容是,可能有三到四种主要方法来实现这一目标。
- 通过使用核心动画并定义“关键点”和动画过渡b / w这些关键点。 例如,如果演员需要在时间t1处于A点而在时间t2处处于B点,那么我需要做的就是为它们之间设置动画。 我过去在ActionScript中做过类似的事情并且它很不错但是实现擦除操作并保持每个事务处理同步特别具有挑战性,所以我不是这种方法的忠实粉丝。 想象一下,您必须在动画中间实现暂停或者在动画中间进行擦除。 这是可行但不愉快。
- 设置一个计时器,比如每秒30次并在每个刻度上查询模型(模型是脚本json文件以及演员和背景的描述)并绘制此时需要绘制的内容。 使用Quartz 2D的API和drawRect。 这可能是一个简单的方法,但我没有足够的经验来判断它在不同设备上的工作情况,可能是CPU方面的,这完全取决于我需要对每个tick进行的计算量以及努力需要ios来绘制一切。 我没有预感。
- 类似于2,但使用OpenGL绘制。 我更喜欢2 b / c,API更容易,但也许资源方面的OpenGL更合适。
- 使用像我之前从未使用的cocos2d这样的游戏框架,但似乎解决了或多或少类似的问题。 他们似乎有一个很好的API,所以如果我能找到他们的所有要求,我会很高兴。
在我刚刚描述的要求之上(根据它的“脚本”文件以及对演员,背景和声音的描述来播放电影),还有另一套要求 –
- 电影需要以全屏模式或部分屏幕模式播放(其中屏幕的其余部分专用于其他控件)
- 我开始使用iphone,ipad应该随之而来。
- 我希望能够创建这部电影的缩略图以供本地电话使用(在我的应用程序中的画廊中显示)。 缩略图可能只是电影的第一帧。
- 我希望能够将结果“导出”为电影,可以轻松上传到youtube或facebook。
所以这里最大的问题是我想到的任何建议的1-4实现(或者你可能建议的其他实现)是否能以某种方式导出这样的电影。
如果电影导出任务中的所有四个都失败了,那么我有另一种选择。 另一种方法是使用运行ffmpeg的服务器并接受所有电影图像的捆绑(我必须在手机中绘制它们并按顺序将它们上传到服务器)然后服务器将编译所有图像将他们的配乐录制成一部电影。
显然要保持简单,我宁愿做无服务器,也就是说能够从iphone导出电影,但如果要求太多,那么最后的要求是至少能够导出所有的一套图像(电影中的关键帧)所以我可以捆绑它们并上传到服务器。
电影的长度应该是一两分钟。 我希望这个问题不会太久,而且很明显……
谢谢!
写得很好的问题。 对于您的video导出需求,请查看AVFoundation(从iOS 4开始提供)。 如果我要实现这个,我会尝试#1或#4。 我认为#1可能是最快的尝试,但这可能是因为我对cocos2d没有任何经验。 我想你可以暂停和擦洗CoreAnimation:查看它采用的CAMediaTiming协议。
冉,你有很多选择。 您不会找到“完整的解决方案”,但可以利用现有的库来跳过大量的实现和性能问题。 你当然可以尝试在OpenGL中构建这一整个东西,但我的建议是你采用另一种方法。 我建议你根据你的json设置在设备上逐帧渲染整个“video”。 这基本上归结为设置你的场景元素,然后确定每个元素在时间[0,1,2]的位置,其中每个数字表示某个帧速率的帧(15,20或24 FPS绰绰有余) 。 首先,请查看我的库中的非平凡iOS动画 ,在其中您将找到一个名为AVOfflineComposition的类,它执行“comp项目并保存到磁盘上的文件”步骤。 显然,这个类并不能满足您的所有需求,但它是创建N个元素组合并将结果写入video文件的基本逻辑的良好起点。 创建comp的关键是,所有读取设置并将对象放在comp中特定位置的代码都可以在离线模式下运行,最后得到的结果是video文件。 将此与维护内存中所有这些元素所涉及的所有细节进行比较,然后根据一切运行的速度更快或更慢地前进。
下一步将创建1个音频文件,该文件是所有复合帧的“电影”的长度,并使其包含特定时间的任何声音。 这基本上意味着在运行时混合音频并将结果保存到输出文件,以便使用AVAudioPlayer轻松播放结果。 你可以看一下我为这类事情写的一些非常简单的PCM混音器代码 。 但是,您可能想要考虑更完整的音频引擎,如theamazingaudioengine 。
有了音频文件和电影文件后,可以使用AVAnimatorMedia类一起播放这些文件并保持同步。 看看这个AVSync示例的源代码,它显示了一个播放video和显示电影的紧密同步的示例。
您的上一个要求可以使用AVAssetWriterConvertFromMaxvid类实现,它实现的逻辑将读取.mvid电影文件,并使用iPhone或iPad上的h.264编码器硬件将其写为h.264编码video。 使用此代码,您不需要编写基于ffmpeg的服务器模块。 此外,这无论如何都行不通,因为将所有未压缩的video上传到您的服务器需要很长时间。 在将video上传或通过应用程序发送电子邮件之前,您需要将video压缩为h.264。