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));

처음부터 재생 다시 시작

데이터 세트의 시작 부분부터 재생을 다시 시작하려면 세션을 재개하기 전에 세션을 일시중지하고 동일한 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.
}

다음 단계