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

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

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

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

הסרת אודיו או וידאו

הסרת אודיו או וידאו באמצעות 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();

מתבצעת אופטימיזציה של הגימור

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

Kotlin

Transformer.Builder(context)
    .experimentalSetTrimOptimizationEnabled(true)
    .build()

Java

new Transformer.Builder(context)
    .experimentalSetTrimOptimizationEnabled(true)
    .build();

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

האופטימיזציה הזו פועלת רק בקלט MP4 עם נכס יחיד, ללא אפקטים אין אפקטים של וידאו הפעלה וסיבובים שניתנים לחלוקה ב-90 מעלות. אם האופטימיזציה נכשל, הטרנספורמר חוזר אוטומטית לייצוא הרגיל, ומדווח תוצאת האופטימיזציה ב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();

אפקטים בהתאמה אישית לסרטון

ה-constructor של Effects מקבל רשימה של אפקטים של אודיו ושל וידאו שאפשר להשתמש בהם. מסגרת האפקטים של Transformer ממירה באופן פנימי את רשימת האפקטים לווידאו לרצף של תוכנות הצללה (shader) GL שמופעלות לפי הסדר. במקרים מסוימים, באמצעות תוכנת ההצללה יש אפשרות להשתמש במספר אפקטים. לדוגמה, תוכנית של תוכנת ההצללה (shader) יכולה להחיל מספר מטריצה ברצף טרנספורמציות, כדי לשפר את היעילות והאיכות.

אפשר להשתמש באפקטים של וידאו גם בתצוגה מקדימה ב-ExoPlayer, באמצעות ExoPlayer.setVideoEffects

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

עריכות אודיו

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