איך מתחילים?

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

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

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

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

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

Kotlin

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

מגניב

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

כאשר 1.4.0 היא הגרסה המועדפת עליכם. הגרסה העדכנית ביותר יכולה להיות נמצאו לפי מאמרי העזרה של הגרסה הערות.

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

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

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

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

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

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