استخدام مسارات الوسائط

يمثّل الرمز MediaTrack مقطعًا صوتيًا من الوسائط، يمكن أن يكون بثًا صوتيًا أو فيديو بثًا أو نصًا (مثل مقاطع ترجمة وشرح). يمكن لتطبيقك تجميع مقاطع الصوتية من الوسائط وتصميمها وتفعيلها.

إعداد مقطع صوتي

يمكنك تهيئة مقطع صوتي وتعيين رقم تعريف فريد له. تنشئ التعليمة البرمجية التالية مسارًا نصيًا باللغة الإنجليزية ومسارًا نصيًا فرنسيًا ومسارًا صوتيًا فرنسيًا، ويكون لكل منها معرّف خاص به:

كوتلين
val englishSubtitle = MediaTrack.Builder(1 /* ID */, MediaTrack.TYPE_TEXT)
    .setName("English Subtitle")
    .setSubtype(MediaTrack.SUBTYPE_SUBTITLES)
    .setContentId("https://some-url/caption_en.vtt")
    /* language is required for subtitle type but optional otherwise */
    .setLanguage("en-US")
    .build()

val frenchSubtitle = MediaTrack.Builder(2, MediaTrack.TYPE_TEXT)
    .setName("French Subtitle")
    .setSubtype(MediaTrack.SUBTYPE_SUBTITLES)
    .setContentId("https://some-url/caption_fr.vtt")
    .setLanguage("fr")
    .build()

val frenchAudio = MediaTrack.Builder(3, MediaTrack.TYPE_AUDIO)
    .setName("French Audio")
    .setContentId("trk0001")
    .setLanguage("fr")
    .build()
Java
MediaTrack englishSubtitle = new MediaTrack.Builder(1 /* ID */,
MediaTrack.TYPE_TEXT)
  .setName("English Subtitle")
  .setSubtype(MediaTrack.SUBTYPE_SUBTITLES)
  .setContentId("https://some-url/caption_en.vtt")
  /* language is required for subtitle type but optional otherwise */
  .setLanguage("en-US")
  .build();

MediaTrack frenchSubtitle = new MediaTrack.Builder(2, MediaTrack.TYPE_TEXT)
  .setName("French Subtitle")
  .setSubtype(MediaTrack.SUBTYPE_SUBTITLES)
  .setContentId("https://some-url/caption_fr.vtt")
  .setLanguage("fr")
  .build();

MediaTrack frenchAudio = new MediaTrack.Builder(3, MediaTrack.TYPE_AUDIO)
  .setName("French Audio")
  .setContentId("trk0001")
  .setLanguage("fr")
  .build();

تجميع الأغاني

يمكنك تجميع عدة مقاطع صوتية في عنصر وسائط، ويتمثل في العلامة MediaInfo. يأخذ مثيل MediaInfo مجموعة من المسارات ويجمّع معلومات أخرى حول عنصر الوسائط. بناءً على المثال، يمكن لتطبيقك إضافة مسارات الوسائط الثلاثة هذه إلى عنصر وسائط من خلال تمرير قائمة بهذه المسارات الثلاثة إلى MediaInfo.Builder.setMediaTracks(List). يحتاج تطبيقك إلى ربط المسارات في MediaInfo بهذه الطريقة قبل تحميل الوسائط إلى جهاز الاستقبال.

كوتلين
val tracks: MutableList<MediaTrack> = ArrayList<MediaTrack>()
tracks.add(englishSubtitle)
tracks.add(frenchSubtitle)
tracks.add(frenchAudio)
val mediaInfo = MediaInfo.Builder(url)
    .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
    .setContentType(getContentType())
    .setMetadata(getMetadata())
    .setMediaTracks(tracks)
    .build()
Java
List tracks = new ArrayList();
tracks.add(englishSubtitle);
tracks.add(frenchSubtitle);
tracks.add(frenchAudio);
MediaInfo mediaInfo = MediaInfo.Builder(url)
  .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
  .setContentType(getContentType())
  .setMetadata(getMetadata())
  .setMediaTracks(tracks)
  .build();

إزالة قنوات الإصدار

لإزالة كل المقاطع الصوتية من الوسائط الحالية (مثل إيقاف الترجمة الثلاثة في المثال)، انقر على الرمز MediaInfo.Builder.setMediaTracks(List) واختَر قائمة فارغة من المعرّفات.

تعديل الأغاني

يمكن لتطبيقك تفعيل مقطع صوتي واحد أو أكثر كان مرتبطًا بعنصر الوسائط (بعد تحميل الوسائط)، عن طريق الاتصال بالرمز RemoteMediaClient.setActiveMediaTracks(long[]) وتمرير أرقام تعريف المسارات المطلوب تفعيلها. ينشط هذا المثال العنوان الفرعي والصوت الفرنسي:

كوتلين
// the ID for the French subtitle is '2' and for the French audio '3'
remoteMediaClient.setActiveMediaTracks(longArrayOf(2, 3))
    .setResultCallback(ResultCallback {
            mediaChannelResult: RemoteMediaClient.MediaChannelResult ->
                if (!mediaChannelResult.status.isSuccess) {
                    Log.e(TAG, "Failed with status code:" +
                            mediaChannelResult.status.statusCode
                    )
                }
    })
Java
// the ID for the French subtitle is '2' and for the French audio '3'
remoteMediaClient.setActiveMediaTracks(new long[]{2, 3})
    .setResultCallback(mediaChannelResult -> {
        if (!mediaChannelResult.getStatus().isSuccess()) {
            Log.e(TAG, "Failed with status code:" +
                    mediaChannelResult.getStatus().getStatusCode());
        }
    });

تحديد نمط مسارات النص

TextTrackStyle: يتم تضمين معلومات نمط مسار نصي. بعد إنشاء عنصر TextTrackStyle حالي أو تحديثه، يمكنك تطبيق هذا النمط على عنصر الوسائط الذي يتم تشغيله حاليًا من خلال استدعاء RemoteMediaClient.setTextTrackStyle، على النحو التالي:

كوتلين
// the ID for the French subtitle is '2' and for the French audio '3'
remoteMediaClient.setTextTrackStyle(style)
    .setResultCallback(ResultCallback {
            mediaChannelResult: RemoteMediaClient.MediaChannelResult ->
                if (!mediaChannelResult.status.isSuccess) {
                    Log.e(TAG, "Failed to set the style, status code: " +
                            mediaChannelResult.status.statusCode
                    )
                }
    })
Java
remoteMediaClient.setTextTrackStyle(style)
    .setResultCallback(mediaChannelResult -> {
        if (!mediaChannelResult.getStatus().isSuccess()) {
            Log.e(TAG, "Failed to set the style, status code: " +
                    mediaChannelResult.getStatus().getStatusCode());
        }
    });

يجب أن يسمح تطبيقك للمستخدمين بتعديل نمط مسارات النص، إما باستخدام الإعدادات التي يوفرها النظام أو من خلال التطبيق نفسه. في إصدار Android KitKat والإصدارات الأحدث، يمكنك استخدام إعدادات الترجمة والشرح على مستوى النظام التي يوفّرها إطار العمل:

كوتلين
val textTrackStyle = TextTrackStyle.fromSystemSettings(context)
Java
TextTrackStyle textTrackStyle = TextTrackStyle.fromSystemSettings(context);

بالنسبة إلى الإصدارات التي تسبق إصدار KitKat، سيعرض الاستدعاء أعلاه كائنًا تكون حقوله غير محدّدة، لذا عليك تعبئة تلك الحقول في تطبيقك بناءً على اختيارات المستخدم وبعض القيم التلقائية. يمكنك تصميم عناصر نمط مسار النص التالية:

  • لون المقدمة (النص) ودرجة التعتيم
  • لون الخلفية ودرجة التعتيم
  • نوع الحافة
  • لون الحافة
  • مقياس الخط
  • مجموعة الخطوط
  • نمط الخط

على سبيل المثال، اضبط لون النص على الأحمر (FF) بدرجة تعتيم 50% (80) كما يلي:

كوتلين
textTrackStyle.foregroundColor = Color.parseColor("#80FF0000")
Java
textTrackStyle.setForegroundColor(Color.parseColor("#80FF0000"));

في الإصدار KitKat والإصدارات الأحدث، يجب تسجيل التطبيق لتلقّي إشعار عند تحديث إعدادات الترجمة على مستوى النظام. لتحقيق هذه الغاية، عليك تنفيذ CaptioningManager.CaptioningChangeListener في تطبيقك وتسجيل هذا المستمع من خلال الاتصال بما يلي:

كوتلين
CaptioningManager.addCaptioningChangeListener(yourChangeListener)
Java
CaptioningManager.addCaptioningChangeListener(yourChangeListener);

عندما يتلقّى تطبيقك مكالمة تفيد بأنّه تم تغيير إعدادات الترجمة، يجب استخراج الإعدادات الجديدة وتعديل نمط الشرح النصي للوسائط التي يتم تشغيلها حاليًا من خلال طلب رمز RemoteMediaClient.setTextTrackStyle واستخدام النمط الجديد.

تلقّي تحديثات الحالة

عند اتصال عدة مرسلين بالمستلم نفسه، من المهم أن يكون كل مرسل على علم بالتغييرات في المتلقي حتى إذا كانت هذه التغييرات قد بدأت من مرسلين آخرين.

لتحقيق هذه الغاية، يجب أن يسجِّل تطبيقك RemoteMediaClient.Listener وRemoteMediaClient.ProgressListener.

في حال تغيير TextTrackStyle الوسائط الحالية، سيتم إرسال إشعار إلى كل المُرسِلين المرتبطين من خلال كل من أداة معالجة البيانات المسجَّلة أعلاه. في هذه الحالة، لا تتحقّق حزمة تطوير البرامج (SDK) للمستلِم مما إذا كان النمط الجديد مختلفًا عن النمط السابق، وتبلّغ جميع المُرسِلين المتصلين بغض النظر عن ذلك. ومع ذلك، في حال تغيّرت حالة المسارات النشطة، لن يتم إشعار سوى RemoteMediaClient.ProgressListener في المرسِلين المتصلين.

استيفاء متطلبات CORS

بالنسبة إلى بث الوسائط التكيُّفي، يتطلّب Google Cast توفُّر عناوين CORS، ومع ذلك حتى أحداث بث وسائط mp4 البسيطة تتطلّب استخدام CORS إذا كانت تتضمن مقاطع صوتية. إذا كنت تريد تمكين المقاطع الصوتية لأي وسائط، يجب تمكين CORS لكل من مجموعات بث مقاطعك الصوتية وبث الوسائط. لذا، إذا لم تتوفّر لديك عناوين CORS لوسائط mp4 البسيطة على الخادم، وأضفت مسار ترجمة بسيطًا، لن تتمكّن من بث الوسائط ما لم تُحدِّث الخادم لتضمين رأس CORS المناسب. بالإضافة إلى ذلك، تحتاج إلى السماح بالعناوين التالية على الأقل: Content-Type وAccept-Encoding وRange. لاحظ أن العنوانين الأخيرين هما رؤوس إضافية ربما لم تكن بحاجة إليها من قبل.