الخطوات الأولى

تتألف عملية البدء في استخدام 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.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.

تفعيل ميزة "التوافق مع Java 8"

إذا لم يكن مفعّلاً، عليك تفعيل دعم Java 8 في جميع build.gradle الملفات التي تعتمد على Transformer من خلال إضافة ما يلي إلى القسم android:

compileOptions {
  targetCompatibility JavaVersion.VERSION_1_8
}

بدء عملية تحويل

في ما يلي مثال على إنشاء EditedMediaItem لإزالة الصوت من ملف input ، ثم إنشاء مثيل 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 عمله في الخلفية وينشر طلبات الاستماع إلى methods في سلسلة محادثات التطبيق.

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

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