شروع کردن

شروع کار با Transformer شامل مراحل زیر است:

  1. Media3 Transformer را به عنوان یک وابستگی در پروژه خود اضافه کنید.
  2. یک EditedMediaItem بسازید که نشان دهنده رسانه برای پردازش و ویرایش برای اعمال آن است.
  3. یک Transformer بسازید که خروجی مورد نیاز و شنونده ای را برای رویدادهای تکمیل و خطا توصیف می کند.
  4. عملیات صادرات را شروع کنید و از EditedMediaItem برای ویرایش و یک مسیر خروجی عبور دهید. در حین صادرات، می توانید پیشرفت فعلی را پرس و جو کنید یا عملیات را لغو کنید.
  5. هنگام صادرات نهایی، خروجی را در صورت نیاز مدیریت کنید. به عنوان مثال، می توانید خروجی را در برنامه دیگری به اشتراک بگذارید یا آن را در یک سرور آپلود کنید.

برای جزئیات بیشتر در مورد این مراحل به ادامه مطلب بروید و برای مثال کامل، TransformerActivity در برنامه نمایشی ترانسفورماتور ببینید.

Media3 Transformer را به عنوان یک وابستگی اضافه کنید

ساده ترین راه برای شروع استفاده از Transformer اضافه کردن وابستگی های gradle به کتابخانه در فایل build.gradle ماژول برنامه است:

کاتلین

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

شیار

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

که در آن 1.5.0 نسخه ترجیحی شماست. آخرین نسخه را می توانید با مراجعه به یادداشت های انتشار پیدا کنید.

اطلاعات بیشتر در مورد ماژول های کتابخانه موجود را می توانید در صفحه Google Maven AndroidX Media3 بیابید.

پشتیبانی از جاوا 8 را روشن کنید

اگر قبلاً فعال نیست، باید پشتیبانی از جاوا 8 را در همه فایل‌های build.gradle که به Transformer وابسته هستند، با افزودن موارد زیر به بخش android فعال کنید:

compileOptions {
  targetCompatibility JavaVersion.VERSION_1_8
}

یک تحول را شروع کنید

در اینجا مثالی از ایجاد یک EditedMediaItem برای حذف صدا برای یک فایل ورودی، سپس ایجاد و پیکربندی یک نمونه Transformer برای صادر کردن ویدیوی H.265/HEVC و خروجی نتیجه به outputPath شده است.

کاتلین

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)

جاوا

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 اجرا کنید، اما صادرات همزمان با همان نمونه پشتیبانی نمی شود.

نکته ای در مورد نخ زنی

به نمونه های ترانسفورماتور باید از یک رشته برنامه دسترسی داشت و متدهای شنونده در همان رشته فراخوانی می شوند. در اکثر موارد، موضوع برنامه فقط می تواند موضوع اصلی برنامه باشد. در داخل، Transformer کار خود را در پس‌زمینه انجام می‌دهد و تماس‌های خود را با متدهای شنونده در رشته برنامه ارسال می‌کند.

به رویدادها گوش دهید

روش start ناهمزمان است. بلافاصله برمی‌گردد و برنامه از طریق شنونده که به سازنده Transformer ارسال می‌شود، از رویدادها مطلع می‌شود.

کاتلین

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)
  }
}

جاوا

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 می تواند برای به روز رسانی نوار پیشرفت پیاده سازی شود.

کاتلین

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)
        }
      }
    }
)

جاوا

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 لغو کنید. منابعی مانند کدک‌های ویدیوی سخت‌افزاری، به‌ویژه در دستگاه‌های پایین‌رده محدود هستند، بنابراین انجام این کار برای آزاد کردن منابع در صورت عدم نیاز به خروجی بسیار مهم است.