איך מתחילים?

כדי להתחיל להשתמש ב-Transformer, מבצעים את השלבים הבאים:

  1. מוסיפים את Media3 Transformer כתלות בפרויקט.
  2. פיתוח EditedMediaItem שמייצג את המדיה לצורך עיבוד ועריכות חלות עליו.
  3. יוצרים Transformer, מתארים את הפלט הנדרש ומגדירים מאזין לאירועי השלמה ושגיאה.
  4. מתחילים את פעולת הייצוא, מעבירים את EditedMediaItem לעריכה ונתיב פלט. במהלך הייצוא, אפשר לשלוח שאילתה לגבי ההתקדמות הנוכחית או לבטל את הפעולה.
  5. בסיום הייצוא, מטפלים בפלט לפי הצורך. לדוגמה, אפשר לשתף את הפלט עם אפליקציה אחרת או להעלות אותו לשרת.

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

הוספת Media3 Transformer כיחס תלות

הדרך הקלה ביותר להתחיל להשתמש ב-Transformer היא להוסיף יחסי תלות של Gradle לספרייה בקובץ build.gradle של מודול האפליקציה:

Kotlin

implementation("androidx.media3:media3-transformer:1.4.1")
implementation("androidx.media3:media3-effect:1.4.1")
implementation("androidx.media3:media3-common:1.4.1")

Groovy

implementation "androidx.media3:media3-transformer:1.4.1"
implementation "androidx.media3:media3-effect:1.4.1"
implementation "androidx.media3:media3-common:1.4.1"

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

מידע נוסף על המודולים הזמינים בספרייה זמין בדף Google Maven AndroidX Media3.

הפעלת התמיכה ב-Java 8

אם עדיין לא הפעלתם את התמיכה ב-Java 8, צריך להוסיף את הקטע הבא לקטע android בכל הקבצים build.gradle שמסתמכים על Transformer:

compileOptions {
  targetCompatibility JavaVersion.VERSION_1_8
}

התחלת טרנספורמציה

דוגמה ליצירה של EditedMediaItem כדי להסיר אודיו של קלט ואז יצירה והגדרה של מכונה Transformer לייצוא סרטון H.265/HEVC, פלט את התוצאה אל outputPath.

Kotlin

val inputMediaItem = MediaItem.fromUri("path_to_input_file")
val editedMediaItem =
    EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build()
val transformer = Transformer.Builder(context)
    .setVideoMimeType(MimeTypes.VIDEO_H265)
    .addListener(transformerListener)
    .build()
transformer.start(editedMediaItem, outputPath)

Java

MediaItem inputMediaItem = MediaItem.fromUri("path_to_input_file");
EditedMediaItem editedMediaItem =
    new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build();
Transformer transformer =
    new Transformer.Builder(context)
        .setVideoMimeType(MimeTypes.VIDEO_H265)
        .addListener(transformerListener)
        .build();
transformer.start(editedMediaItem, outputPath);

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

אפשר להריץ כמה פעולות ייצוא ברצף באותה מכונה של Transformer, אבל אי אפשר לייצא בו-זמנית באותה מכונה.

הערה לגבי שימוש בשרשור

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

האזנה לאירועים

השיטה start היא אסינכרונית. הפונקציה מחזירה תשובה באופן מיידי, והאפליקציה מקבלת התראות על אירועים דרך ה-listener שהוענק ל-builder של Transformer.

Kotlin

val transformerListener: Transformer.Listener =
    object : Transformer.Listener {
  override fun onCompleted(composition: Composition, result: ExportResult) {
    playOutput()
  }

  override fun onError(composition: Composition, result: ExportResult,
                       exception: ExportException) {
    displayError(exception)
  }
}

Java

Transformer.Listener transformerListener =
    new Transformer.Listener() {
      @Override
      public void onCompleted(Composition composition, ExportResult result) {
        playOutput();
      }

      @Override
      public void onError(Composition composition, ExportResult result,
          ExportException exception) {
        displayError(exception);
      }
    };

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

קבלת עדכונים על ההתקדמות

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

Kotlin

transformer.start(inputMediaItem, outputPath)
val progressHolder = ProgressHolder()
mainHandler.post(
    object : Runnable {
      override fun run() {
        val progressState: @ProgressState Int = transformer.getProgress(progressHolder)
        updateProgressInUi(progressState, progressHolder)
        if (progressState != Transformer.PROGRESS_STATE_NOT_STARTED) {
          mainHandler.postDelayed(/* r= */this,  /* delayMillis= */500)
        }
      }
    }
)

Java

transformer.start(inputMediaItem, outputPath);
ProgressHolder progressHolder = new ProgressHolder();
mainHandler.post(
    new Runnable() {
      @Override
      public void run() {
        @Transformer.ProgressState int progressState = transformer.getProgress(progressHolder);
        updateProgressInUi(progressState, progressHolder);
        if (progressState != PROGRESS_STATE_NOT_STARTED) {
          mainHandler.postDelayed(/* r= */ this, /* delayMillis= */ 500);
        }
      }
    });

ביטול טרנספורמציה

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