מערכת צילום בדרך כלל מקליטה שידורי וידאו ואודיו, דוחסת אותם, משלבת את שני השידורים ואז כותבת את השידור שנוצר בדיסק.
ב-CameraX, הפתרון לצילום וידאו הוא תרחיש השימוש VideoCapture:
VideoCapture.כמו שמוצג באיור 2, צילום וידאו ב-CameraX כולל כמה רכיבים ארכיטקטוניים ברמה גבוהה:
SurfaceProviderלמקור הסרטון.AudioSourceלמקור האודיו.- שני מקודדים כדי לקודד ולדחוס את הווידאו והאודיו.
- ממקסר מדיה כדי למקסר את שני הסטרימים.
- כלי לשמירת קבצים כדי לכתוב את התוצאה.
VideoCapture API מסתיר את מנוע הצילום המורכב ומספק לאפליקציות ממשק API פשוט וישיר יותר.
סקירה כללית על VideoCapture API
VideoCapture הוא תרחיש לדוגמה של CameraX שפועל היטב בפני עצמו או בשילוב עם תרחישים אחרים לדוגמה. השילובים הספציפיים שנתמכים תלויים ביכולות החומרה של המצלמה, אבל Preview ו-VideoCapture הם שילוב תקין של תרחישי שימוש בכל המכשירים.
VideoCapture API מורכב מהאובייקטים הבאים שמתקשרים עם אפליקציות:
-
VideoCaptureהיא המחלקה של תרחיש השימוש ברמה העליונה. VideoCaptureנקשר ל-LifecycleOwnerעםCameraSelectorו-UseCases אחרים של CameraX. מידע נוסף על המושגים והשימושים האלה זמין במאמר ארכיטקטורת CameraX. -
Recorderהוא הטמעה של VideoOutput שמקושרת באופן הדוק ל-VideoCapture. Recorderמשמש לצילום הווידאו והקלטת האודיו. אפליקציה יוצרת הקלטות מ-Recorder. PendingRecordingמגדיר הקלטה, ומספק אפשרויות כמו הפעלת אודיו והגדרת רכיב event listener. כדי ליצורPendingRecording, צריך להשתמש ב-Recorder.PendingRecordingלא מקליט שום דבר.- ההקלטה עצמה מתבצעת באמצעות
Recording. כדי ליצורRecording, צריך להשתמש ב-PendingRecording.
באיור 3 מוצגים הקשרים בין האובייקטים האלה:
מקרא:
- יצירת
RecorderעםQualitySelector. - מגדירים את
Recorderבאמצעות אחת מOutputOptions. - אם צריך, מפעילים את האודיו באמצעות
withAudioEnabled(). - כדי להתחיל להקליט, צריך להתקשר אל
start()עם מאזיןVideoRecordEvent. - אפשר להשתמש ב-
pause()/resume()/stop()ב-Recordingכדי לשלוט בהקלטה. - מגיבים לאירוע
VideoRecordEventsבתוך רכיב ה-event listener.
רשימת ה-API המפורטת נמצאת בקובץ current.txt בתוך קוד המקור.
שימוש ב-VideoCapture API
כדי לשלב את תרחיש השימוש VideoCapture של CameraX באפליקציה:
- כריכה של
VideoCapture. - מכינים ומגדירים את ההקלטה.
- התחלה של הקלטת זמן הריצה ושליטה בה.
בקטעים הבאים מוסבר מה אפשר לעשות בכל שלב כדי לקבל סשן הקלטה מקצה לקצה.
קישור של VideoCapture
כדי לקשר את תרחיש השימוש VideoCapture:
- יוצרים אובייקט
Recorder. - יוצרים אובייקט
VideoCapture. - קישור אל
Lifecycle.
CameraX VideoCapture API פועל לפי תבנית העיצוב של ה-builder. אפליקציות משתמשות ב-Recorder.Builder כדי ליצור Recorder. אפשר גם להגדיר את רזולוציית הווידאו של Recorder באמצעות אובייקט QualitySelector.
CameraX Recorder תומך ב-Qualities המוגדרים מראש הבאים לרזולוציות של סרטונים:
Quality.UHDלגודל סרטון 4K Ultra HD (2160p)Quality.QHDלגודל וידאו Quad HD (1440p), שהוצג ב-CameraX1.7.0-alpha02-
Quality.FHDלסרטון בגודל Full HD (1080p) Quality.HDלסרטון באיכות HD (720p)-
Quality.SDלגודל וידאו SD (480p)
חשוב לזכור ש-CameraX יכולה לבחור גם רזולוציות אחרות אם האפליקציה מאשרת זאת.
גודל הסרטון המדויק של כל אפשרות תלוי ביכולות של המצלמה והמקודד. מידע נוסף זמין במאמרי העזרה של CamcorderProfile.
כדי להגדיר את הרזולוציה באפליקציות, צריך ליצור QualitySelector.
אפשר ליצור QualitySelector באחת מהשיטות הבאות:
אפשר לספק כמה רזולוציות מועדפות באמצעות
fromOrderedList(), ולכלול אסטרטגיית חלופית למקרה שאף אחת מהרזולוציות המועדפות לא נתמכת.CameraX יכולה להחליט מהי ההתאמה החלופית הטובה ביותר על סמך היכולת של המצלמה שנבחרה. פרטים נוספים זמינים ב-
FallbackStrategy specificationשלQualitySelector. לדוגמה, הקוד הבא מבקש את הרזולוציה הגבוהה ביותר שנתמכת להקלטה, ואם אף אחת מהרזולוציות המבוקשות לא נתמכת, מאשר ל-CameraX לבחור את הרזולוציה שהכי קרובה לרזולוציה Quality.SD:val qualitySelector = QualitySelector.fromOrderedList( listOf(Quality.UHD, Quality.QHD, Quality.FHD, Quality.HD, Quality.SD), FallbackStrategy.lowerQualityOrHigherThan(Quality.SD))קודם צריך לשלוח שאילתה לגבי יכולות המצלמה, ואז לבחור מבין הרזולוציות הנתמכות באמצעות
QualitySelector::from():val cameraInfo = cameraProvider.availableCameraInfos.filter { Camera2CameraInfo .from(it) .getCameraCharacteristic(CameraCharacteristics.LENS\_FACING) == CameraMetadata.LENS_FACING_BACK } val supportedQualities = QualitySelector.getSupportedQualities(cameraInfo[0]) val filteredQualities = arrayListOf (Quality.UHD, Quality.QHD, Quality.FHD, Quality.HD, Quality.SD) .filter { supportedQualities.contains(it) } // Use a simple ListView with the id of simple_quality_list_view viewBinding.simpleQualityListView.apply { adapter = ArrayAdapter(context, android.R.layout.simple_list_item_1, filteredQualities.map { it.qualityToString() }) // Set up the user interaction to manually show or hide the system UI. setOnItemClickListener { _, _, position, _ -> // Inside View.OnClickListener, // convert Quality.* constant to QualitySelector val qualitySelector = QualitySelector.from(filteredQualities[position]) // Create a new Recorder/VideoCapture for the new quality // and bind to lifecycle val recorder = Recorder.Builder() .setQualitySelector(qualitySelector).build() // ... } } // A helper function to translate Quality to a string fun Quality.qualityToString() : String { return when (this) { Quality.UHD -> "UHD" Quality.QHD -> "QHD" Quality.FHD -> "FHD" Quality.HD -> "HD" Quality.SD -> "SD" else -> throw IllegalArgumentException() } }שימו לב שהיכולת שמוחזרת מ-
QualitySelector.getSupportedQualities()תעבוד בוודאות בתרחיש לדוגמהVideoCaptureאו בשילוב של התרחישים לדוגמהVideoCaptureו-Preview. כשמבצעים קישור יחד עם תרחיש לדוגמה שלImageCaptureאוImageAnalysis, יכול להיות ש-CameraX עדיין ייכשל בקישור אם השילוב הנדרש לא נתמך במצלמה המבוקשת.
אחרי שיש לכם QualitySelector, האפליקציה יכולה ליצור אובייקט VideoCapture ולבצע את הקישור. שימו לב שהקישור הזה זהה לקישור בתרחישים אחרים:
val recorder = Recorder.Builder()
.setExecutor(cameraExecutor).setQualitySelector(qualitySelector)
.build()
val videoCapture = VideoCapture.withOutput(recorder)
try {
// Bind use cases to camera
cameraProvider.bindToLifecycle(
this, CameraSelector.DEFAULT_BACK_CAMERA, preview, videoCapture)
} catch(exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}
שימו לב שהפונקציה bindToLifecycle() מחזירה אובייקט Camera. במדריך הזה מוסבר איך לשלוט בפלט של המצלמה, כמו זום וחשיפה.
Recorder בוחר את הפורמט הכי מתאים למערכת. קודק הווידאו הנפוץ ביותר הוא H.264 AVC, עם פורמט מארז MPEG-4.
הגדרה ויצירה של הקלטה
מתוך Recorder, האפליקציה יכולה ליצור אובייקטים של הקלטה כדי לצלם את הווידאו ולהקליט את האודיו. כדי ליצור הקלטות באפליקציות:
- מגדירים את
OutputOptionsבאמצעותprepareRecording(). - (אופציונלי) מפעילים את הקלטת האודיו.
- משתמשים ב-
start()כדי לרשום מאזיןVideoRecordEvent, ומתחילים לצלם את הסרטון.
ה-Recorder מחזיר אובייקט Recording כשמפעילים את הפונקציה start().
האפליקציה יכולה להשתמש באובייקט Recording הזה כדי לסיים את ההקלטה או לבצע פעולות אחרות, כמו השהיה או המשך.
Recorder תומך באובייקט Recording אחד בכל פעם. אפשר להתחיל הקלטה חדשה אחרי שמפעילים את Recording.stop() או את Recording.close() באובייקט Recording הקודם.
בואו נבחן את השלבים האלה בפירוט. קודם כל, האפליקציה מגדירה את OutputOptions למכשיר הקלטה עם Recorder.prepareRecording().
Recorder תומך בסוגים הבאים של OutputOptions:
-
FileDescriptorOutputOptionsכדי לצלם תמונה ב-FileDescriptor. -
FileOutputOptionsכדי לתעד בFile. -
MediaStoreOutputOptionsכדי לצלם תמונה ב-MediaStore.
כל הסוגים של OutputOptions מאפשרים להגדיר גודל קובץ מקסימלי באמצעות setFileSizeLimit(). אפשרויות אחרות הן ספציפיות לסוג הפלט, כמו ParcelFileDescriptor עבור FileDescriptorOutputOptions.
הפונקציה prepareRecording() מחזירה אובייקט PendingRecording, שהוא אובייקט ביניים שמשמש ליצירת האובייקט Recording התואם. PendingRecording היא מחלקה זמנית שברוב המקרים לא אמורה להיות גלויה, והאפליקציה כמעט אף פעם לא שומרת אותה במטמון.
אפליקציות יכולות להגדיר את ההקלטה, למשל:
- הפעלת האודיו באמצעות
withAudioEnabled(). - רושמים מאזין כדי לקבל אירועים של הקלטת סרטונים באמצעות
start(Executor, Consumer<VideoRecordEvent>). - אפשר להמשיך להקליט הקלטה רציפה בזמן שה-VideoCapture שמחובר להקלטה מקושר מחדש למצלמה אחרת, באמצעות
PendingRecording.asPersistentRecording().
כדי להתחיל להקליט, צריך להתקשר אל PendingRecording.start(). CameraX הופך את ה-PendingRecording ל-Recording, מוסיף את בקשת ההקלטה לתור ומחזיר לאפליקציה את האובייקט Recording החדש שנוצר.
אחרי שההקלטה מתחילה במכשיר המצלמה המתאים, CameraX שולח אירוע VideoRecordEvent.EVENT_TYPE_START.
בדוגמה הבאה אפשר לראות איך מקליטים וידאו ואודיו בקובץ MediaStore:
// Create MediaStoreOutputOptions for our recorder
val name = "CameraX-recording-" +
SimpleDateFormat(FILENAME_FORMAT, Locale.US)
.format(System.currentTimeMillis()) + ".mp4"
val contentValues = ContentValues().apply {
put(MediaStore.Video.Media.DISPLAY_NAME, name)
}
val mediaStoreOutput = MediaStoreOutputOptions.Builder(this.contentResolver,
MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
.setContentValues(contentValues)
.build()
// 2. Configure Recorder and Start recording to the mediaStoreOutput.
val recording = videoCapture.output
.prepareRecording(context, mediaStoreOutput)
.withAudioEnabled()
.start(ContextCompat.getMainExecutor(this), captureListener)
כברירת מחדל, התצוגה המקדימה של המצלמה הקדמית מוצגת בשיקוף, אבל סרטונים שצולמו באמצעות VideoCapture לא מוצגים בשיקוף כברירת מחדל. ב-CameraX 1.3 אפשר להפוך הקלטות וידאו כך שהתצוגה המקדימה של המצלמה הקדמית והסרטון המוקלט יהיו זהים.
יש שלוש אפשרויות ל-MirrorMode: MIRROR_MODE_OFF, MIRROR_MODE_ON ו-MIRROR_MODE_ON_FRONT_ONLY. כדי להתאים לתצוגה המקדימה של המצלמה, Google ממליצה להשתמש ב-MIROR_MODE_ON_FRONT_ONLY, כלומר השיקוף לא מופעל במצלמה האחורית, אבל מופעל במצלמה הקדמית. מידע נוסף על MirrorMode זמין במאמר MirrorMode constants.
בקטע הקוד הבא אפשר לראות איך להפעיל את VideoCapture.Builder.setMirrorMode() באמצעות MIRROR_MODE_ON_FRONT_ONLY. מידע נוסף זמין במאמר setMirrorMode().
Kotlin
val recorder = Recorder.Builder().build() val videoCapture = VideoCapture.Builder(recorder) .setMirrorMode(MIRROR_MODE_ON_FRONT_ONLY) .build() useCases.add(videoCapture);
Java
Recorder.Builder builder = new Recorder.Builder(); if (mVideoQuality != QUALITY_AUTO) { builder.setQualitySelector( QualitySelector.from(mVideoQuality)); } VideoCapture<Recorder> videoCapture = new VideoCapture.Builder<>(builder.build()) .setMirrorMode(MIRROR_MODE_ON_FRONT_ONLY) .build(); useCases.add(videoCapture);
טווח דינמי (סרטון HDR)
CameraX תומך בהקלטת וידאו בטווח דינמי גבוה (HDR) של 10 ביט, כמו HLG10, HDR10, HDR10+ או Dolby Vision, באמצעות DynamicRange.
כדי להשתמש בצילום וידאו ב-HDR, פועלים לפי השלבים הבאים:
- שולחים שאילתה לגבי הטווחים הדינמיים שהמצלמה תומכת בהם באמצעות
VideoCapabilities.getSupportedDynamicRanges(). - אופציונלי: אם מגדירים
QualitySelectorבהתאמה אישית, בודקים אילו איכויות נתמכות בטווח הדינמי הזה באמצעותgetSupportedQualities(DynamicRange). - מגדירים את
VideoCapture.BuilderבאמצעותsetDynamicRange().
בדוגמה הבאה, מופעלת הקלטת וידאו HDR באיכות 10 ביט בפורמט HLG כשהמצלמה תומכת בכך:
Kotlin
val videoCapabilities = Recorder.getVideoCapabilities(cameraInfo) val supportedHdrRanges = videoCapabilities.supportedDynamicRanges .filter { it != DynamicRange.SDR } val recorder = Recorder.Builder().build() val videoCapture = VideoCapture.Builder(recorder) .apply { if (supportedHdrRanges.contains(DynamicRange.HLG_10_BIT)) { setDynamicRange(DynamicRange.HLG_10_BIT) } } .build()
Java
VideoCapabilities videoCapabilities = Recorder.getVideoCapabilities(cameraInfo); Set<DynamicRange> supportedRanges = videoCapabilities.getSupportedDynamicRanges(); Recorder recorder = new Recorder.Builder().build(); VideoCapture.Builder<Recorder> builder = new VideoCapture.Builder<>(recorder); if (supportedRanges.contains(DynamicRange.HLG_10_BIT)) { builder.setDynamicRange(DynamicRange.HLG_10_BIT); } VideoCapture<Recorder> videoCapture = builder.build();
ייצוב וידאו
CameraX תומך בייצוב וידאו כדי להפחית את הרעידות והתנודות של היד בזמן צילום סרטונים.
כדי להפעיל את ייצוב הווידאו:
- בודקים אם המצלמה תומכת בייצוב באמצעות
VideoCapabilities.isStabilizationSupported(). - מפעילים אותה ב-
VideoCapture.BuilderבאמצעותsetVideoStabilizationEnabled(true).
בדוגמה הבאה, הייצוב מופעל כשהמצלמה תומכת בו:
Kotlin
val videoCapabilities = Recorder.getVideoCapabilities(cameraInfo) val videoCapture = VideoCapture.Builder(recorder) .setVideoStabilizationEnabled(videoCapabilities.isStabilizationSupported) .build()
Java
VideoCapabilities videoCapabilities = Recorder.getVideoCapabilities(cameraInfo); VideoCapture<Recorder> videoCapture = new VideoCapture.Builder<>(recorder) .setVideoStabilizationEnabled(videoCapabilities.isStabilizationSupported()) .build();
שליטה בהקלטה פעילה
אפשר להשהות, להמשיך ולהפסיק Recording פעילה באמצעות השיטות הבאות:
pauseכדי להשהות את ההקלטה הפעילה הנוכחית.resume()כדי להמשיך הקלטה פעילה שהושהתה.stop()כדי לסיים את ההקלטה ולמחוק את כל האובייקטים שמשויכים להקלטה.mute()כדי להשתיק או לבטל את ההשתקה של ההקלטה הנוכחית.
שימו לב שאפשר להתקשר אל stop() כדי לסיים Recording, גם אם ההקלטה מושהית וגם אם היא פעילה.
אם רשמתם EventListener ב-PendingRecording.start(), ה-Recording מתקשר באמצעות VideoRecordEvent.
-
VideoRecordEvent.EVENT_TYPE_STATUSמשמש לתיעוד נתונים סטטיסטיים כמו גודל הקובץ הנוכחי ומשך הזמן שתועד. - השדה
VideoRecordEvent.EVENT_TYPE_FINALIZEמשמש לתוצאת ההקלטה וכולל מידע כמו ה-URI של הקובץ הסופי, יחד עם שגיאות קשורות.
אחרי שהאפליקציה מקבלת EVENT_TYPE_FINALIZE שמציין שסשן ההקלטה הצליח, אפשר לגשת לסרטון שצולם מהמיקום שצוין ב-OutputOptions.
עוצמת השמע והמצב בזמן אמת
במהלך ההקלטה, אירועי VideoRecordEvent.Status מספקים נתונים סטטיסטיים של אודיו בזמן אמת באמצעות AudioStats:
- הפונקציה
AudioStats.getAudioAmplitude()מחזירה את עוצמת השיא הנוכחית של האודיו, בטווח שבין0.0ל-1.0. אפשר להשתמש בערך הזה כדי להפעיל מדי ממשק משתמש או רכיבי visualizer של צורות גל של אודיו. -
AudioStats.getAudioState(): הסטטוס הנוכחי של שידור האודיו, למשלAUDIO_STATE_ACTIVE, AUDIO_STATE_MUTEDאוAUDIO_STATE_SOURCE_SILENCED.
בדוגמה הבאה, המערכת קוראת את עוצמת הקול מאירוע סטטוס:
Kotlin
when (event) { is VideoRecordEvent.Status -> { val audioStats = event.recordingStats.audioStats if (audioStats.hasAudio()) { val amplitude = audioStats.audioAmplitude updateAudioWaveform(amplitude) } } // ... }
Java
if (event instanceof VideoRecordEvent.Status) { VideoRecordEvent.Status status = (VideoRecordEvent.Status) event; AudioStats audioStats = status.getRecordingStats().getAudioStats(); if (audioStats.hasAudio()) { double amplitude = audioStats.getAudioAmplitude(); updateAudioWaveform(amplitude); } }
סרטונים במהירות גבוהה ובהילוך איטי
CameraX תומך בצילום וידאו במהירות גבוהה, כמו 120, 240 או 480 פריימים לשנייה, שמאפשר שני תרחישי שימוש שונים:
- סרטון בקצב פריימים גבוה (הילוך איטי שמנוהל על ידי הנגן): CameraX מצלם ושומר פריימים בקצב פריימים גבוה (לדוגמה, 120fps). בנגן הווידאו יש כפתורים לשינוי מהירות ההפעלה, שמאפשרים למשתמשים לעבור בין מהירות רגילה להילוך איטי או לנתח את הסרטון פריים אחרי פריים.
- סרטון בהילוך איטי שמוכן להפעלה: CameraX מעבד את הסטרימינג במהירות גבוהה ומוציא קובץ וידאו רגיל של 30fps עם חותמות זמן מותאמות של פריימים. אפקט ההילוך האיטי "מוטמע" בסרטון, כך שהוא מופעל בהילוך איטי באופן אוטומטי בכל נגן וידאו רגיל, בלי צורך בתמיכה מיוחדת של הנגן. לדוגמה, צילום בקצב של 120 פריימים לשנייה שמופעל בקצב של 30 פריימים לשנייה יוצר סרטון בהילוך איטי במהירות של 1/4x.
בדיקת היכולות של המהירות הגבוהה
כדי לצלם וידאו במהירות גבוהה, נדרשת תמיכה בחומרה והגדרות CamcorderProfile תואמות מיצרני המכשירים, כמו CamcorderProfile.QUALITY_HIGH_SPEED_1080P או QUALITY_HIGH_SPEED_720P.
לפני שמגדירים צילום במהירות גבוהה, צריך לשלוח שאילתה לגבי היכולות של המכשיר באמצעות Recorder.getHighSpeedVideoCapabilities(CameraInfo):
Kotlin
val highSpeedCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo) if (highSpeedCapabilities == null) { // Camera does not support high-speed video capture return } val supportedQualities = highSpeedCapabilities.getSupportedQualities(DynamicRange.SDR)
Java
VideoCapabilities highSpeedCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo); if (highSpeedCapabilities == null) { // Camera does not support high-speed video capture return; } List<Quality> supportedQualities = highSpeedCapabilities.getSupportedQualities(DynamicRange.SDR);
הגדרת HighSpeedVideoSessionConfig
כדי להשתמש בצילום במהירות גבוהה, צריך לשלב את תרחישי השימוש של VideoCapture ו-Preview ב-HighSpeedVideoSessionConfig. כדי להגדיר את הסשן, מבצעים את השלבים הבאים:
- יוצרים תרחיש שימוש אחד של
VideoCaptureותרחיש שימוש אחד שלPreview. - מאתחלים את
HighSpeedVideoSessionConfig.Builderעם תרחיש השימושVideoCaptureומצרפים אתPreview. - שולחים שאילתה לגבי טווחי קצב הפריימים הנתמכים באמצעות
CameraInfo.getSupportedFrameRateRanges(SessionConfig)ומגדירים את הטווח שנבחר. - בוחרים בין סרטון עם קצב פריימים גבוה לבין סרטון בהילוך איטי שמוכן להפעלה:
- כדי ליצור סרטון בקצב פריימים גבוה, משאירים את הערך
setSlowMotionEnabled(false)(ברירת המחדל). - כדי ליצור סרטון בהילוך איטי שמוכן להפעלה, צריך להפעיל את
setSlowMotionEnabled(true).
- כדי ליצור סרטון בקצב פריימים גבוה, משאירים את הערך
- מקשרים את הגדרת הסשן באמצעות
cameraProvider.bindToLifecycle().
בדוגמה הבאה מגדירים ומקשרים סשן של הילוך איטי שמוכן להפעלה:
Kotlin
val preview = Preview.Builder().build() val recorder = Recorder.Builder() .setQualitySelector(QualitySelector.from(supportedQualities.first())) .build() val videoCapture = VideoCapture.withOutput(recorder) // Build HighSpeedVideoSessionConfig val sessionConfigBuilder = HighSpeedVideoSessionConfig.Builder(videoCapture) .setPreview(preview) // Enable automatic slow-motion playback at 30 fps .setSlowMotionEnabled(true) // Query and set a supported high-speed frame rate range (such as 120 or 240 fps). // The set is non-empty because getHighSpeedVideoCapabilities() returned non-null earlier. val supportedFpsRanges = cameraInfo.getSupportedFrameRateRanges(sessionConfigBuilder.build()) sessionConfigBuilder.setFrameRateRange(supportedFpsRanges.first()) val sessionConfig = sessionConfigBuilder.build() // Bind session config to lifecycle cameraProvider.bindToLifecycle( lifecycleOwner, CameraSelector.DEFAULT_BACK_CAMERA, sessionConfig )
Java
Preview preview = new Preview.Builder().build(); Recorder recorder = new Recorder.Builder() .setQualitySelector(QualitySelector.from(supportedQualities.get(0))) .build(); VideoCapture<Recorder> videoCapture = VideoCapture.withOutput(recorder); HighSpeedVideoSessionConfig.Builder sessionConfigBuilder = new HighSpeedVideoSessionConfig.Builder(videoCapture) .setPreview(preview) .setSlowMotionEnabled(true); // The set is non-empty because getHighSpeedVideoCapabilities() returned non-null earlier. Set<Range<Integer>> supportedFpsRanges = cameraInfo.getSupportedFrameRateRanges(sessionConfigBuilder.build()); sessionConfigBuilder.setFrameRateRange(supportedFpsRanges.iterator().next()); HighSpeedVideoSessionConfig sessionConfig = sessionConfigBuilder.build(); cameraProvider.bindToLifecycle( lifecycleOwner, CameraSelector.DEFAULT_BACK_CAMERA, sessionConfig );
אפשר גם להשתמש ב-Kotlin DSL, שהוצג ב-CameraX 1.7.0-alpha02, כדי להגדיר סשנים במהירות גבוהה בצורה תמציתית:
val sessionConfig = highSpeedVideoSessionConfig(videoCapture) {
this.preview = preview
isSlowMotionEnabled = true
frameRateRange = supportedFpsRanges.first()
}
cameraProvider.bindToLifecycle(
lifecycleOwner,
CameraSelector.DEFAULT_BACK_CAMERA,
sessionConfig
)
איך מצלמים סרטונים במהירות גבוהה או בהילוך איטי
אחרי שמחברים את HighSpeedVideoSessionConfig, מתחילים לצלם באמצעות VideoCapture באותו אופן שבו מצלמים סרטונים רגילים:
Kotlin
val recording = videoCapture.output .prepareRecording(context, mediaStoreOutput) .withAudioEnabled() .start(ContextCompat.getMainExecutor(context)) { event -> when (event) { is VideoRecordEvent.Start -> Log.d(TAG, "Recording started") is VideoRecordEvent.Finalize -> { if (!event.hasError()) { Log.d(TAG, "Video saved: ${event.outputResults.outputUri}") } } } }
Java
Recording recording = videoCapture.getOutput() .prepareRecording(context, mediaStoreOutput) .withAudioEnabled() .start(ContextCompat.getMainExecutor(context), event -> { if (event instanceof VideoRecordEvent.Start) { Log.d(TAG, "Recording started"); } else if (event instanceof VideoRecordEvent.Finalize) { VideoRecordEvent.Finalize finalize = (VideoRecordEvent.Finalize) event; if (!finalize.hasError()) { Log.d(TAG, "Video saved: " + finalize.getOutputResults().getOutputUri()); } } });
מקורות מידע נוספים
איפה אפשר למצוא מידע נוסף על CameraX?
- Codelab תחילת העבודה עם CameraX
- אפליקציה לדוגמה רשמית של CameraX
- רשימת ה-API העדכניים של CameraX Video Capture
- נתוני הגרסה של CameraX
- קוד המקור של CameraX
- צילום במהירות גבוהה וסרטונים בהילוך איטי באמצעות CameraX 1.5