שימוש בסשן של הגברת התאורה החלשה

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

Kotlin

dependencies {
  val low_light_boost_version = "16.0.1-beta04"
  implementation("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.10.2")
  implementation("com.google.android.gms:play-services-base:18.7.0")
  implementation("com.google.android.gms:play-services-camera-low-light-boost:${low_light_boost_version}")
  implementation("com.google.android.gms:play-services-tasks:18.3.0")
}

מגניב

dependencies {
  def low_light_boost_version = "16.0.1-beta04"
  implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.10.2'
  implementation 'com.google.android.gms:play-services-base:18.7.0'
  implementation 'com.google.android.gms:play-services-camera-low-light-boost:${low_light_boost_version}'
  implementation 'com.google.android.gms:play-services-tasks:18.3.0'
}

‫LowLightBoostSession מסופק על ידי החבילה com.google.android.gms.cameralowlight של Google Play Services. במסמכי התיעוד של Google Play Services מוסבר איך לגשת לממשקי ה-API של Google Play Services.

יצירת אובייקט קריאה חוזרת (callback)

כשיוצרים את הסשן של שדרוג התאורה, צריך להעביר לו אובייקט שמטמיע את הממשק LowLightBoostCallback. המערכת קוראת לפונקציות של האובייקט הזה כשהסשן מתנתק או נמחק. הקוד הבא מראה איך ליצור קריאה חוזרת (callback):

Kotlin

private fun createLowLightBoostCallback(): LowLightBoostCallback =
  object : LowLightBoostCallback() {
    override fun onSessionDestroyed() {
      Log.d(TAG, "onSessionDestroyed")
      lowLightBoostSession = null
    }

    override fun onSessionDisconnected(statusCode: Int) {
      Log.d(TAG, "onSessionDisconnected: error=$statusCode")
      lowLightBoostSession = null
    }
  }

Java

private LowLightBoostCallback createLowLightBoostCallback() {
  LowLightBoostCallback lowLightBoostCallback = new LowLightBoostCallback() {
    @Override
    public void onSessionDestroyed() {
      Log.d(TAG, "onSessionDestroyed");
      lowLightBoostSession = null;
    }

    @Override
    public void onSessionDisconnected(int statusCode) {
      Log.d(TAG, "onSessionCreationFailed: error=" + statusCode);
      lowLightBoostSession = null;
    }
  }
  return lowLightBoostCallback;
}

מידע חשוב על הקוד

  • הקוד הזה מגדיר שיטה פרטית, createLowLightBoostCallback(), שיוצרת את אובייקט הקריאה החוזרת (callback). תקראו לשיטה הזו כשתצרו את הסשן של שיפור התאורה, כמו שמתואר בקטע יצירת סשן.
  • הקריאה החוזרת (callback) מתבצעת כשהסשן מתנתק או נהרס. היא לא נקראת כשהסשן נוצר. כדי לבדוק אם הסשן נוצר, בודקים את האובייקט Task שמוחזר על ידי LowLightBoostClient.createSession.

יצירת סשן

כדי ליצור סשן בתאורה חלשה, מפעילים את ה-method‏ LowLightBoostClient.createSession.

Kotlin

val options = LowLightBoostOptions(
  previewSurface,
  cameraId,
  previewWidth,
  previewHeight,
  enableLowLightBoost
)

launch {
  try {
    val lowLightBoostSession = lowLightBoostClient
      .createSession(options, createLowLightBoostCallback()).await()

    Log.d(TAG, "Session created successfully")

    // Get the surface from the LLB session;
    // give it to camera so camera can write frames to it
  } catch (e: CancellationException) {
    Log.w(TAG, "Session creation was canceled", e)
    lowLightBoostSession = null
  } catch (e: ApiException) {
    Log.e(TAG, "Session creation failed with ApiException:", e)
    lowLightBoostSession = null
  } catch (e: Exception) {
    Log.e(TAG, "Session creation failed with Exception", e)
    lowLightBoostSession = null
  }
}

Java

LowLightBoostOptions options = new LowLightBoostOptions(
  previewSurface,
  cameraId,
  previewWidth,
  previewHeight,
  enableLowLightBoost);

lowLightBoostClient
  .createSession(options, createLowLightBoostCallback())
  .addOnSuccessListener(
    lowLightBoostExecutor,
    (session) -> {
      Log.d(TAG, "Session created successfully");

      // Get the surface from the LLB session;
      // give it to camera so camera can write frames to it

    })
  .addOnFailureListener(
    lowLightBoostExecutor,
    (e) -> {
      ApiException apiException = (ApiException) e;
      Log.d(TAG, "Session creation failed: " + e);
      lowLightBoostSession = null;
    })
  .addOnCompleteListener(
    lowLightBoostExecutor,
    (task) -> Log.d(TAG, "Session creation complete"))
  .addOnCanceledListener(
    lowLightBoostExecutor,
    () -> {
      throw new RuntimeException("Session creation canceled");
    });

מידע חשוב על הקוד

  • מעבירים אובייקט LowLightBoostOptions אל createSession() כדי להגדיר את הסשן. האובייקט הזה מציין דברים כמו משטח היעד, מזהה המצלמה שבה צריך להשתמש ומידות התצוגה המקדימה.
  • הקוד הזה מניח שכבר פתחתם חיבור למצלמת Camera2, והשתמשתם במידע הזה כדי להגדיר את הערכים של cameraId, previewWidth, previewHeight. מידע נוסף זמין במסמכי התיעוד של Camera2.
  • ‫enableLowLightBoost הוא ערך בוליאני שקובע אם התכונה "שיפור התאורה" תופעל או תושבת כברירת מחדל.
  • ‫createLowLightBoostCallback היא שיטה שכותבים כדי ליצור את אובייקט הקריאה החוזרת (callback). האובייקט הזה נקרא כשהסשן מנותק או נהרס.
  • השיטה LowLightBoostClient.createSession() מחזירה אובייקט Task. אתם משתמשים באובייקט הזה כדי להגדיר מאזינים להצלחה ולכישלון. צריך לתעד את הסרטון בתוך מאזין האירועים (event listener) של ההצלחה.
  • אפשר לציין Executor כדי להפעיל את המאזינים. אם לא מציינים Executor, המאזינים פועלים בשרשור הראשי. בקוד הזה, אנחנו מניחים ש-lowLightBoostExecutor הוא Executor מתאים.

העברת תוצאות הצילום

כדי לדעת כמה להבהיר את התמונה, התכונה "שיפור התאורה" של Google צריכה מטא-נתונים מסוימים מהמצלמה. צריך להעביר את TotalCaptureResult ל-method‏ processCaptureResult(). אפשר לקבל את הערך של TotalCaptureResult בשיטת הקריאה החוזרת (callback) onCaptureCompleted().

Kotlin

  val captureCallback = CameraCaptureSession.CaptureCallback() {
    override fun onCaptureCompleted(
      session: CameraCaptureSession,
      request: CaptureRequest,
      result: TotalCaptureResult
    ) {
      super.onCaptureCompleted(session, request, result)
      lowLightBoostSession?.processCaptureResult(result)
    }
  }

Java

  CameraCaptureSession.CaptureCallback captureCallback =
    new CameraCaptureSession.CaptureCallback() {
      @Override
      public void onCaptureCompleted(
        @NonNull CameraCaptureSession session,
        @NonNull CaptureRequest request,
        @NonNull TotalCaptureResult result) {
          super.onCaptureCompleted(session, request, result)
          if (lowLightBoostSession != null) {
            lowLightBoostSession.processCaptureResult(result);
          }
        }
      };

מידע חשוב על הקוד

  • הקוד הזה מציג רק את הקוד של CaptureCallback שרלוונטי ל-Google LLB. סביר להניח שיהיה לכם קוד אחר בקריאות החוזרות האלה.
  • העברת ה-TotalCaptureResult מאפשרת ל-Google LLB לנתח את נתוני החשיפה האוטומטית ומטא-נתונים אחרים שנדרשים ל-LLB כדי לעבד את זיהוי הסצנה ולקבוע כמה שיפור להחיל על הפריים.
  • צריך להעביר את האובייקט captureCallback כשיוצרים את סשן המצלמה, לדוגמה באמצעות setSingleRepeatingRequest()‎.

התחלת התצוגה המקדימה של המצלמה

אחרי שיוצרים סשן בתאורה חלשה, אפשר להתחיל את הסטרימינג של התצוגה המקדימה במצלמה. צריך לעשות את זה בתוך הקריאה החוזרת (callback) של onSuccess() שמעבירים לסשן בתאורה חלשה, כמו שמתואר בקטע יצירת סשן. הקוד הבא מראה איך לצלם וידאו:

Kotlin

MainActivity.this.lowLightBoostSession =
  lowLightBoostSession
MainActivity.this.lowLightBoostSession
  .setSceneDetectorCallback(
    (lowLightBoostSession, boostStrength) -> {
      Log.d(TAG, "onSceneBrightnessChanged: " +
        "boostStrength=$boostStrength")
      // boostStrength > 0.5 indicates a low light scene.
      // Update UI accordingly.
    },
    lowLightBoostExecutor
  )
try {
  startCaptureSession(
    lowLightBoostSession.getCameraSurface())
    // Start a Camera2 session here. Pass the LLB surface
    // to the camera so the camera can write frames to it.
} catch (e: CameraAccessException) {
  Log.e(TAG, "Failed to start capture session", e)
  // Must try again or start the capture session without LLB.
}

Java

MainActivity.this.lowLightBoostSession =
  lowLightBoostSession;
MainActivity.this.lowLightBoostSession
  .setSceneDetectorCallback(
    (lowLightBoostSession, boostStrength) -> {
      Log.d(TAG, "onSceneBrightnessChanged: " +
        "boostStrength=" + boostStrength);
      // boostStrength > 0.5 indicates a low light scene.
      // Update UI accordingly.
    },
    lowLightBoostExecutor
  );
try {
  startCaptureSession(
    lowLightBoostSession.getCameraSurface());
    // Start a Camera2 session here. Pass the LLB surface
    // to the camera so the camera can write frames to it.
} catch (CameraAccessException e) {
  Log.e(TAG, "Failed to start capture session", e);
  // Must try again or start the capture session without LLB.
}

מידע חשוב על הקוד

  • ‫lowLightBoostSession הוא הסשן שיצרתם בקטע יצירת סשן.
  • setSceneDetectorCallback() מגדיר אובייקט קריאה חוזרת (callback) שמטמיע את הממשק SceneDetectorCallback. הסשן קורא ל-method‏ onSceneBrightnessChanged() של האובייקט הזה כשבהירות הסצנה משתנה. ההטמעה שלכם צריכה להתאים את ממשק המשתמש של המצלמה בהתאם.
  • אפשר לציין Executor כדי להריץ את הקריאה החוזרת (callback). אם לא מציינים Executor, פונקציית ה-callback פועלת ב-thread הראשי. בקוד הזה, אנחנו מניחים ש-lowLightBoostExecutor הוא Executor מתאים.
  • הפונקציה lowLightBoostSession.getCameraSurface() מחזירה את Surface עם הסרטון שצולם.

שחרור הסשן

כשהמצלמה כבר לא פעילה, צריך לשחרר את הסשן של שיפור התאורה על ידי קריאה ל-LowLightBoostSession.release(). חשוב במיוחד לוודא שהסשן משוחרר כשהפעילות מושמדת. כדי לעשות את זה, מפעילים את השיטה ב-method‏ onDestroy() של הפעילות:

Kotlin

override protected void onDestroy() {
  super.onDestroy()
  if (lowLightBoostSession != null) {
    lowLightBoostSession.release()
    lowLightBoostSession = null
  }
}

Java

@Override
protected void onDestroy() {
  super.onDestroy();
  if (lowLightBoostSession != null) {
    lowLightBoostSession.release();
    lowLightBoostSession = null;
  }
}

מידע חשוב על הקוד

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