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

Recording & Playback API を使用すると、特定の環境内で動画と AR データを 1 回だけ録画し、そのコンテンツを使用してライブ カメラ セッションを置き換えることができます。

前提条件

続行する前に、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));

再生を最初からやり直す

データセットの先頭から再生を再開するには、セッションを一時停止し、セッションを再開する前に、同じ MP4 録音を指定して ArSession_setPlaybackDatasetUri() を呼び出します。

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

次のステップ