跳到主要内容

导出到相册与分享

当用户完成创作后,通常需要“保存一段能直接播放的视频”或“发给别人看”。Voxel Kit 提供后台视频导出: 输入一份 VFP,得到完整 MP4 字节;你的应用再决定将它保存到相册、调用分享面板,还是上传至服务端。

这里按用户实际操作说明流程。GLTI、GLB 和恢复校验是导出器内部采用的格式能力;需要字段含义或恢复规则时, 请查阅下方链接的 API 参考。

你需要准备什么

  • 一份完整的 VFP 1.3 ArrayBuffer。若当前只有 JSON,先使用 VfpCompiler 编译;若来自文件选择器,先由 宿主读取 URI 中的文件字节。
  • 一个允许用户保存视频的页面上下文。Voxel Kit 不申请媒体库权限、不弹出系统相册选择器,也不直接写相册。
  • 导出期间的业务状态,例如禁用重复按钮、显示“正在导出”,并在成功后展示保存结果。

VoxelViewer 不必处于可见状态,用户也不必进入编辑模式;这是一个独立的离屏任务。

第一步:导出视频字节

import { VoxelKit, VoxelGltiExportOptions } from 'voxel-kit';

async function createShareVideo(vfpBytes: ArrayBuffer): Promise<ArrayBuffer> {
const options = new VoxelGltiExportOptions();
options.width = 1024;
options.height = 1024;
options.frameRate = 24;
options.durationMs = 3000;
options.antiAliasScale = 2;

return await VoxelKit.createGltiExporter().export(vfpBytes, options);
}

默认结果为 video/mp4,包含一圈模型旋转视频。导出在 HAR 的 Native 异步任务中运行,避免阻塞 ArkUI;但 会使用设备的图形和媒体编码资源。因此一个页面同一时刻只应启动一次导出,并在 try/catch 中处理失败。

第二步:由宿主保存到系统相册

导出器只返回字节,保存到相册是宿主应用的下游业务。推荐顺序是:

  1. ArrayBuffer 写入应用沙箱中的临时 .mp4 文件;
  2. 通过 photoAccessHelper.showAssetsCreationDialog() 请求用户确认相册创建位置;
  3. 将临时文件复制到系统返回的目标 URI;
  4. 无论成功或失败,都关闭文件描述符,并在适当时机清理临时文件。

独立 VoxelHarDemo 的“导出展示 GLTI 到相册”按钮就是该流程的可运行参考。不要让 HAR 静默写入相册: 相册权限、确认对话框、文件名和取消行为都属于应用自身的产品决策。

try {
const mp4Bytes = await createShareVideo(vfpBytes);
// 使用宿主已有的 fileIo + photoAccessHelper 保存流程处理 mp4Bytes。
// 用户取消相册对话框时,保留当前页面并提示“未保存”,不要当作导出失败。
} catch (error) {
// 导出失败时不要保存任何部分文件;允许用户稍后重试。
}

同一份字节也可以交给你的上传接口或分享 SDK。文件扩展名使用 .mp4,MIME 类型使用 video/mp4

是否保留编辑源:独立的打包选择

“保存到相册”与“是否保留编辑源”是两个独立问题。默认值保留编辑源,方便将来在另一设备恢复原 VFP; 关闭后,视频仍可保存、播放、上传和分享,只是无法恢复为编辑工程。

需求embedEditableVfp后续能力
希望其他受控客户端继续编辑true(默认)可由 GltiPackageReader 严格恢复原 VFP。
只需要展示视频或标准 3D 内容false不含私有 VFP,恢复器会拒绝。
const options = new VoxelGltiExportOptions();
options.embedEditableVfp = false; // 仅控制是否保留编辑源
const mp4Bytes = await VoxelKit.createGltiExporter().export(vfpBytes, options);

不要把 false 理解为“只能保存到相册”,也不要把 true 理解为“不能公开分享”。这是由产品的数据保留、 访问控制和内容策略决定的选项;保存目的地由宿主业务决定。

导出质量与失败处理

默认规格为 1024 × 1024 / 24 fps / 3 秒 / 2× 抗锯齿。它不会录制当前页面,因此不含状态栏、按钮、背景图、 加载遮罩或地面网格。若目标设备因为资源或编码能力拒绝任务,可降低尺寸、帧率或时长后重试;不要通过保存 不完整文件来伪装成功。

需要了解的内容参考
导出器的全部字段、范围、返回值与错误VoxelGltiExporter API
从保留编辑源的文件恢复 VFP 的校验规则GltiPackageReader API
透明背景动图而非视频VoxelTurntableExporter