在 Android NDK 上录制和播放 AR 现场录像

《The Recording》和借助 Playback API,您可以在给定环境中录制一次视频和 AR 数据,然后使用这些内容替换实时摄像头会话。

前提条件

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

与其他 ARCore API 的兼容性

由于会话数据的处理方式不同,ARCore API 在播放期间产生的结果可能与记录期间观察到的结果不同。在后续播放会话中,它们也可能会产生不同的结果。例如,在播放过程中,检测到的可跟踪对象的数量、检测的精确时间及其位置方向随时间而变化。

与云锚点的兼容性

您可以在录制或回放会话时托管和解析云锚点

正在录制

开始、停止和检查 ARCore 现场录像的状态。

录制 ARCore 现场录像

如需录制 ARCore 现场录像,请配置现场录像并提供录制的 MP4 URI。在第一次调用 ArSession_resume() 之前调用 ArSession_startRecording()。会话恢复后,系统会自动开始录制。如需在会话暂停时自动停止录制,请调用 ArRecordingConfig_setAutoStopOnPause()。如需录制部分会话,请在会话运行时调用 ArSession_startRecording()

ArRecordingConfig* recording_config = nullptr;
ArRecordingConfig_create(ar_session, &recording_config);
ArRecordingConfig_setMp4DatasetUri(ar_session, recording_config,
                                   mp4_dataset_uri);
ArRecordingConfig_setAutoStopOnPause(ar_session, recording_config, true);

CHECK(ArSession_startRecording(ar_session, recording_config));
// …
// Resume ARCore session to start recording.
CHECK(ArSession_resume(ar_session));
// …
// Recording ends.
CHECK(ArSession_pause(ar_session));

停止录制

要在不暂停当前正在运行的 AR 会话的情况下停止录制,请调用 ArSession_stopRecording()ArRecordingConfig_destroy()

ArStatus status = ArSession_stopRecording(ar_session);
ArRecordingConfig_destroy(recording_config);

查看录制状态

ArSession_getRecordingStatus() 可随时用于确定当前的 ArRecordingStatus

ArRecordingStatus recording_status;
// Can be called at any time.
ArSession_getRecordingStatus(ar_session, &recording_status);
if (recording_status == AR_RECORDING_NONE) {
  // The dataset recorder is not recording.
} else if (recording_status == AR_RECORDING_OK) {
  // The dataset recorder is recording normally.
} else if (recording_status == AR_RECORDING_IO_ERROR) {
  // The dataset recorder encountered an error while recording.
}

播放

播放之前录制的 AR 会话。课程会实时播放,且无法调整课程播放或速度。

播放之前录制的会话

要播放之前录制的会话,请调用 ArSession_setPlaybackDatasetUri() 在对 ArSession_resume()

因首次调用 ArSession_resume() 而开始播放后,通过调用 ArSession_pause() 暂停会话后,系统会暂停处理数据集中的所有相机图像帧和任何其他已记录的传感器数据。当通过调用 ArSession_resume() 再次恢复会话时,系统不会重新处理以这种方式舍弃的相机图像帧和传感器帧数据。由于所处理的数据存在缺口,相应会话的 AR 跟踪通常会受到影响。

// Specify previously recorded MP4 file.
CHECK(ArSession_setPlaybackDatasetUri(ar_session, mp4_dataset_uri));
// …
// Playback starts from the beginning of the dataset.
CHECK(ArSession_resume(ar_session));
// …
// Pause AR session, but allow playback to silently continue.
CHECK(ArSession_pause(ar_session));
// …
// Resume AR session. Playback continues with gap to paused session.
CHECK(ArSession_resume(ar_session));

从头开始重新播放

如需从数据集开头重新播放,请暂停会话并 致电 ArSession_setPlaybackDatasetUri()、 然后继续会话前指定相同的 MP4 录制。

CHECK(ArSession_pause(ar_session));
// Pause and specify the *same* dataset:
CHECK(ArSession_setPlaybackDatasetUri(ar_session, mp4_dataset_uri));
// Playback starts from the *beginning* of the dataset.
CHECK(ArSession_resume(ar_session));

播放其他会话

如需播放其他数据集,请暂停会话并指定新数据集 然后再继续会话

CHECK(ArSession_pause(ar_session));
// Pause and specify a *different* dataset:
CHECK(ArSession_setPlaybackDatasetUri(ar_session, other_mp4_dataset_uri));
// Playback starts from the *beginning* of the new dataset.
CHECK(ArSession_resume(ar_session));

检查播放状态

使用 ArSession_getPlaybackStatus(),随时确定当前的 ArPlaybackStatus

ArPlaybackStatus playback_status;
// Can be called at any time.
ArSession_getPlaybackStatus(ar_session, &playback_status);
if (playback_status == AR_PLAYBACK_NONE) {
  // The session is not playing back an MP4 dataset file.
} else if (playback_status == AR_PLAYBACK_OK) {
  // Playback is in process without issues.
} else if (playback_status == AR_PLAYBACK_IO_ERROR) {
  // Playback has stopped due to an error.
} else if (playback_status == AR_PLAYBACK_FINISHED) {
  // Playback has finished successfully.
}

后续步骤