מדריכים

צילום מהיר וסרטונים בהילוך איטי באמצעות CameraX 1.5

משך הקריאה: 6 דקות
Leo Huang
מהנדס תוכנה

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

בעבר, הטמעה של התכונות האלה באמצעות Camera2 API הייתה תהליך מעשי יותר. עכשיו, עם ה-API החדש למהירות גבוהה ב-CameraX 1.5, התהליך כולו פשוט יותר, ואתם יכולים ליצור סרטונים אמיתיים בקצב פריימים גבוה או קליפים בהילוך איטי שמוכנים להפעלה. בפוסט הזה נסביר איך לשלוט בשני סוגי המודעות. אם אתם חדשים ב-CameraX, תוכלו לקרוא את הסקירה הכללית על CameraX כדי להכיר את הנושא.


העיקרון שמאחורי הילוך איטי

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

כדי שהסרטון הסופי יהיה חלק וזורם, בדרך כלל צריך לבצע רינדור בקצב של 30 פריימים לשנייה לפחות. כלומר, כדי ליצור סרטון בהילוך איטי פי 4, קצב הפריימים המקורי של הצילום צריך להיות לפחות 120fps (120fps של צילום חלקי 4 = 30fps של הפעלה).

אחרי שמצלמים את הצילומים בקצב פריימים גבוה, יש שתי דרכים עיקריות להשיג את התוצאה הרצויה:

  • הילוך איטי שמופעל על ידי הנגן (סרטון עם קצב פריימים גבוה): הצילום במהירות גבוהה (למשל 120fps) נשמר ישירות כקובץ סרטון עם קצב פריימים גבוה. אחרי כן, נגן הסרטונים מאט את מהירות ההפעלה. כך המשתמש יכול לעבור בקלות בין הפעלה רגילה להפעלה בהילוך איטי.
  • סרטון בהילוך איטי שמוכן להפעלה (סרטון שעבר קידוד מחדש): זרם הווידאו המהיר עובר עיבוד וקידוד מחדש לקובץ עם קצב פריימים רגיל (למשל, ‎30 fps). האפקט של ההילוך האיטי מוטמע בסרטון על ידי שינוי חותמות הזמן של הפריים. הסרטון שיתקבל יופעל בהילוך איטי בכל נגן וידאו רגיל ללא צורך בטיפול מיוחד. הסרטון מופעל בהילוך איטי כברירת מחדל, אבל נגני וידאו עדיין יכולים לספק כפתורים לשינוי מהירות ההפעלה, שיאפשרו למשתמש להגביר את המהירות ולצפות בסרטון במהירות המקורית שלו.

ממשק CameraX API מפשט את התהליך הזה ומאפשר לכם לבחור את הגישה הרצויה באופן אחיד, כפי שמוסבר בהמשך.


ה-API החדש של סרטונים מהירים

הפתרון החדש של CameraX מבוסס על שני רכיבים עיקריים:

  • Recorder#getHighSpeedVideoCapabilities(CameraInfo): בשיטה הזו אפשר לבדוק אם המצלמה יכולה לצלם במהירות גבוהה, ואם כן, אילו רזולוציות (אובייקטים מסוג Quality) נתמכות.
  • HighSpeedVideoSessionConfig: זהו אובייקט הגדרה מיוחד שמקבץ את תרחישי השימוש של VideoCapture ושל Preview, ומורה ל-CameraX ליצור סשן מאוחד של מצלמה מהירה. שימו לב: אמנם הסטרימינג של VideoCapture יפעל בקצב הפריימים הגבוה שהוגדר, אבל הסטרימינג של התצוגה המקדימה בדרך כלל יוגבל לקצב סטנדרטי של לפחות 30 FPS על ידי מערכת המצלמה, כדי להבטיח תצוגה חלקה על המסך.

תחילת העבודה

לפני שמתחילים, מוסיפים את יחסי התלות הדרושים של CameraX לקובץ build.gradle.kts של האפליקציה. תצטרכו את ארטיפקט camera-video יחד עם ספריות הליבה של CameraX.

// build.gradle.kts (Module: app)

dependencies {

    val camerax_version = "1.5.1"


    implementation("androidx.camera:camera-core:$camerax_version")

    implementation("androidx.camera:camera-camera2:$camerax_version")

    implementation("androidx.camera:camera-lifecycle:$camerax_version")

    implementation("androidx.camera:camera-video:$camerax_version")

    implementation("androidx.camera:camera-view:$camerax_version")

}

הערה לגבי ממשקי API ניסיוניים

חשוב לציין שכרגע ממשקי ה-API של ההקלטה המהירה הם ניסיוניים. כלומר, הם עשויים להשתנות בגרסאות עתידיות. כדי להשתמש בהם, צריך להוסיף את ההערה הבאה לקוד:

@kotlin.OptIn(ExperimentalSessionConfig::class, ExperimentalHighSpeedVideo::class)

הטמעה

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

1. הגדרת צילום במהירות גבוהה

קודם כל, בלי קשר ליעד שלכם, אתם צריכים לקבל את ProcessCameraProvider, לבדוק את היכולות של המכשיר וליצור את תרחישי השימוש שלכם.

בלוק הקוד הבא מציג את תהליך ההגדרה המלא בתוך פונקציית השהיה. אפשר להפעיל את הפונקציה הזו מההקשר של שגרת המשך (coroutine), כמו lifecycleScope.launch.

// Add the OptIn annotation at the top of your function or class

@kotlin.OptIn(ExperimentalSessionConfig::class, ExperimentalHighSpeedVideo::class)

private suspend fun setupCamera() {

    // Asynchronously get the CameraProvider

    val cameraProvider = ProcessCameraProvider.awaitInstance(this)



    // -- CHECK CAPABILITIES --

    val cameraInfo = cameraProvider.getCameraInfo(CameraSelector.DEFAULT_BACK_CAMERA)

    val videoCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo)

    if (videoCapabilities == null) {

        // This camera device does not support high-speed video.

        return

    }




    // -- CREATE USE CASES --

    val preview = Preview.Builder().build()    


    // You can create a Recorder with default settings.

    // CameraX will automatically select a suitable quality.

    val recorder = Recorder.Builder().build()


    // Alternatively, to use a specific resolution, you can configure the
    // Recorder with a QualitySelector. This is useful if your app has
    // specific resolution requirements or you want to offer user
    // preferences. 

    // To use a specific quality, you can uncomment the following lines.

    // Get the list of qualities supported for high-speed video. 

    // val supportedQualities = videoCapabilities.getSupportedQualities(DynamicRange.SDR)

    // Build the Recorder using the quality from the supported list.

    // val recorderWithQuality = Recorder.Builder()

    //     .setQualitySelector(QualitySelector.from(supportedQualities.first()))

    //     .build()



    // Create the VideoCapture use case, using either recorder or recorderWithQuality

    val videoCapture = VideoCapture.withOutput(recorder)

    // Now you are ready to configure the session for your desired output...

}

2. בחירת הפלט

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

אפשרות א': יצירת סרטון עם קצב פריימים גבוה

מומלץ לבחור באפשרות הזו אם רוצים שקצב הפריימים של הקובץ הסופי יהיה גבוה (למשל, סרטון עם 120fps).

// Create a builder for the high-speed session

val sessionConfigBuilder = HighSpeedVideoSessionConfig.Builder(videoCapture)

    .setPreview(preview)


// Query and apply a supported frame rate. Common supported frame rates include 120 and 240 fps.

val supportedFrameRateRanges =

    cameraInfo.getSupportedFrameRateRanges(sessionConfigBuilder.build())


sessionConfigBuilder.setFrameRateRange(supportedFrameRateRanges.first())

אפשרות ב': יצירת סרטון בהילוך איטי שמוכן להפעלה

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

// Create a builder for the high-speed session

val sessionConfigBuilder = HighSpeedVideoSessionConfig.Builder(videoCapture)

    .setPreview(preview)



// This is the key: enable automatic slow-motion!

sessionConfigBuilder.setSlowMotionEnabled(true)



// Query and apply a supported frame rate. Common supported frame rates include 120, 240, and 480 fps.

val supportedFrameRateRanges =

   cameraInfo.getSupportedFrameRateRanges(sessionConfigBuilder.build())

sessionConfigBuilder.setFrameRateRange(supportedFrameRateRanges.first())

הדגל הזה הוא המפתח ליצירת סרטון בהילוך איטי שמוכן להפעלה. אם הערך של setSlowMotionEnabled הוא true, ‏ CameraX מעבד את הזרם המהיר ושומר אותו כקובץ וידאו רגיל של 30fps. מהירות ההילוך האיטי נקבעת לפי היחס בין קצב הפריימים של הצילום לבין קצב ההפעלה הרגיל הזה.

לדוגמה:

  • הקלטה ב-120fps תיצור סרטון שיופעל ב-1/4 מהמהירות (‎120 ÷ 30 = 4).
  • צילום ב-240fps ייצור סרטון שיופעל ב-1/8 מהמהירות (240 ÷ 30 = 8).

סיכום: הקלטת הסרטון

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

הפוסט הזה מתמקד בהגדרה של מהירות גבוהה, ולכן לא נסביר בפירוט על תהליך ההקלטה. לקבלת מדריך מקיף בנושאים שונים, החל מהכנת אובייקט FileOutputOptions או MediaStoreOutputOptions ועד לטיפול בקריאות החוזרות (callback) של VideoRecordEvent, אפשר לעיין במסמכי התיעוד של VideoCapture.

// Bind the session config to the lifecycle

cameraProvider.bindToLifecycle(

    this as LifecycleOwner,

    CameraSelector.DEFAULT_BACK_CAMERA,

    sessionConfigBuilder.build() // Bind the config object from Option A or B

)



// Start the recording using the VideoCapture use case

val recording = videoCapture.output

    .prepareRecording(context, outputOptions) // See docs for creating outputOptions

    .start(ContextCompat.getMainExecutor(context)) { recordEvent ->

        // Handle recording events (e.g., Start, Pause, Finalize)

    }

תמיכה בסרטונים בהילוך איטי ב-Google Photos

כשמפעילים את setSlowMotionEnabled(true) ב-CameraX, קובץ הווידאו שנוצר מיועד להיות מזוהה וניתן להפעלה באופן מיידי כהילוך איטי בנגני וידאו רגילים ובאפליקציות גלריה. ב-Google Photos יש פונקציונליות משופרת לסרטונים בהילוך איטי, אם קצב הפריימים בצילום הוא 120,‏ 240,‏ 360,‏ 480 או 960 פריימים לשנייה:

  • זיהוי ממשק משתמש ייחודי בתמונה הממוזערת: בספרייה שלכם ב-Google Photos, אפשר לזהות סרטונים בהילוך איטי לפי רכיבי ממשק משתמש ספציפיים, שמבדילים אותם מסרטונים רגילים.
normal.png
  • קטעים עם מהירות מתכווננת במהלך ההפעלה: כשמפעילים סרטון בהילוך איטי, Google Photos מספקת אמצעי בקרה לשינוי המהירות של חלקים שונים בסרטון. כך המשתמשים יכולים להחליט אילו חלקים יופעלו בהילוך איטי ואילו במהירות רגילה, ולקבל שליטה יצירתית. אחרי העריכה, אפשר לייצא את הסרטון כקובץ סרטון חדש באמצעות הלחצן שיתוף, והקטעים שהגדרתם בהילוך איטי יישמרו.
normal2.png

הערה לגבי תמיכה במכשירים

ה-API המהיר של CameraX מסתמך על מערכת CamcorderProfile הבסיסית של Android כדי לקבוע אילו רזולוציות וקצבי פריימים מהירים נתמכים במכשיר. פרופילי מצלמת הווידאו מאומתים על ידי חבילת בדיקות התאימות (CTS) של Android, כך שאתם יכולים להיות בטוחים ביכולות צילום הווידאו המדווחות של המכשיר.

כלומר, היכולת של מכשיר להקליט סרטון בהילוך איטי באמצעות אפליקציית המצלמה המובנית שלו לא מבטיחה ש-CameraX API במהירות גבוהה יפעל. הפער הזה נוצר כי יצרני המכשירים אחראים לאכלוס הערכים של CamcorderProfile בקושחה של המכשיר, ולפעמים לא נכללים פרופילים נחוצים של מהירות גבוהה כמו CamcorderProfile.QUALITY_HIGH_SPEED_1080P ו-CamcorderProfile.QUALITY_HIGH_SPEED_720P. אם הפרופילים האלה חסרים, Recorder.getHighSpeedVideoCapabilities() יחזיר null.

לכן, חשוב מאוד להשתמש תמיד ב-Recorder.getHighSpeedVideoCapabilities() כדי לבדוק באופן פרוגרמטי אם התכונות נתמכות, כי זו הדרך הכי אמינה להבטיח חוויה עקבית במכשירים שונים. אם תנסו לקשור HighSpeedVideoSessionConfig במכשיר שבו Recorder.getHighSpeedVideoCapabilities() מחזיר ערך null, הפעולה תיכשל עם IllegalArgumentException. אפשר לוודא שיש תמיכה במכשירי Google Pixel, כי הם תמיד כוללים את פרופילי המהירות הגבוהה האלה. בנוסף, מכשירים שונים של יצרנים אחרים, כמו Motorola Edge 30,‏ OPPO Find N2 Flip ו-Sony Xperia 1 V, תומכים גם הם ביכולות של צילום וידאו במהירות גבוהה.


סיכום

ממשק ה-API של CameraX לצילום סרטונים במהירות גבוהה הוא גם עוצמתי וגם גמיש. אם אתם צריכים צילום אמיתי בקצב פריימים גבוה לניתוח טכני, או שאתם רוצים להוסיף לאפליקציה שלכם אפקטים של הילוך איטי קולנועי, HighSpeedVideoSessionConfig מספק פתרון פשוט ומאוחד. הבנת התפקיד של הדגל setSlowMotionEnabled מאפשרת לכם לתמוך בקלות בשני תרחישי השימוש ולתת למשתמשים שלכם יותר שליטה יצירתית.

נכתב על ידי:

להמשך הקריאה