צילום והפעלה של סשן AR ב-AR Foundation שמטרגט ל-Android

באמצעות Recording & Playback API אפשר להקליט סרטונים ונתוני AR פעם אחת בסביבה נתונה, ולהשתמש בתוכן הזה כדי להחליף סשן מצלמה בשידור חי.

דרישות מוקדמות

לפני שממשיכים, חשוב להבין את המושגים הבסיסיים של AR ואת האופן שבו מגדירים סשן ARCore.

תאימות לממשקי API אחרים של ARCore

בגלל האופן שבו נתוני הסשן מעובדים, יכול להיות ש-ARCore APIs יניבו תוצאות שונות במהלך ההפעלה מאשר במהלך הצילום. ייתכן גם שהן יניבו תוצאות שונות במהלך סשנים של הפעלה עתידיים. לדוגמה, מספר האובייקטים שניתן לעקוב אחריהם שזוהו, התזמון המדויק של הזיהוי שלהם והתנוחות שלהם לאורך זמן עשויים להיות שונים במהלך ההפעלה.

תאימות ל-Cloud Anchors

אתם יכולים לארח ולפתור Cloud Anchors בזמן ההקלטה או ההפעלה של הסשן.

מתבצע תיעוד

איך מתחילים, מפסיקים ובודקים את הסטטוס של הקלטה של סשן ARCore.

הקלטה של סשן ARCore

כדי להקליט סשן ARCore, צריך להגדיר את הסשן ולספק מזהה URI של קובץ MP4 להקלטה. צריך להתקשר למספר ARRecordingManager.StartRecording() לפני שממשיכים את הסשן. ההקלטה תתחיל באופן אוטומטי כשהסשן יתחדש. כדי להפסיק את ההקלטה באופן אוטומטי כשהסשן מושהה, מקישים על ARRecordingConfig.AutoStopOnPause. כדי להקליט סשן חלקי, מקישים על ARRecordingManager.StartRecording() בזמן שהסשן פועל.

ARCoreRecordingConfig recordingConfig = ScriptableObject.CreateInstance<ARCoreRecordingConfig>();
Uri datasetUri = new System.Uri("file:///uri/for/dataset.mp4");
recordingConfig.Mp4DatasetUri = datasetUri.AbsoluteUri;

recordingManager.StartRecording(recordingConfig);

איך מפסיקים את ההקלטה של סשן

כדי להפסיק את ההקלטה בלי להשהות את סשן ה-AR שפועל כרגע, מפעילים את הפקודה ARRecordingManager.StopRecording().

recordingManager.StopRecording();

בדיקת סטטוס הצילום

אפשר להשתמש ב-ARRecordingManager.RecordingStatus בכל שלב כדי לבדוק את סטטוס ההקלטה הנוכחי.

Debug.Log("Current Recording Status: " + recordingManager.RecordingStatus);

הפעלה

הפעלה חוזרת של סשנים קודמים של AR. הסשנים מופעלים בזמן אמת, ואי אפשר לשנות את המהירות או את ההפעלה שלהם.

הפעלה חוזרת של סשן שהוקלט בעבר

כדי להפעיל מחדש סשן שהוקלט בעבר, צריך להפעיל את הפונקציה ARPlaybackManager.SetPlaybackDatasetUri() ולציין את ה-URI של מערך הנתונים שרוצים להפעיל מחדש. כדי להשתמש בשיטה הזו, צריך להשהות את הסשן. כדי שהשינוי ייכנס לתוקף, צריך להמשיך את הסשן.

אחרי שההפעלה תתחיל בגלל חידוש הסשן, השהיה של הסשן על ידי השבתת הלחצן ARSession תגרום להשעיית העיבוד של כל התמונות מהמצלמה ושל כל נתוני החיישן האחרים שתועדו במערך הנתונים. כשהסשן יתחדש, לא תתבצע עיבוד חוזר של מסגרות התמונות מהמצלמה ונתוני המסגרות מהחיישן שהושמדו בדרך הזו. בדרך כלל, מעקב ה-AR בסשן ייפגע בגלל הפער בנתונים שעברו עיבוד.

// Disable the ARSession to pause the current AR session.
session.enabled = false;

// In the next frame, provide a URI for the dataset you wish to play back.
Uri datasetUri = new System.Uri("file:///uri/for/dataset.mp4");
playbackManager.SetPlaybackDatasetUri(datasetUri);

// In the frame after that, re-enable the ARSession to resume the session from
// the beginning of the dataset.
session.enabled = true;

בעיה ידועה ופתרון עקיף

יש בעיה ידועה שבה קריאות ל-ARPlaybackManager.SetPlaybackDatasetUri() מחזירות את הערך ErrorPlaybackFailed. הסיבה לכך היא שיכול להיות שיחלפו כמה פריימים עד שהסשן יושהה. אם ARPlaybackManager.SetPlaybackDatasetUri() יקרא לפני שהסשן יושהה, לא תהיה לו גישה לסשן ולכן הוא יחזיר שגיאה.

אפשר להשתמש בקוד הבא כפתרון חלופי.

// Workaround for known issue where `playbackManager.SetPlaybackDatasetUri()`
// returns `ErrorPlaybackFailed` because it can take several frames for a
// session to be paused.

// Reference to the ARSession component in the scene.
ARSession session;

void PlaybackDataset()
{
    setPlaybackDataset = true;

    // Pause the current AR session.
    session.enabled = false;

    // Set a timeout for retrying playback retrieval.
    timeout = 10f;
}

// Next frame
void Update()
{
    ...

    if (setPlaybackDataset)
    {
        PlaybackResult result = playbackManager.SetPlaybackDatasetUri(datasetUri);
        if (result == PlaybackResult.ErrorPlaybackFailed || result == PlaybackResult.SessionNotReady)
        {
            // Try to set the dataset again in the next frame.
            timeout -= Time.deltaTime;
        }
        else
        {
            // Do not set the timeout if the result is something other than ErrorPlaybackFailed.
            timeout = -1f;
        }

        if (timeout < 0.0f)
        {
            setPlaybackDataset = false;
            // If playback is successful, proceed as usual.
            // If playback is not successful, handle the error appropriately.
        }
    }

    ...
}

הפסקת הפעלה

כדי להפסיק את ההפעלה, קוראים ל-ARPlaybackManager.SetPlaybackDatasetUri() ומגדירים את ה-URI של מערך הנתונים ל-null.

// Disable the ARSession to pause the current AR session.
session.enabled = false;

// In the next frame, unset the playback dataset URI.
playbackManager.SetPlaybackDatasetUri(null);

// In the frame after that, re-enable the ARSession to resume the session using
// the device camera and other sensors.
session.enabled = true;

הפעלה מחדש מההתחלה

כדי להפעיל מחדש את ההפעלה מתחילת מערך הנתונים, צריך להפעיל את הפונקציה ARPlaybackManager.SetPlaybackDatasetUri() ולציין את אותו הקלטת ה-MP4 לפני שממשיכים את הסשן.

// Disable the ARSession to pause the current AR session.
session.enabled = false;

// In the next frame, specify the same dataset URI.
playbackManager.SetPlaybackDatasetUri(datasetUri); // Same URI that was previously set.

// In the frame after that, re-enable the ARSession to resume the session from
// the beginning of the dataset.
session.enabled = true;

הפעלה חוזרת של סשן אחר

כדי להפעיל מערך נתונים אחר, משהים את הסשן ומציינים את מערך הנתונים החדש לפני שממשיכים את הסשן.

// Disable the ARSession to pause the current AR session.
session.enabled = false;

// In the next frame, specify a new dataset URI.
Uri newDatasetUri = new System.Uri("file:///uri/for/different/dataset.mp4");
playbackManager.SetPlaybackDatasetUri(newDatasetUri); // Different URI than was previously set.

// In the frame after that, re-enable the ARSession to resume the session from
// the beginning of the new dataset.
session.enabled = true;

בדיקת סטטוס ההפעלה

אפשר להשתמש ב-ARPlaybackManager.PlaybackStatus בכל שלב כדי לבדוק את סטטוס ההפעלה הנוכחי.

Debug.Log("Current Playback Status: " + playbackManager.PlaybackStatus);

מה השלב הבא?