常见问题
问:PAG 收费吗?
PAG 已正式对外开源,采用 Apache 2.0 协议,可以商用,是不收费的。
问:PAG 支持哪些平台?
PAG 的渲染 SDK 目前已经支持 Android、iOS、macOS、Windows、Linux、Web 和微信小程序等平台。 桌面预览工具 PAGViewer 和 AE 导出插件同时支持 macOS 和 Windows 平台。目前在 Android、iOS、Web 和微信小程序平台上我们会定期发布预编译的制品库,具体接入参考:
其他平台由于没有统一的 UI 框架或者使用上本来也需要自己做一些渲染桥接的适配,我们没有发布统一的预编译制品库,可以自行从Github 的源码进行构建。
问:PAG 源码编译的时候报错了怎么处理?
PAG 项目的编译依赖一些第三方库的下载同步,以及正确版本的编译工具安装。在运行 Demo 前请务必先阅读位于根目录的 README.md,根据 开发指南 一节的指引进行依赖同步和编译环境配置。如还有问题,可以在PAG论坛向我们反馈。
问:PAG 支持模拟器吗?在模拟器上测试性能是否准确?
PAG 只保证 UI 动画在模拟器里的基本预览,不建议在模拟器上高强度使用或者进行性能测试。PAG 是一个全链路 GPU 加速的 渲染方案,在模拟器上由于无法开启 GPU 加速,性能会比实际情况差很多,另外模拟器也缺失部分必要的接口,导致一些配合高级视频编辑功能的接口在模拟器上也不支持。例如无法绘制到 CVPixelBuffer 离屏对象上。另外模拟器也不是真实用户场景,性能测试请使用真机进行。
问:在 iOS 上测试了一个 PAG 动效播放,为什么内存占用有 100 多 M 那么大?
PAG 是纯 GPU 渲染的方案,任何一个 GPU 渲染的方案都会有一个初始的屏幕缓冲区开销,如果测试的时候是全屏的,每个像素都需要占用 4 字节的内存,加上双缓冲整体还要乘以 2,已经占用了几十 M 内存了。这个本身不是 PAG 动效占用的内存,而是任何 GPU 渲染方案的基本占用,但是它并不是线性增长的。PAG 提供了合并渲染的能力,你只需要创建一个 PAGView 就可以绘制无数个 PAG 动效文件上去,举个例子,共享 PAGView 的情况下,初始开销可能是几十 M,但是每增加一个 PAG 动效文件可能只增加几 M,所以不能通过一个全屏的 PAGView 测试单个 PAG 文件播放的内存占用来推理 N 个 PAG 动效的内存占用。要放到实际业务场景中进行测试才有意义。
实际业务场景通常是分这两种情况:
1.渲染的数量特别巨大,同屏可能有几十个上百个动效。这种场景下应该只创建一个 PAGView, 把 N 个动效文件合并渲染到同一个 PAGView 上,可以实现很少的内存占用就完美支持巨大数量的动效渲染。另外如果是在直播或者视频编辑里,本身已经创建过一个初始的 OpenGL 环境,还可以让 PAG 复用这个环境进行离屏渲染,也就不存在双缓冲的初始内存占用了。其实使用系统 UI 的 API 进行渲染没有额外双缓冲开销也是一样的原理,因为系统已经创建了一个全局默认的。
2.渲染的数量不多或者面积不大。这种场景下因为总面积不大,即使用了多个 PAGView,双缓冲中的额外内存占用其实也没有构成内存瓶颈,也就没有必要去做合并渲染的优化。直接正常使用 PAGView 即可。但是如果你本来就能够复用一个 PAGView 同时播放多个动效的,建议还是放在一起渲染,内存会进一步降低,性能也会更好。
总结一下:通过构造一个全屏的 PAGView 播放动效的测试 Demo,无法推理出实际的内存占用情况,建议按实际场景里出现的数量和动效最终使用面积来测试真实的内存占用。如果已经是按以上方式在真实场景下进行的内存测试,依然很高。那么问题可能出现在素材上。不同的素材本身内存占用也会有很大的区别。通常情况下过多使用 BMP 预合成会导致内存增量变高很多,因为涉及视频解码,会缓存非常多帧的内存。建议参考官网的素材优化指南来进行针对性优化。如果问题还是无法解决,可以再通过PAG论坛围绕具体 case 分析解决。
问:PAG 支持 Flutter 使用吗?
PAG 支持 Flutter 使用,具体原理是通过外部纹理做桥接,PAG 可以将动效逐帧绘制到指定的纹理上。因此,外部的任何框架包括 Flutter 只要能提供一个纹理给 PAG 绘制,都可以完美实现桥接或融合。具体请搜索 Flutter 外接纹理接口,提供一个纹理包装成 PAGSurface后,然后使用 PAGPlayer 正常进行绘制控制即可。
可以参考:https://github.com/libpag/pag-flutter.git。
问:PAG 与视频编辑的关系?
PAG 诞生之初就是为了解决视频编辑场景下的复杂动效效果渲染需求,提供了相关接口可以便捷的与原生视频渲染链路相整合,但 PAG 本身并不是视频编辑框,它只负责动效的渲染的部分。视频编辑框架是另一个范畴的技术领域,需要业务方自己开发或者接入行业里成熟的方案,解决视频编解码,合成,导出等能力。
在视频编辑框架方面,我们目前已把在腾讯内业务使用的成熟音视频编辑框架 TAVMedia 正式对外开放使用,TAVMedia 可以提供几乎跨所有平台的视频编辑及模板制作能力,集成了剪辑、拼接、特效、转场、播放、导出等功能,并内置了对PAG素材的原生支持。相比第三方视频编辑框架TAVMedia针对PAG做了大量的内部优化,可以最大化发挥PAG素材的极限渲染性能。帮助用户聚焦业务本身,快速轻松实现多平台(Andorid、iOS,服务端)的视频编剪和模板应用。更详细的信息可以访问 TAVMedia 动效素材服务。
问:PAG 文件为什么在移动端播放不出声音?
PAG 文件支持集成音频数据,导出方法具体方法参照 如何在AE中导出音频。但 PAG SDK 仍然还是一个动效渲染库,目前只渲染画面的部分,播放或者合成到视频需要业务方使用音视频框架自行处理。研发侧可以从 PAGFile.audioBytes 接口上读取 PAG 内置的音频数据,将它存储为本地文件使用或者直接在内存中解码都可以。audioBytes 字节流的编码格式为 AAC,容器格式为 MPEG-4。
问:PAG SDK是否支持加载网络文件?
PAG SDK专注于动效渲染,没有内置网络模块,因此是不支持的。 对于大部分APP而言,一般都包含网络模块和缓存模块,直接使用APP中内置的基础模块即可。
问:PAG Windows 版本是否可以直接和 DirectX 11 的现有游戏结合?
目前没有计划要去直接支持 DX 的渲染后端,但是通过 Google 的 ANGLE 项目把 DX 包装成 OpenGL 让 PAG 进行渲染。目前 Chrome 在 Windows 上也是采用的这种实现方案。
问:PAGViewer 里执行占位图替换或者文本编辑后,怎么导出 PAG 文件?
PAGViewer 并没有导出 PAG 文件的能力,只是一个预览工具。PAG 文件只能通过 AE 插件进行导出。这里可能是对 PAG 使用方式上的理解存在误区。PAG 提供的运行时编辑替换功能不是用来生成新的 PAG 文件的,编辑的产物应该是生成一个视频或直接播放动效。可以把 PAG 文件理解为一个动效模板,运行时可以替换为用户千变万化的个性信息,组合出无限的可能,如果每种可能都生成一个新的PAG 文件就失去了模板的意义了,这样导致用户使用的时候要下载无数个 PAG 文件。而正确的用法应该是始终只有一个 PAG 文件,但是可以播放或者渲染出无数的组合效果。
问:PAG 导出插件是否支持 AE 表达式?
AE 表达式还没有原生支持,因为涉及了 JS 虚拟机植入,包会很大,还在考虑最好的方案。但目前是可以导出包含表达式的动效内容的,可以参考如下两种方式导出:
- 右键含有表达式的图层,使用快捷菜单可以把表达式转换为标准的关键帧,然后导出即可。
- 包含表达式效果的图层,如果不需要在运行时被编辑,也可以标记为 BMP 预合成 后导出,这种方式不仅可以导出表达,包含 3D 属性甚至第三方插件的效果也可导出。
问:导出 PAG 时弹出了一个优化建议页面,是什么意思?
提示页面包含两种信息,一种是性能优化建议,发现素材性能不理想时可以根据提示进行优化。另一种是显示当前不支持的能力,对于不支持的能力,可以转化为BMP预合成来导出,可以参考BMP预合成导出,可以在 AE特性列表 查看支持直接被导出的 AE 特性列表。
问:添加了很多特效(Effect),但导出后不见了?
可以在 AE特性列表 里找到目前支持直接导出的特效。如果没有在这个列表里,但特效并不是用在运行时可编辑的图层上(不打算替换内容),或者这是第三方插件的特效,可以转化为BMP预合成来导出,可以参考 BMP预合成导出。如果你需要用在运行时可编辑的图层上,目前还不支持直接导出,可以通过PAG论坛或者 Github 给我们提个需求,我们会根据需求的通用程度排出优先级逐个提供支持。
问:标记为 BMP 预合成后,本来不支持的效果就可以导出了,但感觉清晰度不太够?
可以在对插件选项进行配置,请参考这个文档 插件选项配置面板 与清晰度有关的参数是:
通用
页面下的图像压缩质量
和位图像素密度
BMP预合成
页面下的图像压缩质量
但通常情况下并不需要修改这些默认参数,它们已经被设置在文件大小和清晰度的最佳平衡点上。通常情况下清晰度问题更多是由于额外的素材转换操作导致的。例如提前把一些效果转换成视频放进 AE 里再标记为 BMP 预合成导出,或者自行对图片资源进行压缩后放进 AE 使用。所有这些操作只会导致清晰度降低,并不会对最终导出的 PAG 文件带来任何的文件大小优化。PAG 导出插件已经内置了极高压缩率的算法,请不要额外做任何额外的优化文件大小操作,在 AE 中请一律使用最高清的资源进行动效设计,最终交给 PAG 导出插件来进行统一的压缩就行。 我们推荐如下最佳实践:
- 能用矢量直接绘制的,比如图形或者文本,就不要使用 PS 转换为图片再导入 AE 使用。直接在 AE 里绘制。
- 如果必须从外部工具导入 AE 的资源,且原始资源本身就是矢量的,请尝试转换为 AE 原生的图层类型,否则 PAG 无法识别只能截图处理。
- 无法直接进行导出的 AE 特效,不要自行转成视频放进来再标记为 BMP 预合成导出,标记为 BMP 预合成本来就是帮你截图压缩成视频,两次视频压缩会导致清晰度降低。直接标记为 BMP 预合成让 PAG 导出原始的图层即可。
- 注意一下导出的分辨率是否足够。如果是矢量的内容,跟分辨率无关。如果导出的动效包含位图或者 BMP 预合成,清晰度跟根节点的总预合成的尺寸直接相关。在满足清晰度的情况下,尽可能选择合适的分辨率。
问:导出的 PAG 文件在客户端渲染时为什么会有色差?
桌面预览工具 PAGViewer(2.1.40版本以上) 和客户端 SDK 使用的色彩空间都已经修正为 sRGB。目前解决色差最佳的方式还是 sRGB, 类似 P3 这种广色域的色彩空间并不是所有设备都能支持。如果 AE 设置的是其他色彩空间,请修改为 sRGB,否则导出的 PAG 文件在 渲染的时候可能会出现色差。
问:导出的 PAG 文件为什么播放卡顿不流畅,如何优化素材性能?
PAG 同时支持纯矢量导出(包含图片图层)和 BMP 预合成导出。素材的性能问题通常都是因为过多使用了 BMP 预合成导致的, 针对 BMP 预合成的使用可以参考如下规则:
- 尽量不用:通常只有在正常导出效果不正确时,才使用BMP预合成。可以参考 AE特性列表 文档查看支持直接导出的 AE 特性。
- 尽量少用:如果有多个图层和预合成需要使用BMP预合成,尽量将它们合并,以减少BMP预合成的数目。
- 控制面积:尽可能避免巨大面积的预合成标记为 BMP 预合成导出,只拆解必要的动效区域出来标记为 BMP 预合成导出。
通过以上方式已经能解决绝大部分的素材性能问题,其他更多的素材优化技巧可以参考 PAG 素材优化指南 。 我们定期也会组织面向设计师的在线培训课程,分享素材制作的技巧和新的插件功能,如有需要请关注PAG论坛。
问:如何只播放 PAG 文件的某个区间或者调整播放速度?在 PAGView 上没有找到接口。
这类功能大家可能直觉地会想到去 PAGView 或 PAGPlayer 这些播放控制类上找,但其实应该通过操作 PAGFile 来实现任何定制化的播放需求。
区间播放:首先通过 PAGComposition.Make() 方法创建一个空的 PAGComposition 容器,然后通过它的 addLayer 接口添加你想要播放的 PAGFile 对象。接着你可以对这个 PAGFile 调用 setStartTime 和 setDuration 来控制你想播放的具体区间。最后把这个总的 PAGComposition 交给 PAGView 去播放即可。
举例:一个8s长的pag文件需要循环播放3~6s,将PAGFile添加到PAGComposition后,设置PAGFile的startTime为-3000000,duration为6000000
变速播放:首先设置 PAGFile.setTimeStretchMode(PAGTimeStretchMode.Scale),然后通过 PAGFile.setDuration() 接口设置你想变速后播放的时长即可,设置比原始更长时间是慢速播放,设置更短时间是快速播放。
PAG 提供了非常灵活的图层级别控制 API,运行时可以自由排列组合多个 PAGFile,通过 setStartTime 和 setDuration 控制时间轴,通过 setMatrix 控制相对位置,也可以对图层进行增删改等等。具体可以参考 PAGLayer 以及 PAGComposition 等类的相关接口。通过图层级别的控制 API,你也可以设计一系列复杂的原子特效组合特性,在制作 PAG 素材时就不在需要把各种排列组合的场景都逐一在 AE 拼装导出一遍,而是只要导出拆分的原子 PAG 文件,然后运行时通过编程控制可以组合出无限种类的效果。
问:Android端pag生成视频的时长在不同的手机上表现不一致,甚至相差10秒左右
这里是时间戳设置问题,不能将系统时间戳用于视频编码,不同配置的手机解码性能是不一样的,都会影响到时间戳。需要通过渲染进度计算出来准确的时间戳,脱离跟运行性能的关联。
问:Linux 端文本为啥无法正常显示?PAG 中字体加载的策略是什么?
由于字体文件一般都比较大,pag中不会包含字体文件,但文本内容的显示依赖于字体文件。
在Android、iOS、macOS、Windows端,我们内部注册了系统字体,所以即便使用方没有注册字体,文本内容也能够显示出来。在Linux没有注册默认字体的逻辑,因此如果没有注册字体,文本是无法正常显示的。
如果需要显示特定字体,无论那个平台就需要进行字体注册。字体注册相关接口参考PAGFont的相关方法。 RegisterFont方法用来注册字体,SetFallbackFontPaths用来设置字体回退列表。当输入文本在注册字体文件中查找不到时,会使用回退列表中的字体。
问:PAG 的 AE 导出插件闭源的原因是什么呢?未来会开源么?
答案是不会。举个大家比较熟悉的例子可能更好理解:谷歌的 Chrome 浏览器也不是开源的,开源的是核心的 Chromium 项目。目前开源的 libpag 项目不只是一个渲染库,PAG 文件的核心编解码模块也在其中是完全开源的。所以从原理上如果你希望从头实现一个 AE 导出插件,现在并不存在什么技术上的阻碍,只需要调用 AE SDK 和 PAG 的编码 SDK 即可,剩下的都是一些 UI 业务代码的工作,这部分并没有多少技术含量。那为什么我们不开源这部分 UI 业务的代码呢?实际上你如果只是正常使用 PAG 方案,不是为了快速创造一种不兼容的 PAG 分裂格式,是不会涉及到任何 AE 导出插件代码的内容。但如果开源这部分代码,会显著降低创造一种新的分裂格式的门槛。PAG 的格式跟其他各种图片格式不太一样,它并不是制定完标准后就固化的格式,而是一种动态演进的格式,会随着 AE 功能的支持变多而不断增量变化。如果采用去中心化的管理方式,我们很难保证 PAG 的通用一致性。一旦产生很多分裂版本的格式后,会沦为某些特定业务的私有格式,各种优化无法回馈到社区。设计师也要面对同一个资源可能要导出多种格式的额外工作量,并且需要重复生产大量相似的动效素材,而不能直接复用存量已经导出的资源。这对动效素材社区的发展不利,也是我们非常不愿意看到的。