טרנספורמציות

המרת קידוד בין פורמטים

כשיוצרים Transformer, אפשר לציין את פורמטי האודיו והווידאו של הפלט שרוצים ליצור. לדוגמה, הקוד הבא מראה איך להגדיר את 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(
        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 הזה, אפשר לעיין באפליקציית ההדגמה של האפקט.

אפליקציית ההדגמה כוללת דוגמאות לאפקטים מותאמים אישית של וידאו.

עריכות אודיו

אפקטים קוליים מיושמים על ידי הפעלה של רצף של AudioProcessorמופעים על אודיו גולמי (PCM). ‫ExoPlayer תומך בהעברת מעבדי אודיו אל DefaultAudioSink.Builder, מה שמאפשר לראות תצוגה מקדימה של עריכות אודיו.