Android NDK で AR セッションを録画して再生する

録画と再生 API を使用すると、指定された環境で動画と AR のデータを 1 回録画し、そのコンテンツを使用してライブカメラ セッションを置き換えることができます。

Prerequisites

先に進む前に、基本的な AR のコンセプトARCore セッションの構成方法を理解しておいてください。

他の ARCore API との互換性

セッション データの処理方法により、ARCore API は再生中に記録中に観測された結果とは異なる結果を生成することがあります。また、それ以降の再生セッションで異なる結果になることがあります。たとえば、検出された追跡可能アイテムの数、検出の正確なタイミング、時間の経過に伴う姿勢は、再生中に異なる場合があります。

Cloud Anchors との互換性

セッションを録画または再生しながら、Cloud Anchors をホストして解決できます。

録画中

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.
}

次のステップ