البدء

يتضمّن بدء استخدام 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.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.

تفعيل الإصدار 8 من Java

إذا لم يتم تفعيلها بعد، عليك تفعيل إمكانية استخدام 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 عمله في الخلفية وينشر طلباته إلى طرق المستمع على سلسلة تعليمات التطبيق.

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

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