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

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

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

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

إضافة المحوِّل Media3 كتبعية

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

Kotlin

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

رائع

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

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

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

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