تنظيم صفحاتك في مجموعات
يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.
يتضمّن البدء في استخدام Transformer الخطوات التالية:
أضِف Media3 Transformer كعنصر تابع في مشروعك.
أنشئ EditedMediaItem يمثّل الوسائط المطلوب معالجتها والتعديلات المطلوب تطبيقها عليها.
أنشئ Transformer، واشرح فيه الناتج المطلوب وبرنامج معالجة
لأحداث الإكمال والأخطاء.
ابدأ عملية التصدير، مع تمرير EditedMediaItem لتعديل مسار الإخراج. أثناء عملية التصدير، يمكنك الاستعلام عن مستوى التقدّم الحالي أو إلغاء العملية.
عند الانتهاء من عملية التصدير، تعامَل مع الناتج حسب الحاجة. على سبيل المثال، يمكنك مشاركة الناتج مع تطبيق آخر أو تحميله إلى خادم.
يمكنك الاطّلاع على مزيد من التفاصيل حول هذه الخطوات في ما يلي، كما يمكنك الاطّلاع على TransformerActivity في تطبيق العرض التوضيحي لأداة التحويل للحصول على مثال كامل.
إضافة Media3 Transformer كعنصر تابع
أسهل طريقة لبدء استخدام Transformer هي إضافة ملحقات Gradle
إلى المكتبة في ملف build.gradle الخاص بوحدة تطبيقك:
إذا لم يتم تفعيلها بعد، عليك تفعيل إمكانية استخدام Java 8 في جميع ملفات build.gradle
التي تعتمد على Transformer من خلال إضافة ما يلي إلى القسم android:
في ما يلي مثال على إنشاء EditedMediaItem لإزالة الصوت من ملف إدخال، ثم إنشاء وضبط مثيل Transformer لتصدير فيديو H.265/HEVC، وإخراج النتيجة إلى outputPath.
لمزيد من المعلومات حول عناصر الوسائط، يمكنك الاطّلاع على صفحة عناصر الوسائط في ExoPlayer. يمكن أن يكون الإدخال بثًا متواصلاً أو متكيّفًا، ولكن يكون الإخراج دائمًا بثًا متواصلاً. بالنسبة إلى المدخلات التكيّفية، يتم دائمًا اختيار المقاطع الصوتية ذات أعلى دقة لإجراء عملية التحويل. يمكن أن يكون الإدخال بأي تنسيق حاوية متوافق مع ExoPlayer، ولكن يكون الإخراج دائمًا ملف MP4.
يمكنك تنفيذ عمليات تصدير متعددة بالتسلسل على مثيل Transformer نفسه، ولكن لا تتوفّر عمليات تصدير متزامنة باستخدام المثيل نفسه.
ملاحظة حول سلاسل المحادثات
يجب الوصول إلى مثيلات المحوّل من سلسلة محادثات تطبيق واحدة، ويتم استدعاء طرق المستمع على سلسلة المحادثات نفسها. في معظم الحالات، يمكن أن تكون سلسلة تنفيذ التطبيق هي سلسلة التنفيذ الرئيسية للتطبيق. داخليًا، ينفّذ Transformer عمله في الخلفية وينشر طلباته إلى طرق المستمع في سلسلة تعليمات التطبيق.
الاستماع إلى الأحداث
الطريقة start غير متزامنة. ويتم عرضها على الفور، ويتم إعلام التطبيق بالأحداث من خلال أداة المعالجة التي تم تمريرها إلى أداة إنشاء Transformer.
يتضمّن ExportResult معلومات حول ملف الإخراج، بما في ذلك حجم الملف ومتوسط معدلات نقل البيانات للصوت والفيديو، حسب الاقتضاء.
تلقّي إشعارات بشأن حالة الطلب
اتّصِل بالرقم Transformer.getProgress للاستعلام عن مستوى التقدّم الحالي في عملية تحويل. تشير القيمة التي تم إرجاعها إلى حالة التقدّم. إذا كانت حالة التقدم هي PROGRESS_STATE_AVAILABLE، سيتم تعديل قيمة ProgressHolder المقدَّمة لتصبح نسبة التقدم الحالية. يوضّح المثال التالي كيفية الاستعلام بشكل دوري عن مدى تقدّم عملية تحويل، حيث يمكن تنفيذ الطريقة updateProgressInUi لتعديل شريط التقدّم.
إذا اختار المستخدم الخروج من عملية تصدير، عليك إلغاء عملية التصدير باستخدام Transformer.cancel. تكون الموارد، مثل برامج الترميز والفيديو للأجهزة، محدودة، خاصةً على الأجهزة المنخفضة المواصفات، لذا من المهم إجراء ذلك لإتاحة الموارد إذا لم تكن هناك حاجة إلى الإخراج.
تاريخ التعديل الأخير: 2025-08-27 (حسب التوقيت العالمي المتفَّق عليه)
[[["يسهُل فهم المحتوى.","easyToUnderstand","thumb-up"],["ساعَدني المحتوى في حلّ مشكلتي.","solvedMyProblem","thumb-up"],["غير ذلك","otherUp","thumb-up"]],[["لا يحتوي على المعلومات التي أحتاج إليها.","missingTheInformationINeed","thumb-down"],["الخطوات معقدة للغاية / كثيرة جدًا.","tooComplicatedTooManySteps","thumb-down"],["المحتوى قديم.","outOfDate","thumb-down"],["ثمة مشكلة في الترجمة.","translationIssue","thumb-down"],["مشكلة في العيّنات / التعليمات البرمجية","samplesCodeIssue","thumb-down"],["غير ذلك","otherDown","thumb-down"]],["تاريخ التعديل الأخير: 2025-08-27 (حسب التوقيت العالمي المتفَّق عليه)"],[],[],null,["Getting started with `Transformer` consists of the following steps:\n\n1. Add Media3 Transformer as a dependency in your project.\n2. Build an `EditedMediaItem` representing the media to process and edits to apply to it.\n3. Build a `Transformer`, describing the required output and a listener for completion and error events.\n4. Start the export operation, passing in the `EditedMediaItem` to edit and an output path. During export, you can query the current progress or cancel the operation.\n5. When exporting finishes, handle the output as needed. For example, you can share the output to another app or upload it to a server.\n\nRead on for more detail about these steps, and see `TransformerActivity` in the\n[transformer demo\napp](https://github.com/androidx/media/tree/release/demos/transformer) for a\ncomplete example.\n\nAdd Media3 Transformer as a dependency\n\nThe easiest way to get started using Transformer is to add gradle dependencies\non the library in the `build.gradle` file of your app module: \n\nKotlin \n\n```kotlin\nimplementation(\"androidx.media3:media3-transformer:1.8.0\")\nimplementation(\"androidx.media3:media3-effect:1.8.0\")\nimplementation(\"androidx.media3:media3-common:1.8.0\")\n```\n\nGroovy \n\n```groovy\nimplementation \"androidx.media3:media3-transformer:1.8.0\"\nimplementation \"androidx.media3:media3-effect:1.8.0\"\nimplementation \"androidx.media3:media3-common:1.8.0\"\n```\n\nwhere 1.8.0 is your preferred version. The latest version can be\nfound by consulting the [release\nnotes](https://github.com/androidx/media/tree/release/RELEASENOTES.md).\n| **Important:** If you're using any other Media3 modules, including Media3 ExoPlayer, they must all be the same version.\n\nMore information on the library modules that are available can be found on the\n[Google Maven AndroidX Media3\npage](https://maven.google.com/web/index.html?q=media3).\n\nTurn on Java 8 support\n\nIf not enabled already, you need to turn on Java 8 support in all `build.gradle`\nfiles that depend on Transformer by adding the following to the `android`\nsection: \n\n compileOptions {\n targetCompatibility JavaVersion.VERSION_1_8\n }\n\nStart a transformation\n\nHere's an example of creating an `EditedMediaItem` to remove audio for an input\nfile, then creating and configuring a `Transformer` instance to export\nH.265/HEVC video, outputting the result to `outputPath`. \n\nKotlin \n\n```kotlin\nval inputMediaItem = MediaItem.fromUri(\"path_to_input_file\")\nval editedMediaItem =\n EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build()\nval transformer = Transformer.Builder(context)\n .setVideoMimeType(MimeTypes.VIDEO_H265)\n .addListener(transformerListener)\n .build()\ntransformer.start(editedMediaItem, outputPath)\n```\n\nJava \n\n```java\nMediaItem inputMediaItem = MediaItem.fromUri(\"path_to_input_file\");\nEditedMediaItem editedMediaItem =\n new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build();\nTransformer transformer =\n new Transformer.Builder(context)\n .setVideoMimeType(MimeTypes.VIDEO_H265)\n .addListener(transformerListener)\n .build();\ntransformer.start(editedMediaItem, outputPath);\n```\n\n\u003cbr /\u003e\n\nFor more information about media items, see the [ExoPlayer media items\npage](../exoplayer/media-items). The input can be a progressive or an adaptive\nstream, but the output is always a progressive stream. For adaptive inputs, the\nhighest-resolution tracks are always selected for the transformation. The input\ncan be of any container format [supported](/media/media3/transformer/supported-formats) by ExoPlayer, but\nthe output is always an MP4 file.\n\nYou can execute multiple export operations sequentially on the same\n`Transformer` instance, but concurrent exports with the same instance are not\nsupported.\n| **Note:** Support for generating media by composing together multiple inputs is planned for future versions of Transformer.\n\nA note on threading\n\nTransformer instances must be accessed from a single application thread, and the\nlistener methods are called on the same thread. For the majority of cases, the\napplication thread can just be the main thread of the application. Internally,\nTransformer does its work in the background and posts its calls to listener\nmethods on the application thread.\n\nListen to events\n\nThe `start` method is asynchronous. It returns immediately and the app is\nnotified of events through the listener passed to the `Transformer` builder. \n\nKotlin \n\n```kotlin\nval transformerListener: Transformer.Listener =\n object : Transformer.Listener {\n override fun onCompleted(composition: Composition, result: ExportResult) {\n playOutput()\n }\n\n override fun onError(composition: Composition, result: ExportResult,\n exception: ExportException) {\n displayError(exception)\n }\n}\n```\n\nJava \n\n```java\nTransformer.Listener transformerListener =\n new Transformer.Listener() {\n @Override\n public void onCompleted(Composition composition, ExportResult result) {\n playOutput();\n }\n\n @Override\n public void onError(Composition composition, ExportResult result,\n ExportException exception) {\n displayError(exception);\n }\n };\n```\n\n\u003cbr /\u003e\n\n`ExportResult` includes information about the output file, including the file\nsize and average bitrates for audio and video, as applicable.\n\nGet progress updates\n\nCall `Transformer.getProgress` to query the current progress of a\ntransformation. The returned value indicates the progress state. If the progress\nstate is `PROGRESS_STATE_AVAILABLE`, then the provided `ProgressHolder` is\nupdated with the current progress percentage. The following example shows how to\nperiodically query the progress of a transformation, where the\n`updateProgressInUi` method can be implemented to update a progress bar. \n\nKotlin \n\n```kotlin\ntransformer.start(inputMediaItem, outputPath)\nval progressHolder = ProgressHolder()\nmainHandler.post(\n object : Runnable {\n override fun run() {\n val progressState: @ProgressState Int = transformer.getProgress(progressHolder)\n updateProgressInUi(progressState, progressHolder)\n if (progressState != Transformer.PROGRESS_STATE_NOT_STARTED) {\n mainHandler.postDelayed(/* r= */this, /* delayMillis= */500)\n }\n }\n }\n)\n```\n\nJava \n\n```java\ntransformer.start(inputMediaItem, outputPath);\nProgressHolder progressHolder = new ProgressHolder();\nmainHandler.post(\n new Runnable() {\n @Override\n public void run() {\n @Transformer.ProgressState int progressState = transformer.getProgress(progressHolder);\n updateProgressInUi(progressState, progressHolder);\n if (progressState != PROGRESS_STATE_NOT_STARTED) {\n mainHandler.postDelayed(/* r= */ this, /* delayMillis= */ 500);\n }\n }\n });\n```\n\n\u003cbr /\u003e\n\nCancel a transformation\n\nIf the user chooses to back out of an export flow, cancel the export operation\nwith `Transformer.cancel`. Resources like hardware video codecs are limited,\nespecially on lower-end devices, so it's important to do this to free up\nresources if the output isn't needed."]]