קליפים, להחיל אפקטים על סרטונים ולבצע אופטימיזציה של ייצוא. מילות מפתח_ציבורי: Media3, Transformer, transcode, עריכת סרטונים, חיתוך, עיבוד אודיו, מדיה ל-Android
המרת קידוד בין פורמטים
כשיוצרים טרנספורמציה, אפשר לציין את פורמטי האודיו והווידאו של הפלט שרוצים ליצור. לדוגמה, הקוד הבא מראה איך להגדיר את Transformer כך שיפיק וידאו בפורמט H.264/AVC ואודיו בפורמט AAC:
Kotlin
Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H264) .setAudioMimeType(MimeTypes.AUDIO_AAC) .build()
Java
new Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H264) .setAudioMimeType(MimeTypes.AUDIO_AAC) .build();
אם פורמט המדיה של קובץ הקלט כבר תואם להגדרות של האודיו או הסרטון, Transformer עובר אוטומטית לטרנסמוקסינג, כלומר, הוא מעתיק את הדגימות הדחוסות מהקונטיינר של קובץ הקלט לקונטיינר של קובץ הפלט ללא שינוי. כך נמנעת עלות החישוב ואובדן האיכות הפוטנציאליים של פענוח וקידוד מחדש באותו פורמט.
הסרת אודיו או סרטון
כדי להסיר אודיו או וידאו, משתמשים ב-EditedMediaItem.Builder, לדוגמה:
Kotlin
EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build()
Java
new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build();
חיתוך קליפ
אפשר להסיר כל מדיה מחוץ לטווח של חותמות הזמן של ההתחלה והסיום שצוינו על ידי הגדרת הגדרות החיתוך בפריט המדיה של הקלט. לדוגמה, כדי ליצור קליפ שמכיל רק את המדיה בין 10 שניות ל-20 שניות:
Kotlin
val inputMediaItem = MediaItem.Builder() .setUri(uri) .setClippingConfiguration( MediaItem.ClippingConfiguration.Builder() .setStartPositionMs(10_000) .setEndPositionMs(20_000) .build()) .build()
Java
MediaItem inputMediaItem = new MediaItem.Builder() .setUri(uri) .setClippingConfiguration( new MediaItem.ClippingConfiguration.Builder() .setStartPositionMs(10_000) .setEndPositionMs(20_000) .build()) .build();
רשימות עריכה של MP4
כדי לקצר את תהליך החיתוך, Transformer תומך ברשימות עריכה של MP4, וכך מאפשר עריכות יעילות יותר של חיתוך בלבד בלי לבצע המרה מלאה של הקידוד של הסרטון. השיטה הזו משתמשת בדגימות מקודדות קיימות וב'פרסומת לפני הסרטון' ברשימת העריכה, שמורה לנגן להתחיל את ההפעלה בנקודה ספציפית, וכך למעשה מדלגת על הפלח הראשוני הלא רצוי.
כדי לבצע עריכות של חיתוך בלבד במהירות גבוהה יותר, מתקשרים אל experimentalSetMp4EditListTrimEnabled(true).
Kotlin
Transformer.Builder(context) .experimentalSetMp4EditListTrimEnabled(true) .build()
Java
new Transformer.Builder(context) .experimentalSetMp4EditListTrimEnabled(true) .build();
חשוב לציין שלא כל נגני המדיה תומכים במיקום 'לפני הסרטון'. המשמעות היא שכאשר משתמשים בנגן כזה, ההפעלה של הקובץ תתחיל מההתחלה המוחלטת של הדגימה המקודדת, ללא קשר למידע ברשימת העריכה שאולי מציין נקודת התחלה שונה.
אופטימיזציה של קיצוצים
כדי להקטין את זמן האחזור של חיתוך תחילת הסרטון, מפעילים את האפשרות 'אופטימיזציה של חיתוך'.
Kotlin
Transformer.Builder(context) .experimentalSetTrimOptimizationEnabled(true) .build()
Java
new Transformer.Builder(context) .experimentalSetTrimOptimizationEnabled(true) .build();
כך הייצוא מהיר יותר כי המערכת מפענחת ומקודדת מחדש כמה שפחות מהסרטון, ואז משלבת את הנתונים המקודדים מחדש עם שאר הסרטון המקורי. האופטימיזציה מתבססת על היכולת לחבר חלק מקובץ הקלט עם פלט חדש ומקודד, כלומר פורמט הפלט של המקודד ופורמט הקלט חייבים להיות תואמים. לכן, לדוגמה, אם הקובץ נוצר במקור במכשיר עם הטמעה שונה של מקודד, סביר להניח שלא תהיה אפשרות להחיל את האופטימיזציה.
כדי שהאופטימיזציה תצליח, למקודד שמועבר ל-Transformer דרך EncoderFactory צריכות להיות רמה ופרופיל שתואמים לפורמט הקלט.
האופטימיזציה הזו פועלת רק עם קלט MP4 של נכס יחיד ללא אפקטים, למעט אפקטים של וידאו ללא פעולה וסיבובים שמתחלקים ב-90 מעלות. אם האופטימיזציה נכשלת, Transformer חוזר אוטומטית לייצוא רגיל ומדווח על התוצאה של האופטימיזציה ב-ExportResult.OptimizationResult.
אנחנו בודקים את הפונקציונליות הזו, ואנחנו צופים שהיא תהפוך ללא ניסיונית בגרסה עתידית.
עריכות סרטונים
EditedMediaItems יש רשימות של מעבדי אודיו ואפקטים של וידאו שאפשר להחיל לפי הסדר. הספרייה כוללת הטמעות של אפקטים בסרטונים לתרחישי שימוש נפוצים,
או שאפשר לכתוב אפקטים בהתאמה אישית ולהעביר אותם כשיוצרים פריטי מדיה ערוכים.
אפשר לשנות את קנה המידה של מדיה, וזה יכול להיות שימושי כדי לחסוך במשאבי עיבוד או ברוחב פס כשעובדים עם קלט ברזולוציה גבוהה מאוד, כמו סרטון באיכות 4K או 8K. לדוגמה, כדי לשנות את הגודל באופן יחסי לגובה של 480 פיקסלים:
Kotlin
EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(Effects( /* audioProcessors= */ listOf(), /* videoEffects= */ listOf(Presentation.createForHeight(480)) )).build()
Java
new EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(new Effects( /* audioProcessors= */ ImmutableList.of(), /* videoEffects= */ ImmutableList.of(Presentation.createForHeight(480)))) .build();
אפשרות אחרת היא לשנות את הגודל לפי פקטור נתון, למשל, כדי להקטין את הגודל בחצי:
Kotlin
val editedMediaItem = EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(Effects( /* audioProcessors= */ listOf(), /* videoEffects= */ listOf( ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build()) )).build()
Java
new EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(new Effects( /* audioProcessors= */ ImmutableList.of(), /* videoEffects= */ ImmutableList.of( new ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build()))) .build();
אפשר להגדיר רוטציה באותו אופן:
Kotlin
EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(Effects( /* audioProcessors= */ listOf(), /* videoEffects= */ listOf( ScaleAndRotateTransformation.Builder() .setRotationDegrees(90f) .build()) )).build()
Java
new EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(new Effects( /* audioProcessors= */ ImmutableList.of(), /* videoEffects= */ ImmutableList.of( new ScaleAndRotateTransformation.Builder().setRotationDegrees(90f).build()))) .build();
אפקטים מותאמים אישית לסרטונים
הקונסטרוקטור Effects מקבל רשימה של אפקטים של אודיו ווידאו להחלה.
באופן פנימי, מסגרת האפקטים של Transformer ממירה את רשימת האפקטים של הסרטון לרצף של תוכניות GL Shader שמוחלות לפי הסדר. במקרים מסוימים, מסגרת האפקטים יכולה להחיל כמה אפקטים באמצעות תוכנית הצללה אחת.
לדוגמה, תוכנית הצללה אחת יכולה להחיל כמה טרנספורמציות של מטריצות ברצף, מה שמשפר את היעילות והאיכות.
אפשר גם להשתמש ב-ExoPlayer כדי לראות תצוגה מקדימה של אפקטים בסרטונים באמצעות ExoPlayer.setVideoEffects. כדי לראות דוגמה לשימוש ב-API הזה, אפשר לעיין באפליקציית ההדגמה של האפקט.
אפליקציית ההדגמה כוללת דוגמאות לאפקטים מותאמים אישית של וידאו.
קלט של תמונה
מודל Transformer תומך בקלט של תמונות על ידי טיפול בהן כקליפים סטטיים. כדי להגדיר תמונה כמקור קלט:
יצירת
MediaItemבאמצעותMediaItem.Builder. מציינים את משך ההצגה של התמונה בסרטון הפלט באמצעות קריאה ל-setImageDurationMs.יוצרים
EditedMediaItemשעוטף אתMediaItem. מציינים את קצב הפריימים של הווידאו בסטרימינג שנוצר באמצעותEditedMediaItem.Builder#setFrameRate.
בדוגמה הבאה מוסבר איך להגדיר קלט של תמונה כדי ליצור סרטון באורך 5 שניות ב-30 פריימים לשנייה:
Kotlin
val imageMediaItem = MediaItem.Builder() .setUri(imageUri) .setImageDurationMs(5000) // 5 seconds .build() val editedImageItem = EditedMediaItem.Builder(imageMediaItem) .setFrameRate(30) // 30 frames per second .build()
Java
MediaItem imageMediaItem = new MediaItem.Builder() .setUri(imageUri) .setImageDurationMs(5000) // 5 seconds .build(); EditedMediaItem editedImageItem = new EditedMediaItem.Builder(imageMediaItem) .setFrameRate(30) // 30 frames per second .build();
עריכות אודיו
אפקטים של אודיו מיושמים על ידי הפעלה של רצף של AudioProcessor
מופעים על אודיו גולמי (PCM). ExoPlayer תומך בהעברת מעבדי אודיו אל DefaultAudioSink.Builder, מה שמאפשר לראות תצוגה מקדימה של עריכות אודיו.