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

借助 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_resume() 之前调用 ArSession_setPlaybackDatasetUri()

因首次调用 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.
}

后续步骤