ARCore রেকর্ডিং এবং প্লেব্যাক API এর ভূমিকা

1. ভূমিকা

একটি MP4 ফাইলে একটি AR অভিজ্ঞতা সংরক্ষণ করতে এবং MP4 ফাইল থেকে প্লে ব্যাক করতে সক্ষম হওয়া অ্যাপ ডেভেলপার এবং শেষ ব্যবহারকারী উভয়ের জন্যই উপযোগী হতে পারে।

ডিবাগ করুন এবং আপনার ডেস্ক থেকে নতুন বৈশিষ্ট্য পরীক্ষা করুন

ARCore Record & Playback API-এর সবচেয়ে সহজবোধ্য ব্যবহার হল ডেভেলপারদের জন্য। সেই দিনগুলি চলে গেছে যেখানে আপনাকে একটি পরীক্ষা ডিভাইসে অ্যাপ তৈরি করতে হবে এবং চালাতে হবে, USB কেবলটি সংযোগ বিচ্ছিন্ন করতে হবে এবং শুধুমাত্র একটি ছোট কোড পরিবর্তন পরীক্ষা করার জন্য ঘুরে বেড়াতে হবে। এখন আপনাকে প্রত্যাশিত ফোন চলাচলের সাথে পরীক্ষার পরিবেশে একটি MP4 রেকর্ড করতে হবে এবং সরাসরি আপনার ডেস্ক থেকে পরীক্ষা করতে হবে।

বিভিন্ন ডিভাইস থেকে রেকর্ড এবং প্লে ব্যাক

রেকর্ডিং এবং প্লেব্যাক এপিআইগুলির সাথে, একজন ব্যবহারকারী একটি ডিভাইস ব্যবহার করে একটি সেশন রেকর্ড করতে পারে এবং অন্য একটি ভিন্ন ডিভাইসে একই সেশন প্লে ব্যাক করতে পারে। অন্য ব্যবহারকারীর সাথে একটি AR অভিজ্ঞতা শেয়ার করা সম্ভব। সম্ভাবনা অনেক আছে!

আপনি কি এই প্রথম কোনো ARCore অ্যাপ তৈরি করছেন?

না. হ্যাঁ।

আপনি কিভাবে এই কোডল্যাব ব্যবহার করবেন?

শুধুমাত্র এটি মাধ্যমে পড়ুন এটি পড়ুন এবং ব্যায়াম সম্পূর্ণ করুন

আপনি কি নির্মাণ করবেন

এই কোডল্যাবে, আপনি একটি অ্যাপ তৈরি করতে রেকর্ডিং এবং প্লেব্যাক API ব্যবহার করবেন যা উভয়ই একটি MP4 ফাইলে একটি AR অভিজ্ঞতা রেকর্ড করে এবং একই ফাইল থেকে অভিজ্ঞতাটি প্লে করে। আপনি শিখবেন:

  • একটি MP4 ফাইলে একটি AR সেশন সংরক্ষণ করতে রেকর্ডিং API কীভাবে ব্যবহার করবেন।
  • একটি MP4 ফাইল থেকে একটি AR সেশন রিপ্লে করতে প্লেব্যাক API কীভাবে ব্যবহার করবেন।
  • কীভাবে একটি ডিভাইসে একটি এআর সেশন রেকর্ড করবেন এবং অন্যটিতে এটি পুনরায় চালাবেন।

আপনি কি প্রয়োজন হবে

এই কোডল্যাবে, আপনি হ্যালো এআর জাভা অ্যাপটি সংশোধন করবেন, যেটি ARCore Android SDK দিয়ে তৈরি। অনুসরণ করার জন্য আপনার নির্দিষ্ট হার্ডওয়্যার এবং সফ্টওয়্যার প্রয়োজন হবে।

হার্ডওয়্যার প্রয়োজনীয়তা

  • একটি ARCore সমর্থিত ডিভাইস যেখানে বিকাশকারী বিকল্পগুলি চালু আছে ৷ এবং USB ডিবাগিং সক্ষম, একটি USB তারের মাধ্যমে আপনার ডেভেলপমেন্ট মেশিনে সংযুক্ত।
  • একটি ডেভেলপমেন্ট মেশিন যেখানে আপনি অ্যান্ড্রয়েড স্টুডিও চালান।
  • বিকাশের সময় লাইব্রেরি ডাউনলোড করার জন্য ইন্টারনেটে অ্যাক্সেস।

সফ্টওয়্যার প্রয়োজনীয়তা

সেরা ফলাফলের জন্য আপনার ARCore সম্পর্কে প্রাথমিক ধারণাও থাকতে হবে।

2. আপনার উন্নয়ন পরিবেশ সেট আপ করুন

আপনার উন্নয়ন পরিবেশ সেট আপ করে শুরু করুন.

ARCore Android SDK ডাউনলোড করুন

SDK ডাউনলোড করতে ক্লিক করুন।

ARCore Android SDK আনজিপ করুন

একবার আপনি আপনার মেশিনে Android SDK ডাউনলোড করলে, ফাইলটি আনজিপ করুন এবং arcore-android-sdk-1.24/samples/hello_ar_java ডিরেক্টরিতে নেভিগেট করুন। এটি অ্যাপটির রুট ডিরেক্টরি যা আপনি নিয়ে কাজ করবেন।

হ্যালো-আর-জাভা-নিষ্কৃত

Android স্টুডিওতে Hello AR Java লোড করুন

অ্যান্ড্রয়েড স্টুডিও চালু করুন এবং একটি বিদ্যমান অ্যান্ড্রয়েড স্টুডিও প্রকল্প খুলুন ক্লিক করুন।

অ্যান্ড্রয়েড-স্টুডিও-ওপেন-প্রকল্প

ফলস্বরূপ ডায়ালগ উইন্ডোতে, arcore-android-sdk-1.24/samples/hello_ar_java নির্বাচন করুন এবং খুলুন ক্লিক করুন।

অ্যান্ড্রয়েড স্টুডিও প্রকল্পটি সিঙ্ক করা শেষ করার জন্য অপেক্ষা করুন। অনুপস্থিত উপাদান থাকলে, প্রকল্প আমদানি ত্রুটি বার্তা সহ ব্যর্থ হতে পারে। চালিয়ে যাওয়ার আগে এই সমস্যাগুলি ঠিক করুন।

নমুনা অ্যাপ চালান

  1. আপনার ডেভেলপমেন্ট মেশিনে একটি ARCore সমর্থিত ডিভাইস সংযুক্ত করুন।
  2. ডিভাইসটি সঠিকভাবে স্বীকৃত হলে, আপনি Android স্টুডিওতে ডিভাইসের নামটি দেখতে পাবেন। android-studio-pixel-5.png
  3. অ্যান্ড্রয়েড স্টুডিও ইনস্টল করতে এবং ডিভাইসে অ্যাপটি চালু করতে রান বোতামে ক্লিক করুন বা রান > রান 'অ্যাপ' নির্বাচন করুন। android-studio-run-button.png
  4. আপনি ছবি তোলা এবং ভিডিও রেকর্ড করার অনুমতি চাওয়ার জন্য একটি প্রম্পট দেখতে পাবেন। অ্যাপটিকে ক্যামেরা অনুমতি দেওয়ার জন্য এই অ্যাপটি ব্যবহার করার সময় নির্বাচন করুন। তারপর আপনি ডিভাইসের স্ক্রিনে আপনার বাস্তব-বিশ্বের পরিবেশ দেখতে পাবেন। হ্যালো-আর-জাভা-অনুমতি
  5. প্লেনের জন্য স্ক্যান করতে ডিভাইসটিকে অনুভূমিকভাবে সরান।
  6. অ্যাপটি একটি প্লেন শনাক্ত করলে একটি সাদা গ্রিড প্রদর্শিত হয়। সেই সমতলে একটি মার্কার স্থাপন করতে এটিতে আলতো চাপুন৷ হ্যালো এআর প্লেসমেন্ট

আপনি এই ধাপে কি করেছেন

  • হ্যালো এআর জাভা প্রজেক্ট সেট আপ করুন
  • একটি ARCore সমর্থিত ডিভাইসে নমুনা অ্যাপ তৈরি এবং চালান

এর পরে, আপনি একটি MP4 ফাইলে একটি AR সেশন রেকর্ড করবেন।

3. একটি MP4 ফাইলে একটি ARCore সেশন রেকর্ড করুন৷

আমরা এই ধাপে রেকর্ডিং বৈশিষ্ট্য যোগ করব। এটি গঠিত:

  • রেকর্ডিং শুরু বা বন্ধ করার জন্য একটি বোতাম।
  • ডিভাইসে MP4 ফাইল সংরক্ষণ করার জন্য স্টোরেজ ফাংশন।
  • ARCore সেশন রেকর্ডিং শুরু বা বন্ধ করতে কল।

রেকর্ড বোতামের জন্য UI যোগ করুন

আপনি রেকর্ডিং বাস্তবায়ন করার আগে, UI-তে একটি বোতাম যোগ করুন যাতে ব্যবহারকারী ARCore কে কখন রেকর্ডিং শুরু বা বন্ধ করতে পারে তা জানাতে পারে।

প্রজেক্ট প্যানেলে, app/res/layout/activity_main.xml ফাইলটি খুলুন।

কার্যকলাপ_প্রধান-এক্সএমএল-লোকেশন-ইন-প্রজেক্ট

ডিফল্টরূপে, আপনি app/res/layout/activity_main.xml ফাইলটি খোলার পরে Android স্টুডিও ডিজাইন ভিউ ব্যবহার করবে। কোড ভিউতে স্যুইচ করতে ট্যাবের উপরের ডানদিকের কোড বোতামে ক্লিক করুন।

swith-to-the-code-view.png

activity_main.xml এ, নতুন রেকর্ড বোতাম তৈরি করতে ক্লোজিং ট্যাগের আগে নিম্নলিখিত কোড যোগ করুন এবং এর ইভেন্ট হ্যান্ডলারকে onClickRecord() নামক একটি পদ্ধতিতে সেট করুন:

  <!--
    Add a new "Record" button with those attributes:
        text is "Record",
        onClick event handler is "onClickRecord",
        text color is "red".
  -->
  <Button
      android:id="@+id/record_button"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignLeft="@id/surfaceview"
      android:layout_alignBottom="@id/surfaceview"
      android:layout_marginBottom="100dp"
      android:onClick="onClickRecord"
      android:text="Record"
      android:textColor="@android:color/holo_red_light" />

আপনি উপরের কোডটি যোগ করার পরে, একটি ত্রুটি সাময়িকভাবে প্রদর্শিত হতে পারে: Corresponding method handler 'public void onClickRecord(android.view.View)' not found" । এটি প্রত্যাশিত। আপনি onClickRecord() ফাংশন তৈরি করে ত্রুটিটি সমাধান করবেন পরবর্তী কয়েক ধাপ।

রাজ্যের উপর ভিত্তি করে বোতামে পাঠ্য পরিবর্তন করুন

রেকর্ড বোতামটি আসলে রেকর্ডিং এবং থামানো উভয়ই পরিচালনা করে। যখন অ্যাপটি ডেটা রেকর্ড করছে না, তখন এটি "রেকর্ড" শব্দটি প্রদর্শন করবে। যখন অ্যাপটি ডেটা রেকর্ড করছে, তখন "স্টপ" শব্দটি প্রদর্শন করতে বোতামটি পরিবর্তন করা উচিত।

বোতামটিকে এই কার্যকারিতা দেওয়ার জন্য, অ্যাপটিকে তার বর্তমান অবস্থা জানতে হবে। নিম্নলিখিত কোডটি অ্যাপটির কার্যকারী অবস্থার প্রতিনিধিত্ব করার জন্য AppState নামে একটি নতুন enum তৈরি করে এবং appState নামক একটি ব্যক্তিগত সদস্য ভেরিয়েবলের মাধ্যমে নির্দিষ্ট রাজ্যের পরিবর্তনগুলি ট্র্যাক করে। HelloArActivity ক্লাসের শুরুতে HelloArActivity.java এ এটি যোগ করুন।

  // Represents the app's working state.
  public enum AppState {
    Idle,
    Recording
  }

  // Tracks app's specific state changes.
  private AppState appState = AppState.Idle;

এখন যেহেতু আপনি অ্যাপের অভ্যন্তরীণ অবস্থা ট্র্যাক করতে পারেন, updateRecordButton() নামে একটি ফাংশন তৈরি করুন যা অ্যাপের বর্তমান অবস্থার উপর ভিত্তি করে বোতামের পাঠ্য পরিবর্তন করে। HelloArActivity.java তে HelloArActivity ক্লাসের ভিতরে নিম্নলিখিত কোডটি যোগ করুন।

// Add imports to the beginning of the file.
import android.widget.Button;

  // Update the "Record" button based on app's internal state.
  private void updateRecordButton() {
    View buttonView = findViewById(R.id.record_button);
    Button button = (Button) buttonView;

    switch (appState) {
      case Idle:
        button.setText("Record");
        break;
      case Recording:
        button.setText("Stop");
        break;
    }
  }

এরপর, onClickRecord() পদ্ধতিটি তৈরি করুন যা অ্যাপের অবস্থা পরীক্ষা করে, এটিকে পরবর্তীতে পরিবর্তন করে এবং বোতামের UI পরিবর্তন করতে updateRecordButton() কল করে। HelloArActivity.java তে HelloArActivity ক্লাসের ভিতরে নিম্নলিখিত কোডটি যোগ করুন।

  // Handle the "Record" button click event.
  public void onClickRecord(View view) {
    Log.d(TAG, "onClickRecord");

    // Check the app's internal state and switch to the new state if needed.
    switch (appState) {
        // If the app is not recording, begin recording.
      case Idle: {
        boolean hasStarted = startRecording();
        Log.d(TAG, String.format("onClickRecord start: hasStarted %b", hasStarted));

        if (hasStarted)
          appState = AppState.Recording;

        break;
      }

      // If the app is recording, stop recording.
      case Recording: {
        boolean hasStopped = stopRecording();
        Log.d(TAG, String.format("onClickRecord stop: hasStopped %b", hasStopped));

        if (hasStopped)
          appState = AppState.Idle;

        break;
      }

      default:
        // Do nothing.
        break;
    }

    updateRecordButton();
  }

রেকর্ডিং শুরু করতে অ্যাপটি সক্ষম করুন

ARCore-এ রেকর্ডিং শুরু করার জন্য আপনাকে শুধুমাত্র দুটি জিনিস করতে হবে:

  1. একটি RecordingConfig অবজেক্টে রেকর্ডিং ফাইল URI নির্দিষ্ট করুন।
  2. RecordingConfig অবজেক্টের সাথে session.startRecording কল করুন

বাকিটা শুধু বয়লারপ্লেট কোড: কনফিগারেশন, লগিং এবং সঠিকতা পরীক্ষা করা।

startRecording() নামে একটি নতুন ফাংশন তৈরি করুন যা ডেটা রেকর্ড করে এবং এটি একটি MP4 URI-তে সংরক্ষণ করে। HelloArActivity.java তে HelloArActivity ক্লাসের ভিতরে নিম্নলিখিত কোডটি যোগ করুন।

// Add imports to the beginning of the file.
import android.net.Uri;
import com.google.ar.core.RecordingConfig;
import com.google.ar.core.RecordingStatus;
import com.google.ar.core.exceptions.RecordingFailedException;

  private boolean startRecording() {
    Uri mp4FileUri = createMp4File();
    if (mp4FileUri == null)
      return false;

    Log.d(TAG, "startRecording at: " + mp4FileUri);

    pauseARCoreSession();

    // Configure the ARCore session to start recording.
    RecordingConfig recordingConfig = new RecordingConfig(session)
        .setMp4DatasetUri(mp4FileUri)
        .setAutoStopOnPause(true);

    try {
      // Prepare the session for recording, but do not start recording yet.
      session.startRecording(recordingConfig);
    } catch (RecordingFailedException e) {
      Log.e(TAG, "startRecording - Failed to prepare to start recording", e);
      return false;
    }

    boolean canResume = resumeARCoreSession();
    if (!canResume)
      return false;

    // Correctness checking: check the ARCore session's RecordingState.
    RecordingStatus recordingStatus = session.getRecordingStatus();
    Log.d(TAG, String.format("startRecording - recordingStatus %s", recordingStatus));
    return recordingStatus == RecordingStatus.OK;
  }

একটি ARCore সেশন নিরাপদে পজ করতে এবং পুনরায় শুরু করতে, HelloArActivity.javapauseARCoreSession() এবং resumeARCoreSession() তৈরি করুন।

  private void pauseARCoreSession() {
    // Pause the GLSurfaceView so that it doesn't update the ARCore session.
    // Pause the ARCore session so that we can update its configuration.
    // If the GLSurfaceView is not paused,
    //   onDrawFrame() will try to update the ARCore session
    //   while it's paused, resulting in a crash.
    surfaceView.onPause();
    session.pause();
  }

  private boolean resumeARCoreSession() {
    // We must resume the ARCore session before the GLSurfaceView.
    // Otherwise, the GLSurfaceView will try to update the ARCore session.
    try {
      session.resume();
    } catch (CameraNotAvailableException e) {
      Log.e(TAG, "CameraNotAvailableException in resumeARCoreSession", e);
      return false;
    }

    surfaceView.onResume();
    return true;
  }

রেকর্ডিং বন্ধ করতে অ্যাপটি সক্ষম করুন

আপনার অ্যাপকে নতুন ডেটা রেকর্ড করা বন্ধ করতে HelloArActivity.java তে stopRecording() নামে একটি ফাংশন তৈরি করুন। এই ফাংশনটি session.stopRecording() কল করে এবং অ্যাপটি রেকর্ডিং বন্ধ করতে না পারলে কনসোল লগে একটি ত্রুটি পাঠায়।

  private boolean stopRecording() {
    try {
      session.stopRecording();
    } catch (RecordingFailedException e) {
      Log.e(TAG, "stopRecording - Failed to stop recording", e);
      return false;
    }

    // Correctness checking: check if the session stopped recording.
    return session.getRecordingStatus() == RecordingStatus.NONE;
  }

Android 11 স্কোপড স্টোরেজ ব্যবহার করে ফাইল স্টোরেজ ডিজাইন করুন

এই কোডল্যাবে স্টোরেজ সম্পর্কিত ফাংশনগুলি নতুন অ্যান্ড্রয়েড 11 স্কোপড স্টোরেজ প্রয়োজনীয়তা অনুসরণ করে ডিজাইন করা হয়েছে।

Android 11 টার্গেট করতে app/build.gradle ফাইলে কিছু ছোট পরিবর্তন করুন। Android Studio Project প্যানেলে, এই ফাইলটি Gradle Scripts নোডের অধীনে, অ্যাপ মডিউলের সাথে যুক্ত।

app-build.gradle.png

compileSdkVersion এবং targetSdkVersion 30 এ পরিবর্তন করুন।

    compileSdkVersion 30
    defaultConfig {
      targetSdkVersion 30
    }

রেকর্ডিংয়ের জন্য, শেয়ার করা মুভি ডিরেক্টরিতে MP4 ফাইল তৈরি করতে Android MediaStore API ব্যবহার করুন।

HelloArActivity.javacreateMp4File() নামে একটি ফাংশন তৈরি করুন:

// Add imports to the beginning of the file.
import java.text.SimpleDateFormat;
import android.content.ContentResolver;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.content.ContentValues;
import java.io.File;
import android.content.CursorLoader;
import android.database.Cursor;
import java.util.Date;


  private final String MP4_VIDEO_MIME_TYPE = "video/mp4";

  private Uri createMp4File() {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss");
    String mp4FileName = "arcore-" + dateFormat.format(new Date()) + ".mp4";

    ContentResolver resolver = this.getContentResolver();

    Uri videoCollection = null;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
      videoCollection = MediaStore.Video.Media.getContentUri(
          MediaStore.VOLUME_EXTERNAL_PRIMARY);
    } else {
      videoCollection = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
    }

    // Create a new Media file record.
    ContentValues newMp4FileDetails = new ContentValues();
    newMp4FileDetails.put(MediaStore.Video.Media.DISPLAY_NAME, mp4FileName);
    newMp4FileDetails.put(MediaStore.Video.Media.MIME_TYPE, MP4_VIDEO_MIME_TYPE);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
      // The Relative_Path column is only available since API Level 29.
      newMp4FileDetails.put(MediaStore.Video.Media.RELATIVE_PATH, Environment.DIRECTORY_MOVIES);
    } else {
      // Use the Data column to set path for API Level <= 28.
      File mp4FileDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
      String absoluteMp4FilePath = new File(mp4FileDir, mp4FileName).getAbsolutePath();
      newMp4FileDetails.put(MediaStore.Video.Media.DATA, absoluteMp4FilePath);
    }

    Uri newMp4FileUri = resolver.insert(videoCollection, newMp4FileDetails);

    // Ensure that this file exists and can be written.
    if (newMp4FileUri == null) {
      Log.e(TAG, String.format("Failed to insert Video entity in MediaStore. API Level = %d", Build.VERSION.SDK_INT));
      return null;
    }

    // This call ensures the file exist before we pass it to the ARCore API.
    if (!testFileWriteAccess(newMp4FileUri)) {
      return null;
    }

    Log.d(TAG, String.format("createMp4File = %s, API Level = %d", newMp4FileUri, Build.VERSION.SDK_INT));

    return newMp4FileUri;
  }

  // Test if the file represented by the content Uri can be open with write access.
  private boolean testFileWriteAccess(Uri contentUri) {
    try (java.io.OutputStream mp4File = this.getContentResolver().openOutputStream(contentUri)) {
      Log.d(TAG, String.format("Success in testFileWriteAccess %s", contentUri.toString()));
      return true;
    } catch (java.io.FileNotFoundException e) {
      Log.e(TAG, String.format("FileNotFoundException in testFileWriteAccess %s", contentUri.toString()), e);
    } catch (java.io.IOException e) {
      Log.e(TAG, String.format("IOException in testFileWriteAccess %s", contentUri.toString()), e);
    }

    return false;
  }

স্টোরেজ অনুমতিগুলি পরিচালনা করুন

আপনি যদি একটি Android 11 ডিভাইস ব্যবহার করেন তবে আপনি কোডটি পরীক্ষা করা শুরু করতে পারেন। অ্যান্ড্রয়েড 10 বা তার নিচের ডিভাইসগুলিকে সমর্থন করতে, আপনাকে লক্ষ্য ডিভাইসের ফাইল সিস্টেমে ডেটা সংরক্ষণ করার জন্য অ্যাপ স্টোরেজ অনুমতি দিতে হবে।

AndroidManifest.xml এ, ঘোষণা করুন যে অ্যাপটির Android 11 (API স্তর 30) এর আগে স্টোরেজ পড়ার এবং লেখার অনুমতি প্রয়োজন।

  <!-- Inside the <manifest> tag, below the existing Camera permission -->
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
      android:maxSdkVersion="29" />

  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
      android:maxSdkVersion="29" />

রানটাইম চলাকালীন WRITE_EXTERNAL_STORAGE অনুমতির অনুরোধ করতে HelloArActivity.java তে checkAndRequestStoragePermission() নামে একটি সহায়ক ফাংশন যোগ করুন।

// Add imports to the beginning of the file.
import android.Manifest;
import android.content.pm.PackageManager;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

  private final int REQUEST_WRITE_EXTERNAL_STORAGE = 1;
  public boolean checkAndRequestStoragePermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
        != PackageManager.PERMISSION_GRANTED) {
      ActivityCompat.requestPermissions(this,
          new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
          REQUEST_WRITE_EXTERNAL_STORAGE);
      return false;
    }

    return true;
  }

আপনি যদি API লেভেল 29 বা তার আগে থাকেন, createMp4File() এর শীর্ষে স্টোরেজ অনুমতির জন্য একটি চেক যোগ করুন এবং অ্যাপটির সঠিক অনুমতি না থাকলে তাড়াতাড়ি ফাংশন থেকে প্রস্থান করুন। API স্তর 30 (Android 11) মিডিয়াস্টোরে ফাইলগুলি অ্যাক্সেস করার জন্য স্টোরেজ অনুমতির প্রয়োজন হয় না।

  private Uri createMp4File() {
    // Since we use legacy external storage for Android 10,
    // we still need to request for storage permission on Android 10.
    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
      if (!checkAndRequestStoragePermission()) {
        Log.i(TAG, String.format(
            "Didn't createMp4File. No storage permission, API Level = %d",
            Build.VERSION.SDK_INT));
        return null;
      }
    }
    // ... omitted code ...
  }

লক্ষ্য ডিভাইস থেকে রেকর্ড

এখন পর্যন্ত আপনি কী তৈরি করেছেন তা দেখার সময় এসেছে। আপনার মোবাইল ডিভাইসটিকে আপনার ডেভেলপমেন্ট মেশিনের সাথে সংযুক্ত করুন এবং অ্যান্ড্রয়েড স্টুডিওতে চালান ক্লিক করুন৷

আপনি স্ক্রিনের নীচে বাম দিকে একটি লাল রেকর্ড বোতাম দেখতে পাবেন। এটিতে আলতো চাপলে পাঠ্যটিকে থামাতে পরিবর্তন করা উচিত। একটি সেশন রেকর্ড করতে আপনার ডিভাইসটি চারপাশে সরান, এবং আপনি যখন রেকর্ডিং সম্পূর্ণ করতে চান তখন স্টপ বোতামটি ক্লিক করুন৷ এটি আপনার ডিভাইসের বাহ্যিক স্টোরেজে arcore-xxxxxx_xxxxxx.mp4 নামে একটি নতুন ফাইল সংরক্ষণ করবে।

record-button.png

এখন, আপনার ডিভাইসের বাহ্যিক সঞ্চয়স্থানে আপনার একটি নতুন arcore-xxxxxx_xxxxxx.mp4 ফাইল থাকা উচিত। Pixel 5 ডিভাইসে, পাথ হল /storage/emulated/0/Movies/ । একটি রেকর্ডিং শুরু করার পরে Logcat উইন্ডোতে পাথ পাওয়া যাবে।

com.google.ar.core.examples.java.helloar D/HelloArActivity: startRecording at:/storage/emulated/0/Movies/arcore-xxxxxxxx_xxxxxx.mp4
com.google.ar.core.examples.java.helloar D/HelloArActivity: startRecording - RecordingStatus OK

রেকর্ডিং দেখুন

আপনি রেকর্ডিং দেখতে বা আপনার ডেভেলপমেন্ট মেশিনে এটি অনুলিপি করতে Google দ্বারা ফাইলের মতো একটি ফাইল সিস্টেম অ্যাপ ব্যবহার করতে পারেন। অ্যান্ড্রয়েড ডিভাইস থেকে ফাইলগুলিকে তালিকাভুক্ত এবং আনার জন্য নীচে দুটি অ্যাডবি কমান্ড রয়েছে:

  • ডিভাইসের এক্সটার্নাল স্টোরেজে মুভি ডিরেক্টরীতে ফাইলগুলি দেখানোর জন্য adb shell ls '$EXTERNAL_STORAGE/Movies/*'
  • ডিভাইস থেকে ডেভেলপমেন্ট মেশিনে ফাইল কপি করতে adb pull /absolute_path_from_previous_adb_shell_ls/arcore-xxxxxxxx_xxxxxx.mp4

এই দুটি কমান্ড ব্যবহার করার পরে এটি একটি উদাহরণ আউটপুট (macOS থেকে):

$ adb shell ls '$EXTERNAL_STORAGE/Movies/*'
/sdcard/Movies/arcore-xxxxxxxx_xxxxxx.mp4


$ adb pull /sdcard/Movies/arcore-xxxxxxxx_xxxxxx.mp4
/sdcard/Movies/arcore-xxxxxxxx_xxxxxx.mp4: ... pulled

আপনি এই ধাপে কি করেছেন

  • রেকর্ডিং শুরু এবং বন্ধ করতে একটি বোতাম যোগ করা হয়েছে
  • রেকর্ডিং শুরু এবং বন্ধ করার জন্য কার্যকরী ফাংশন
  • ডিভাইসে অ্যাপটি পরীক্ষা করা হয়েছে
  • আপনার মেশিনে রেকর্ড করা MP4 অনুলিপি এবং এটি যাচাই

এরপরে, আপনি একটি MP4 ফাইল থেকে একটি AR সেশন প্লে ব্যাক করবেন।

4. একটি MP4 ফাইল থেকে একটি ARCore সেশন প্লেব্যাক করুন

আপনার কাছে এখন একটি রেকর্ড বোতাম এবং কিছু MP4 ফাইল রয়েছে যাতে রেকর্ড করা সেশন রয়েছে৷ এখন, আপনি এআরকোর প্লেব্যাক এপিআই ব্যবহার করে সেগুলি আবার প্লে করবেন।

প্লেব্যাক বোতামের জন্য UI যোগ করুন

আপনি প্লেব্যাক প্রয়োগ করার আগে, UI-তে একটি বোতাম যোগ করুন যাতে ব্যবহারকারী ARCore কে জানাতে পারে যে এটি কখন শুরু হবে এবং সেশনটি আবার চালানো বন্ধ করবে।

প্রজেক্ট প্যানেলে, app/res/layout/activity_main.xml ফাইলটি খুলুন।

কার্যকলাপ_প্রধান-এক্সএমএল-লোকেশন-ইন-প্রজেক্ট

activity_main.xml এ, নতুন প্লেব্যাক বোতাম তৈরি করতে ক্লোজিং ট্যাগের আগে নীচের কোড যোগ করুন এবং এর ইভেন্ট হ্যান্ডলারটিকে onClickPlayback() নামক একটি পদ্ধতিতে সেট করুন। এই বোতামটি রেকর্ড বোতামের মতো হবে এবং স্ক্রিনের ডানদিকে প্রদর্শিত হবে।

  <!--
    Add a new "Playback" button with those attributes:
        text is "Playback",
        onClick event handler is "onClickPlayback",
        text color is "green".
  -->
  <Button
      android:id="@+id/playback_button"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignEnd="@id/surfaceview"
      android:layout_alignBottom="@id/surfaceview"
      android:layout_marginBottom="100dp"
      android:onClick="onClickPlayback"
      android:text="Playback"
      android:textColor="@android:color/holo_green_light" />

প্লেব্যাকের সময় আপডেট বোতাম

অ্যাপটিতে এখন Playingback নামে একটি নতুন অবস্থা রয়েছে। AppState enum এবং সমস্ত বিদ্যমান ফাংশন আপডেট করুন যা appState এটি পরিচালনা করার জন্য একটি যুক্তি হিসাবে গ্রহণ করে।

HelloArActivity.java তে AppState enum-এ Playingback যোগ করুন:

  public enum AppState {
    Idle,
    Recording,
    Playingback // New enum value.
  }

যদি রেকর্ড বোতামটি প্লেব্যাকের সময় এখনও স্ক্রিনে থাকে তবে ব্যবহারকারী দুর্ঘটনাক্রমে এটিতে ক্লিক করতে পারেন। এটি এড়াতে, প্লেব্যাকের সময় রেকর্ড বোতামটি লুকান। এইভাবে আপনাকে onClickRecord()Playingback অবস্থার জন্য পরিচালনা করতে হবে না।

অ্যাপটি Playingback অবস্থায় থাকলে রেকর্ড বোতামটি লুকানোর জন্য HelloArActivity.java তে updateRecordButton() ফাংশনটি পরিবর্তন করুন।

  // Update the "Record" button based on app's internal state.
  private void updateRecordButton() {
    View buttonView = findViewById(R.id.record_button);
    Button button = (Button)buttonView;

    switch (appState) {

      // The app is neither recording nor playing back. The "Record" button is visible.
      case Idle:
        button.setText("Record");
        button.setVisibility(View.VISIBLE);
        break;

      // While recording, the "Record" button is visible and says "Stop".
      case Recording:
        button.setText("Stop");
        button.setVisibility(View.VISIBLE);
        break;

      // During playback, the "Record" button is not visible.
      case Playingback:
        button.setVisibility(View.INVISIBLE);
        break;
    }
  }

একইভাবে, ব্যবহারকারী যখন একটি সেশন রেকর্ড করছেন তখন প্লেব্যাক বোতামটি লুকান এবং ব্যবহারকারী যখন সক্রিয়ভাবে একটি সেশন প্লেব্যাক করছেন তখন "বন্ধ করুন" বলে এটি পরিবর্তন করুন। এইভাবে, তারা একটি প্লেব্যাক নিজে থেকে সম্পূর্ণ হওয়ার জন্য অপেক্ষা না করেই বন্ধ করতে পারে।

HelloArActivity.java এ একটি updatePlaybackButton() ফাংশন যোগ করুন:

  // Update the "Playback" button based on app's internal state.
  private void updatePlaybackButton() {
    View buttonView = findViewById(R.id.playback_button);
    Button button = (Button)buttonView;

    switch (appState) {

      // The app is neither recording nor playing back. The "Playback" button is visible.
      case Idle:
        button.setText("Playback");
        button.setVisibility(View.VISIBLE);
        break;

      // While playing back, the "Playback" button is visible and says "Stop".
      case Playingback:
        button.setText("Stop");
        button.setVisibility(View.VISIBLE);
        break;

      // During recording, the "Playback" button is not visible.
      case Recording:
        button.setVisibility(View.INVISIBLE);
        break;
    }
  }

অবশেষে, updatePlaybackButton() কল করতে onClickRecord() আপডেট করুন। HelloArActivity.java এ নিম্নলিখিত লাইন যোগ করুন:

  public void onClickRecord(View view) {
    // ... omitted code ...
    updatePlaybackButton(); // Add this line to the end of the function.
  }

প্লেব্যাক বোতাম সহ একটি ফাইল নির্বাচন করুন

ট্যাপ করা হলে, প্লেব্যাক বোতামটি ব্যবহারকারীকে প্লেব্যাক করার জন্য একটি ফাইল নির্বাচন করার অনুমতি দেবে। অ্যান্ড্রয়েডে, ফাইল নির্বাচন অন্য অ্যাক্টিভিটিতে সিস্টেম ফাইল পিকারে পরিচালনা করা হয়। এটি স্টোরেজ অ্যাক্সেস ফ্রেমওয়ার্ক ( এসএএফ ) এর মাধ্যমে। একবার ব্যবহারকারী একটি ফাইল নির্বাচন করলে, অ্যাপটি onActivityResult() নামে একটি কলব্যাক পায়। আপনি এই কলব্যাক ফাংশনের ভিতরে প্রকৃত প্লেব্যাক শুরু করবেন।

HelloArActivity.java এ, ফাইল নির্বাচন করতে একটি onClickPlayback() ফাংশন তৈরি করুন এবং ব্যাক প্লে করা বন্ধ করুন।

  // Handle the click event of the "Playback" button.
  public void onClickPlayback(View view) {
    Log.d(TAG, "onClickPlayback");

    switch (appState) {

      // If the app is not playing back, open the file picker.
      case Idle: {
        boolean hasStarted = selectFileToPlayback();
        Log.d(TAG, String.format("onClickPlayback start: selectFileToPlayback %b", hasStarted));
        break;
      }

      // If the app is playing back, stop playing back.
      case Playingback: {
        boolean hasStopped = stopPlayingback();
        Log.d(TAG, String.format("onClickPlayback stop: hasStopped %b", hasStopped));
        break;
      }

      default:
        // Recording - do nothing.
        break;
    }

    // Update the UI for the "Record" and "Playback" buttons.
    updateRecordButton();
    updatePlaybackButton();
  }

HelloArActivity.java এ, একটি selectFileToPlayback() ফাংশন তৈরি করুন যা ডিভাইস থেকে একটি ফাইল নির্বাচন করে। Android ফাইল সিস্টেম থেকে একটি ফাইল নির্বাচন করতে, একটি ACTION_OPEN_DOCUMENT ইন্টেন্ট ব্যবহার করুন।

// Add imports to the beginning of the file.
import android.content.Intent;
import android.provider.DocumentsContract;

  private boolean selectFileToPlayback() {
    // Start file selection from Movies directory.
    // Android 10 and above requires VOLUME_EXTERNAL_PRIMARY to write to MediaStore.
    Uri videoCollection;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
      videoCollection = MediaStore.Video.Media.getContentUri(
          MediaStore.VOLUME_EXTERNAL_PRIMARY);
    } else {
      videoCollection = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
    }

    // Create an Intent to select a file.
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);

    // Add file filters such as the MIME type, the default directory and the file category.
    intent.setType(MP4_VIDEO_MIME_TYPE); // Only select *.mp4 files
    intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, videoCollection); // Set default directory
    intent.addCategory(Intent.CATEGORY_OPENABLE); // Must be files that can be opened

    this.startActivityForResult(intent, REQUEST_MP4_SELECTOR);

    return true;
  }

REQUEST_MP4_SELECTOR এই অনুরোধটি সনাক্ত করার জন্য একটি ধ্রুবক। আপনি HelloArActivity.java তে HelloArActivity ভিতরে যেকোনো স্থানধারক মান ব্যবহার করে এটি সংজ্ঞায়িত করতে পারেন:

  private int REQUEST_MP4_SELECTOR = 1;

ফাইল পিকার থেকে কলব্যাক পরিচালনা করতে HelloArActivity.java তে onActivityResult() ফাংশনটি ওভাররাইড করুন।

  // Begin playback once the user has selected the file.
  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Check request status. Log an error if the selection fails.
    if (resultCode != android.app.Activity.RESULT_OK || requestCode != REQUEST_MP4_SELECTOR) {
      Log.e(TAG, "onActivityResult select file failed");
      return;
    }

    Uri mp4FileUri = data.getData();
    Log.d(TAG, String.format("onActivityResult result is %s", mp4FileUri));

    // Begin playback.
    startPlayingback(mp4FileUri);
  }

প্লেব্যাক শুরু করতে অ্যাপটি সক্ষম করুন

একটি ARCore সেশনে একটি MP4 ফাইল প্লেব্যাক করতে তিনটি API কল প্রয়োজন:

  1. session.pause()
  2. session.setPlaybackDataset()
  3. session.resume()

HelloArActivity.java এ, startPlayingback() ফাংশন তৈরি করুন।

// Add imports to the beginning of the file.
import com.google.ar.core.PlaybackStatus;
import com.google.ar.core.exceptions.PlaybackFailedException;

  private boolean startPlayingback(Uri mp4FileUri) {
    if (mp4FileUri == null)
      return false;

    Log.d(TAG, "startPlayingback at:" + mp4FileUri);

    pauseARCoreSession();

    try {
      session.setPlaybackDatasetUri(mp4FileUri);
    } catch (PlaybackFailedException e) {
      Log.e(TAG, "startPlayingback - setPlaybackDataset failed", e);
    }

    // The session's camera texture name becomes invalid when the
    // ARCore session is set to play back.
    // Workaround: Reset the Texture to start Playback
    // so it doesn't crashes with AR_ERROR_TEXTURE_NOT_SET.
    hasSetTextureNames = false;

    boolean canResume = resumeARCoreSession();
    if (!canResume)
      return false;

    PlaybackStatus playbackStatus = session.getPlaybackStatus();
    Log.d(TAG, String.format("startPlayingback - playbackStatus %s", playbackStatus));


    if (playbackStatus != PlaybackStatus.OK) { // Correctness check
      return false;
    }

    appState = AppState.Playingback;
    updateRecordButton();
    updatePlaybackButton();

    return true;
  }

প্লেব্যাক বন্ধ করতে অ্যাপটি সক্ষম করুন

HelloArActivity.java তে stopPlayingback() নামে একটি ফাংশন তৈরি করুন যাতে অ্যাপের অবস্থার পরিবর্তনগুলি পরিচালনা করতে হয়:

  1. MP4 প্লেব্যাক ব্যবহারকারী দ্বারা বন্ধ করা হয়েছে
  2. MP4 প্লেব্যাক নিজে থেকেই সম্পন্ন হয়েছে

ব্যবহারকারী প্লেব্যাক বন্ধ করলে, অ্যাপটি সেই অবস্থায় ফিরে আসা উচিত যে অবস্থায় ছিল ব্যবহারকারী যখন এটি প্রথম চালু করেছিল।

  // Stop the current playback, and restore app status to Idle.
  private boolean stopPlayingback() {
    // Correctness check, only stop playing back when the app is playing back.
    if (appState != AppState.Playingback)
      return false;

    pauseARCoreSession();

    // Close the current session and create a new session.
    session.close();
    try {
      session = new Session(this);
    } catch (UnavailableArcoreNotInstalledException
        |UnavailableApkTooOldException
        |UnavailableSdkTooOldException
        |UnavailableDeviceNotCompatibleException e) {
      Log.e(TAG, "Error in return to Idle state. Cannot create new ARCore session", e);
      return false;
    }
    configureSession();

    boolean canResume = resumeARCoreSession();
    if (!canResume)
      return false;

    // A new session will not have a camera texture name.
    // Manually set hasSetTextureNames to false to trigger a reset.
    hasSetTextureNames = false;

    // Reset appState to Idle, and update the "Record" and "Playback" buttons.
    appState = AppState.Idle;
    updateRecordButton();
    updatePlaybackButton();

    return true;
  }

প্লেয়ারটি MP4 ফাইলের শেষে পৌঁছে যাওয়ার পরে একটি প্লেব্যাক স্বাভাবিকভাবেই বন্ধ হতে পারে। যখন এটি ঘটবে, stopPlayingback() অ্যাপের অবস্থাকে Idle এ ফিরিয়ে আনতে হবে। onDrawFrame() এ, PlaybackStatus চেক করুন। এটি FINISHED হলে, UI থ্রেডে stopPlayingback() ফাংশনটি কল করুন।

  public void onDrawFrame(SampleRender render) {
      // ... omitted code ...

      // Insert before this line:
      // frame = session.update();

      // Check the playback status and return early if playback reaches the end.
      if (appState == AppState.Playingback
          && session.getPlaybackStatus() == PlaybackStatus.FINISHED) {
        this.runOnUiThread(this::stopPlayingback);
        return;
      }

      // ... omitted code ...
  }

লক্ষ্য ডিভাইস থেকে ফিরে খেলা

এখন পর্যন্ত আপনি কী তৈরি করেছেন তা দেখার সময় এসেছে। আপনার মোবাইল ডিভাইসটিকে আপনার ডেভেলপমেন্ট মেশিনের সাথে সংযুক্ত করুন এবং অ্যান্ড্রয়েড স্টুডিওতে চালান ক্লিক করুন৷

অ্যাপটি চালু হলে, আপনি বাম দিকে একটি লাল রেকর্ড বোতাম এবং ডানদিকে একটি সবুজ প্লেব্যাক বোতাম সহ একটি স্ক্রীন দেখতে পাবেন৷

playback-button.png

প্লেব্যাক বোতামটি আলতো চাপুন এবং আপনি এইমাত্র রেকর্ড করা MP4 ফাইলগুলির মধ্যে একটি নির্বাচন করুন৷ আপনি যদি arcore- দিয়ে শুরু হওয়া কোনো ফাইলের নাম দেখতে না পান, তাহলে হয়তো আপনার ডিভাইস মুভি ফোল্ডার দেখাচ্ছে না। এই ক্ষেত্রে, উপরের বাম কোণে মেনু ব্যবহার করে ফোন মডেল > চলচ্চিত্র ফোল্ডারে নেভিগেট করুন। ফোন মডেল ফোল্ডারটি প্রকাশ করতে আপনাকে অভ্যন্তরীণ স্টোরেজ প্রদর্শন বিকল্পটি সক্ষম করতে হতে পারে।

শো-ইন্টারনাল-স্টোরেজ-বাটন.png

নেটিভেট-টু-মুভি-ফাইল-পিকার.jpg

MP4 ফাইল নির্বাচন করতে পর্দায় একটি ফাইলের নাম আলতো চাপুন। অ্যাপটির MP4 ফাইলটি প্লে ব্যাক করা উচিত।

playback-stop-button.png

একটি সেশন বাজানো এবং একটি সাধারণ ভিডিও প্লে ব্যাক করার মধ্যে একটি পার্থক্য হল আপনি রেকর্ড করা সেশনের সাথে ইন্টারঅ্যাক্ট করতে পারেন। স্ক্রিনে মার্কার স্থাপন করতে একটি শনাক্ত প্লেনে আলতো চাপুন।

প্লেব্যাক প্লেসমেন্ট

আপনি এই ধাপে কি করেছেন

  • প্লেব্যাক শুরু এবং বন্ধ করতে একটি বোতাম যোগ করা হয়েছে
  • অ্যাপটি শুরু করতে এবং রেকর্ডিং বন্ধ করতে একটি ফাংশন প্রয়োগ করেছে৷
  • ডিভাইসে পূর্বে রেকর্ড করা ARCore সেশন প্লে ব্যাক করা হয়েছে

5. MP4 এ অতিরিক্ত ডেটা রেকর্ড করুন

ARCore 1.24 দিয়ে, MP4 ফাইলে অতিরিক্ত তথ্য রেকর্ড করা সম্ভব। আপনি AR অবজেক্ট প্লেসমেন্টের Pose রেকর্ড করতে পারেন, তারপর প্লেব্যাকের সময়, একই অবস্থানে AR অবজেক্ট তৈরি করুন।

রেকর্ড করতে নতুন ট্র্যাক কনফিগার করুন

HelloArActivity.java এ একটি UUID এবং একটি MIME ট্যাগ সহ একটি নতুন ট্র্যাক সংজ্ঞায়িত করুন।

// Add imports to the beginning of the file.
import java.util.UUID;
import com.google.ar.core.Track;

  // Inside the HelloArActiity class.
  private static final UUID ANCHOR_TRACK_ID = UUID.fromString("53069eb5-21ef-4946-b71c-6ac4979216a6");;
  private static final String ANCHOR_TRACK_MIME_TYPE = "application/recording-playback-anchor";

  private boolean startRecording() {
    // ... omitted code ...

    // Insert after line:
    //   pauseARCoreSession();

    // Create a new Track, with an ID and MIME tag.
    Track anchorTrack = new Track(session)
        .setId(ANCHOR_TRACK_ID).
        .setMimeType(ANCHOR_TRACK_MIME_TYPE);
    // ... omitted code ...
  }

addTrack() এ কল দিয়ে RecordingConfig অবজেক্ট তৈরি করতে প্রস্থান কোড আপডেট করুন।

  private boolean startRecording() {
    // ... omitted code ...

    // Update the lines below with a call to the addTrack() function:
    //   RecordingConfig recordingConfig = new RecordingConfig(session)
    //    .setMp4DatasetUri(mp4FileUri)
    //    .setAutoStopOnPause(true);

    RecordingConfig recordingConfig = new RecordingConfig(session)
        .setMp4DatasetUri(mp4FileUri)
        .setAutoStopOnPause(true)
        .addTrack(anchorTrack); // add the new track onto the recordingConfig

    // ... omitted code ...
  }

রেকর্ডিংয়ের সময় অ্যাঙ্কর পোজ সংরক্ষণ করুন

যখনই ব্যবহারকারী একটি শনাক্ত প্লেনে ট্যাপ করবে, একটি AR মার্কার একটি Anchor স্থাপন করা হবে, যার পোজ ARCore দ্বারা আপডেট করা হবে।

আপনি যদি এখনও ARCore সেশন রেকর্ড করেন তবে এটি তৈরি করা ফ্রেমে একটি Anchor ভঙ্গি রেকর্ড করুন।

HelloArActivity.javahandleTap() ফাংশন পরিবর্তন করুন।

// Add imports to the beginning of the file.
import com.google.ar.core.Pose;
import java.nio.FloatBuffer;

  private void handleTap(Frame frame, Camera camera) {
          // ... omitted code ...

          // Insert after line:
          // anchors.add(hit.createAnchor());

          // If the app is recording a session,
          // save the new Anchor pose (relative to the camera)
          // into the ANCHOR_TRACK_ID track.
          if (appState == AppState.Recording) {
            // Get the pose relative to the camera pose.
            Pose cameraRelativePose = camera.getPose().inverse().compose(hit.getHitPose());
            float[] translation = cameraRelativePose.getTranslation();
            float[] quaternion = cameraRelativePose.getRotationQuaternion();
            ByteBuffer payload = ByteBuffer.allocate(4 * (translation.length + quaternion.length));
            FloatBuffer floatBuffer = payload.asFloatBuffer();
            floatBuffer.put(translation);
            floatBuffer.put(quaternion);

            try {
              frame.recordTrackData(ANCHOR_TRACK_ID, payload);
            } catch (IllegalStateException e) {
              Log.e(TAG, "Error in recording anchor into external data track.", e);
            }
          }
          // ... omitted code ...
  }

বিশ্ব আপেক্ষিক Pose না করে আমরা কেন ক্যামেরা আপেক্ষিক Pose ধরে রাখি তার কারণ হল একটি রেকর্ডিং সেশনের বিশ্ব উত্স এবং প্লেব্যাক সেশনের বিশ্ব উত্স এক নয়৷ রেকর্ডিং সেশনের ওয়ার্ল্ড অরিজিন প্রথমবার সেশন পুনরায় শুরু হলে শুরু হয়, যখন Session.resume() প্রথম কল করা হয়। একটি প্লেব্যাক সেশনের বিশ্ব উত্স শুরু হয় যখন প্রথম ফ্রেমটি রেকর্ড করা হয়, যখন Session.resume() প্রথমে Session.startRecording() এর পরে কল করা হয়।

প্লেব্যাক অ্যাঙ্কর সৃষ্টি

একটি Anchor পুনরায় তৈরি করা সোজা। HelloArActivity.javacreateRecordedAnchors() নামে একটি ফাংশন যোগ করুন।

// Add imports to the beginning of the file.
import com.google.ar.core.TrackData;

  // Extract poses from the ANCHOR_TRACK_ID track, and create new anchors.
  private void createRecordedAnchors(Frame frame, Camera camera) {
    // Get all `ANCHOR_TRACK_ID` TrackData from the frame.
    for (TrackData trackData : frame.getUpdatedTrackData(ANCHOR_TRACK_ID)) {
      ByteBuffer payload = trackData.getData();
      FloatBuffer floatBuffer = payload.asFloatBuffer();

      // Extract translation and quaternion from TrackData payload.
      float[] translation = new float[3];
      float[] quaternion = new float[4];

      floatBuffer.get(translation);
      floatBuffer.get(quaternion);

      // Transform the recorded anchor pose
      // from the camera coordinate
      // into world coordinates.
      Pose worldPose = camera.getPose().compose(new Pose(translation, quaternion));

      // Re-create an anchor at the recorded pose.
      Anchor recordedAnchor = session.createAnchor(worldPose);

      // Add the new anchor into the list of anchors so that
      // the AR marker can be displayed on top.
      anchors.add(recordedAnchor);
    }
  }

HelloArActivity.javaonDrawFrame() ফাংশনে createRecordedAnchors() কল করুন।

  public void onDrawFrame(SampleRender render) {
    // ... omitted code ...

    // Insert after this line:
    // handleTap(frame, camera);

    // If the app is currently playing back a session, create recorded anchors.
    if (appState == AppState.Playingback) {
      createRecordedAnchors(frame, camera);
    }
    // ... omitted code ...
  }

লক্ষ্য ডিভাইসে পরীক্ষা

আপনার মোবাইল ডিভাইসটিকে আপনার ডেভেলপমেন্ট মেশিনের সাথে সংযুক্ত করুন এবং অ্যান্ড্রয়েড স্টুডিওতে চালান ক্লিক করুন৷

প্রথমে, একটি সেশন রেকর্ড করতে রেকর্ড বোতামে আলতো চাপুন। রেকর্ডিংয়ের সময়, কয়েকটি AR মার্কার রাখতে সনাক্ত করা প্লেনে আলতো চাপুন।

রেকর্ডিং বন্ধ হওয়ার পরে, প্লেব্যাক বোতামটি আলতো চাপুন এবং আপনি যে ফাইলটি রেকর্ড করেছেন সেটি নির্বাচন করুন। প্লেব্যাক শুরু করা উচিত। আপনি যেমন অ্যাপে ট্যাপ করছেন ঠিক তখনই আপনার আগের AR মার্কার প্লেসমেন্টগুলি কীভাবে দেখা যাচ্ছে তা লক্ষ্য করুন।

এই কোডল্যাবের জন্য আপনাকে এই সমস্ত কোডিং করতে হবে।

6. অভিনন্দন

অভিনন্দন, আপনি এই কোডল্যাবের শেষে পৌঁছেছেন! এই কোডল্যাবে আপনি কী করেছেন তা দেখা যাক:

  • ARCore Hello AR Java নমুনা তৈরি এবং চালান।
  • একটি MP4 ফাইলে একটি AR সেশন সংরক্ষণ করতে অ্যাপটিতে একটি রেকর্ড বোতাম যোগ করা হয়েছে৷
  • একটি MP4 ফাইল থেকে একটি AR সেশন চালানোর জন্য অ্যাপে একটি প্লেব্যাক বোতাম যোগ করা হয়েছে
  • প্লে ব্যাক করার জন্য MP4 এ ব্যবহারকারীর দ্বারা তৈরি অ্যাঙ্করগুলি সংরক্ষণ করতে একটি নতুন বৈশিষ্ট্য যুক্ত করা হয়েছে৷

আপনি কি মজা এই কোডল্যাব করছেন?

হ্যাঁ না

আপনি এই কোডল্যাব করতে দরকারী কিছু শিখেছি?

হ্যাঁ না

আপনি কি এই কোডল্যাবে অ্যাপ তৈরি সম্পূর্ণ করেছেন?

হ্যাঁ না