在 Android NDK 上录制时添加自定义数据

《The Recording》和借助 Playback API,您可以录制现场录像并使用它来代替实时摄像头画面。不过,这些记录仅包含视频和传感器数据。您还可以向时段录制添加自定义数据,并在播放期间将该数据返回给您,就好像该数据是相机图片的一部分一样。

ARCore 不会自动在录制内容中包含任何自定义数据。相反,它允许您在录制期间向 ARCore 帧添加自定义数据,并在播放期间从该帧检索相同的数据。您需要对应用进行编程,确保用户在回放会话时能够返回预期数据。

自定义数据的使用场景

向录制内容添加自定义数据可增加 AR 应用的可能性。以下是一些具体用例。

随时随地使用 AR

过去,用户只能在合适的地点和时间获享 AR 体验。如果他们想在客厅放置 AR 灯具,必须亲身站在拍摄地看看 AR 灯具在那里的效果。借助自定义曲目,他们可以在客厅只录制一次视频,然后就可以随时为场景添加虚拟家具。

共同打造 AR 体验

由于没有现场会话要求,用户就拥有更多 AR 编辑选项,因而能够随时随地创建和访问独特的 AR 内容。例如,他们可以录制特定环境、添加增强现实效果并与好友分享。

前提条件

确保您了解 AR 基础概念 以及如何在继续之前配置 ARCore 现场录像

使用自定义数据录制

使用自定义数据创建时段录音。

使用自定义数据初始化记录

如需使用自定义数据初始化录音,请按以下步骤操作。如需开始、停止和检查录制会话,请参阅录制和播放 AR 会话

  1. 获取 ArRecordingConfig
  2. 使用自定义 UUID 创建一个新的 ArTrack。所有自定义数据都将保存在此处。
  3. ArTrack 添加到您在会话配置期间创建的 ArRecordingConfig
// Initialize a new track with a custom UUID.
// Make sure to save the UUID because it is the ID that you will use to get
// your data back during playback.
ArTrack* track = NULL;
ArTrack_create(ar_session, &track);
// String from UUID generator: de5ec7a4-09ec-4c48-b2c3-a98b66e71893
uint8_t uuid_byte_array[16] = {0xde, 0x5e, 0xc7, 0xa4, 0x09, 0xec,
                               0x4c, 0x48, 0xb2, 0xc3, 0xa9, 0x8b,
                               0x66, 0xe7, 0x18, 0x93};
ArTrack_setId(ar_session, track, uuid_byte_array);

// Add the ArTrack to the recording_config.
// recording_config must already be configured.
ArRecordingConfig_addTrack(ar_session, recording_config, track);
ArTrack_destroy(track);

所有新曲目均被视为单独的录音,每个录制的曲目占用自己的 UUID。

可选:使用其他数据配置轨道

为便于以后识别,您可以使用其他数据来配置轨道,以描述会话录音。例如,您可以通过添加备注来说明您录制现场录像的位置和时间:“本次现场录像是在下午在商场录制的”,以此“标记”曲目。

// Set additional data on this track.
// For example, describe where you recorded the session.
uint8_t metadata_size = 4;
uint8_t metadata[5] = "HOME";
ArTrack_setMetadata(ar_session, track, metadata, metadata_size);

可选:使用 MIME 类型配置轨道

如果您的应用需要与外部工具兼容,您可以使用 MIME 类型配置轨道,描述轨道中记录的数据类型。如果您未指定类型,数据将归类为 application/text。读取数据时,ARCore 会忽略 MIME 类型。

// Set a MIME type for compatibility with external tools.
ArTrack_setMimeType(ar_session, track, "text/csv");

录制自定义数据轨道

所有自定义轨道数据都会记录到 ArFrame 上。AR 会话使用 ArSession_update() 获取帧。将数据录制到帧上的时间与播放过程中返回数据的时间相同。例如,如果您调用 ArFrame_recordTrackData() 并将值“A”设为 00:07:02,则播放曲目时,您将在 00:07:02 标记处返回“A”。

如需录制自定义数据轨道,请调用 ArFrame_recordTrackData()

// Place an AR lamp in a room.
if (place_lamp_button_was_pressed) {
  uint8_t lamp_data[1] = {lamp_id};
  ArFrame_recordTrackData(ar_session, frame, uuid_byte_array, lamp_data,
                          /*payload_size=*/1);
}

播放自定义数据轨道

在播放期间从现场录像中提取自定义数据。

初始化播放

使用自定义数据初始化播放与初始化常规时段录音的播放相同。

返回自定义数据

调用 ArFrame_getUpdatedTrackData() 以检索在 ArFrame 中记录的自定义数据。您可以从同一帧中检索多个轨道数据。例如,如果您在录制期间对同一帧调用了两次 ArFrame_recordTrackData(),则会在播放期间返回两个 ArTrackData 实例。

// Create the container to hold the track data retrieved from the frame.
ArTrackDataList* fetched_track_data_list;
ArTrackDataList_create(ar_session, &fetched_track_data_list);

// Fetch the track data from the frame into the created container.
ArFrame_getUpdatedTrackData(ar_session, frame, uuid_byte_array,
                            fetched_track_data_list);

ArTrackData 位于容器对象中后,提取自定义数据的字节。

// Fetch the size of the track data list.
int32_t fetched_track_data_list_size;
ArTrackDataList_getSize(ar_session, fetched_track_data_list,
                        &fetched_track_data_list_size);

// Iterate through the list.
for (int i = 0; i < fetched_track_data_list_size; i++) {
  ArTrackData* fetched_track_data;
  ArTrackDataList_acquireItem(ar_session, fetched_track_data_list, i,
                              &fetched_track_data);
  // Process "fetched_track_data->sample" as desired
  ArTrackData_release(fetched_track_data);
}
ArTrackDataList_destroy(fetched_track_data_list);

后续步骤