البدء

يتألف البدء في استخدام 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.10.0")
implementation("androidx.media3:media3-effect:1.10.0")
implementation("androidx.media3:media3-common:1.10.0")

أنيق

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

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

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