البدء

يتألف بدء استخدام Transformer من الخطوات التالية:

  1. أضِف Media3 Transformer كتبعية في مشروعك.
  2. أنشئ EditedMediaItem يمثّل الوسائط المطلوب معالجتها والتعديلات التي سيتم تطبيقها عليها.
  3. أنشئ Transformer، مع وصف الناتج المطلوب ومستمع لأحداث الإكمال والخطأ.
  4. ابدأ عملية التصدير، مع تمرير EditedMediaItem للتعديل ومسار الإخراج. أثناء التصدير، يمكنك الاستعلام عن مستوى التقدّم الحالي أو إلغاء العملية.
  5. عند انتهاء عملية التصدير، يمكنك التعامل مع الناتج حسب الحاجة. على سبيل المثال، يمكنك مشاركة الناتج مع تطبيق آخر أو تحميله إلى خادم.

يمكنك قراءة المزيد من التفاصيل حول هذه الخطوات، والاطّلاع على TransformerActivity في تطبيق Transformer التجريبي للحصول على مثال كامل.

إضافة Media3 Transformer كتبعية

أسهل طريقة لبدء استخدام Transformer هي إضافة تبعيات Gradle في المكتبة في ملف build.gradle الخاص بوحدة تطبيقك:

Kotlin

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

أنيق

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

حيث يمثّل 1.11.1 الإصدار المفضّل لديك. يمكن العثور على أحدث إصدار من خلال الاطّلاع على ملاحظات الإصدار.

يمكنك الاطّلاع على مزيد من المعلومات حول وحدات المكتبة المتاحة في صفحة Google Maven AndroidX Media3.

تفعيل استخدام Java 8

إذا لم تكن ميزة Java 8 مفعَّلة، عليك تفعيلها في جميع ملفات build.gradle التي تعتمد على Transformer من خلال إضافة ما يلي إلى قسم 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 نفسه، ولكن لا يمكن إجراء عمليات تصدير متزامنة باستخدام المثيل نفسه.

للحصول على معلومات حول إنشاء الوسائط من خلال دمج عدة مدخلات معًا، يُرجى الاطّلاع على تعديل مواد عرض متعددة.

ملاحظة حول سلاسل المحادثات

يجب الوصول إلى نُسخ Transformer من سلسلة محادثات واحدة للتطبيق، ويتم استدعاء طرق المستمع في سلسلة المحادثات نفسها. في معظم الحالات، يمكن أن تكون سلسلة تعليمات التطبيق هي سلسلة التعليمات الرئيسية للتطبيق. داخليًا، تؤدي واجهة Transformer عملها في الخلفية وتنشر طلباتها إلى طرق المستمع في سلسلة محادثات التطبيق.

الاستماع إلى الأحداث

الطريقة start غير متزامنة. ويتم عرضها على الفور ويتم إشعار التطبيق بالأحداث من خلال المستمع الذي تم تمريره إلى أداة إنشاء 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. تكون الموارد مثل برامج ترميز الفيديو للأجهزة محدودة، خاصةً على الأجهزة المنخفضة المواصفات، لذا من المهم إجراء ذلك لإخلاء الموارد إذا لم تكن هناك حاجة إلى الناتج.