تحويل الترميز بين التنسيقات
يمكنك تحديد تنسيقات الإخراج الصوتي والفيديو التي تريد إنتاجها عند إنشاء Transformer. على سبيل المثال، يوضح الرمز التالي كيفية ضبط المحوّل لإخراج فيديو H.264/AVC وصوت AAC:
Kotlin
Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H264) .setAudioMimeType(MimeTypes.AUDIO_AAC) .build()
Java
new Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H264) .setAudioMimeType(MimeTypes.AUDIO_AAC) .build();
وإذا كان تنسيق وسائط الإدخال يتطابق مع إعدادات الصوت أو الفيديو، سيتم تبديل "المحوّل" تلقائيًا إلى تحويل الصوت إلى نص، أي نسخ العيّنات المضغوطة من حاوية الإدخال إلى حاوية الإخراج بدون تعديل. فهذا يتجنب التكلفة الحاسوبية وفقدان الجودة المحتمل لفك الترميز وإعادة الترميز بالتنسيق نفسه.
إزالة الصوت أو الفيديو
إزالة الصوت أو الفيديو باستخدام EditedMediaItem.Builder
، على سبيل المثال:
Kotlin
EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build()
Java
new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build();
قطع مقطع
يمكنك إزالة أي وسائط خارج الطوابع الزمنية المحدّدة للبداية والنهاية من خلال ضبط إعدادات الاقتصاص على عنصر وسائط الإدخال. على سبيل المثال، لإنشاء مقطع يحتوي فقط على وسائط تتراوح مدّتها بين 10 ثوانٍ و20 ثانية:
Kotlin
val inputMediaItem = MediaItem.Builder() .setUri(uri) .setClippingConfiguration( ClippingConfiguration.Builder() .setStartPositionMs(10_000) .setEndPositionMs(20_000) .build()) .build()
Java
MediaItem inputMediaItem = new MediaItem.Builder() .setUri(uri) .setClippingConfiguration( new MediaItem.ClippingConfiguration.Builder() .setStartPositionMs(10_000) .setEndPositionMs(20_000) .build()) .build();
تحسين عمليات القطع
لتقليل وقت الاستجابة لقطع بداية الفيديو، يجب تفعيل ميزة تحسين القطع.
Kotlin
Transformer.Builder(context) .experimentalSetTrimOptimizationEnabled(true) .build()
Java
new Transformer.Builder(context) .experimentalSetTrimOptimizationEnabled(true) .build();
يؤدي ذلك إلى تسريع عملية التصدير من خلال فك الترميز وإعادة ترميز أقل قدر ممكن من محتوى الفيديو، ثم دمج البيانات المُعاد ترميزها مع باقي الفيديو الأصلي. يعتمد التحسين على إمكانية دمج جزء من ملف الإدخال
باستخدام إخراج تم ترميزه حديثًا، ما يعني أنّ تنسيق الإخراج في برنامج الترميز
وتنسيق الإدخال يجب أن يكونا متوافقَين. على سبيل المثال، إذا تم إنشاء الملف في الأصل على جهاز بتطبيق برنامج ترميز مختلف، من المرجح ألا تتمكن من تطبيق التحسين.
لكي تنجح عملية التحسين، يجب أن يحتوي برنامج الترميز الذي يتم تقديمه إلى Transformer عبر EncoderFactory
على مستوى وملف شخصي متوافقَين مع تنسيق الإدخال.
لا يعمل هذا التحسين إلا مع إدخالات MP4 لمادة عرض واحدة بدون أي تأثيرات، باستثناء
أي تأثيرات فيديو تشغيلية وعمليات تدوير قابلة للقسمة على 90 درجة. إذا تعذّر التحسين، يعود Transformer تلقائيًا إلى التصدير العادي، ويُبلغ عن نتيجة التحسين في ExportResult.OptimizationResult
.
نحن نتحقق من صحة هذه الوظيفة ونتوقع أن تصبح غير تجريبية في إصدار لاحق.
تعديلات الفيديوهات
EditedMediaItems
لديه قوائم بمعالجات الصوت وتأثيرات الفيديو المطلوب تطبيقها بالترتيب. تتضمن المكتبة تنفيذ تأثيرات الفيديو لحالات الاستخدام الشائعة،
أو يمكنك كتابة تأثيرات مخصّصة وتمريرها عند إنشاء عناصر وسائط
معدَّلة.
يمكنك إعادة ضبط حجم الوسائط، ما يفيد في توفير موارد المعالجة أو معدّل نقل البيانات عند التعامل مع مدخلات ذات دقة عالية للغاية، مثل فيديو بدقة 4k أو 8K. على سبيل المثال، لضبط الحجم بالتناسب إلى ارتفاع 480 بكسل:
Kotlin
EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(Effects( /* audioProcessors= */ listOf(), /* videoEffects= */ listOf(Presentation.createForHeight(480)) )).build()
Java
new EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(new Effects( /* audioProcessors= */ ImmutableList.of(), /* videoEffects= */ ImmutableList.of(Presentation.createForHeight(480)))) .build();
وبدلاً من ذلك، يمكنك القياس حسب عامل معيّن، على سبيل المثال، لخفض الحجم إلى النصف:
Kotlin
val editedMediaItem = EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(Effects( /* audioProcessors= */ listOf(), /* videoEffects= */ listOf( ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build()) )).build()
Java
new EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(new Effects( /* audioProcessors= */ ImmutableList.of(), /* videoEffects= */ ImmutableList.of( new ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build()))) .build();
يمكنك ضبط التدوير بالطريقة نفسها:
Kotlin
EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(Effects( /* audioProcessors= */ listOf(), /* videoEffects= */ listOf( ScaleAndRotateTransformation.Builder() .setRotationDegrees(90f) .build()) )).build()
Java
new EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects(new Effects( /* audioProcessors= */ ImmutableList.of(), /* videoEffects= */ ImmutableList.of( new ScaleAndRotateTransformation.Builder().setRotationDegrees(90f).build()))) .build();
تأثيرات الفيديو المخصّصة
تقبل الدالة الإنشائية Effects
قائمة بتأثيرات الصوت والفيديو لتطبيقها.
داخليًا، يحوّل إطار عمل تأثيرات التحويل قائمة تأثيرات الفيديو
إلى سلسلة من برامج تظليل GL التي يتم تطبيقها بالترتيب. في بعض الحالات، يمكن لإطار التأثيرات
تطبيق تأثيرات متعددة باستخدام برنامج تظليل واحد.
على سبيل المثال، يمكن لبرنامج مظلل واحد تطبيق عدة تحويلات
متتالية في المصفوفات، مما يحسن الكفاءة والجودة.
يمكن أيضًا معاينة تأثيرات الفيديو في ExoPlayer باستخدام ExoPlayer.setVideoEffects
.
يتضمّن تطبيق العرض التوضيحي أمثلة على تأثيرات الفيديو المخصّصة.
تعديلات الصوت
يتم تنفيذ التأثيرات الصوتية من خلال تطبيق سلسلة من مثيلات AudioProcessor
على الصوت الأولي (PCM). يدعم ExoPlayer تمرير معالجات الصوت إلى DefaultAudioSink.Builder
، ما يسمح بمعاينة تعديلات الصوت.