Media3, डिफ़ॉल्ट PlayerView उपलब्ध कराता है. इससे कुछ हद तक कस्टमाइज़ेशन किया जा सकता है.
ड्रॉएबल बदलना
PlayerView, प्लेबैक कंट्रोल और प्रोग्रेस बार दिखाने के लिए PlayerControlView का इस्तेमाल करता है. PlayerControlView में इस्तेमाल किए गए ड्रॉएबल को, आपके ऐप्लिकेशन में तय किए गए एक ही नाम वाले ड्रॉएबल से बदला जा सकता है. बदले जा सकने वाले कंट्रोल ड्रॉएबल की सूची देखने के लिए, PlayerControlView का दस्तावेज़ देखें.
अगर ऐप्लिकेशन डेवलपर को और बदलाव करने हैं, तो उन्हें अपने यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट लागू करने होंगे. हालांकि, यहां कुछ सबसे सही तरीके दिए गए हैं. इनसे आपको शुरुआत करने में मदद मिल सकती है.
सबसे सही तरीके
Media3 Player से कनेक्ट होने वाले मीडिया यूज़र इंटरफ़ेस (यूआई) को लागू करते समय, ऐप्लिकेशन को यूज़र इंटरफ़ेस (यूआई) का सबसे अच्छा अनुभव देने के लिए, इन सबसे सही तरीकों का पालन करने का सुझाव दिया जाता है. उदाहरण के लिए, ExoPlayer, MediaController या कस्टम Player लागू करना.
चलाएं/रोकें बटन
वीडियो चलाने और रोकने के बटन से, सीधे तौर पर प्लेयर की किसी एक स्थिति का पता नहीं चलता. उदाहरण के लिए, अगर प्लेयर को रोका नहीं गया है, तब भी उपयोगकर्ता को वीडियो खत्म होने या चलने में समस्या आने के बाद, उसे फिर से चलाने का विकल्प मिलना चाहिए.
Media3, लागू करने की प्रोसेस को आसान बनाने के लिए, यूटिलिटी के तरीके उपलब्ध कराता है. इनसे यह तय किया जा सकता है कि कौनसा बटन दिखाना है (Util.shouldShowPlayButton) और बटन दबाने की कार्रवाइयों को कैसे हैंडल करना है (Util.handlePlayPauseButtonAction):
Kotlin
val shouldShowPlayButton: Boolean = Util.shouldShowPlayButton(player) playPauseButton.setImageDrawable(if (shouldShowPlayButton) playDrawable else pauseDrawable) playPauseButton.setOnClickListener { Util.handlePlayPauseButtonAction(player) }
Java
boolean shouldShowPlayButton = Util.shouldShowPlayButton(player); playPauseButton.setImageDrawable(shouldShowPlayButton ? playDrawable : pauseDrawable); playPauseButton.setOnClickListener(view -> Util.handlePlayPauseButtonAction(player));
स्टेट अपडेट सुनना
यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट को Player.Listener जोड़ने की ज़रूरत होती है, ताकि उसे ऐसे स्टेटस बदलावों के बारे में सूचना मिल सके जिनके लिए यूज़र इंटरफ़ेस (यूआई) को अपडेट करना ज़रूरी है. ज़्यादा जानकारी के लिए, प्लेबैक इवेंट सुनना लेख पढ़ें.
यूज़र इंटरफ़ेस (यूआई) को रीफ़्रेश करने में ज़्यादा समय लग सकता है. साथ ही, अक्सर एक साथ कई प्लेयर इवेंट आते हैं. कम समय में यूज़र इंटरफ़ेस (यूआई) को बार-बार रीफ़्रेश करने से बचने के लिए, आम तौर पर सिर्फ़ onEvents को सुनना और वहां से यूज़र इंटरफ़ेस (यूआई) के अपडेट ट्रिगर करना बेहतर होता है:
Kotlin
player.addListener(object : Player.Listener{ override fun onEvents(player: Player, events: Player.Events){ if (events.containsAny( Player.EVENT_PLAY_WHEN_READY_CHANGED, Player.EVENT_PLAYBACK_STATE_CHANGED, Player.EVENT_PLAYBACK_SUPPRESSION_REASON_CHANGED)) { updatePlayPauseButton() } if (events.containsAny(Player.EVENT_REPEAT_MODE_CHANGED)) { updateRepeatModeButton() } } })
Java
player.addListener(new Player.Listener() { @Override public void onEvents(Player player, Player.Events events) { if (events.containsAny( Player.EVENT_PLAY_WHEN_READY_CHANGED, Player.EVENT_PLAYBACK_STATE_CHANGED, Player.EVENT_PLAYBACK_SUPPRESSION_REASON_CHANGED)) { updatePlayPauseButton(); } if (events.containsAny(Player.EVENT_REPEAT_MODE_CHANGED)) { updateRepeatModeButton(); } } });
उपलब्ध निर्देश मैनेज करना
सामान्य मकसद के लिए इस्तेमाल होने वाला यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट, अलग-अलग Player
इस्तेमाल के साथ काम कर सकता है. इसे उपलब्ध प्लेयर कमांड की जांच करनी चाहिए, ताकि बटन दिखाए या छिपाए जा सकें. साथ ही, यह भी देखना चाहिए कि जिन तरीकों का इस्तेमाल नहीं किया जा सकता उन्हें कॉल न किया जाए:
Kotlin
nextButton.isEnabled = player.isCommandAvailable(COMMAND_SEEK_TO_NEXT)
Java
nextButton.setEnabled(player.isCommandAvailable(COMMAND_SEEK_TO_NEXT));
पहले फ़्रेम का शटर और इमेज डिसप्ले
जब कोई यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट वीडियो या इमेज दिखाता है, तो आम तौर पर यह तब तक प्लेसहोल्डर शटर व्यू का इस्तेमाल करता है, जब तक कि पहला फ़्रेम या इमेज उपलब्ध न हो जाए. इसके अलावा, वीडियो और इमेज को एक साथ चलाने के लिए, इमेज व्यू को सही समय पर छिपाना और दिखाना ज़रूरी होता है.
इन अपडेट को मैनेज करने का एक सामान्य तरीका यह है कि चुने गए ट्रैक (EVENT_TRACKS_CHANGED) में किसी भी बदलाव के लिए Player.Listener.onEvents() को सुनें. साथ ही, पहले वीडियो फ़्रेम के रेंडर होने (EVENT_RENDERED_FIRST_FRAME) और नई इमेज के उपलब्ध होने (ImageOutput.onImageAvailable()) के लिए भी सुनें:
Kotlin
override fun onEvents(player: Player, events: Player.Events) { if (events.contains(Player.EVENT_TRACKS_CHANGED)) { // If no video or image track: show shutter, hide image view. // Otherwise: do nothing to wait for first frame or image. } if (events.contains(Player.EVENT_RENDERED_FIRST_FRAME)) { // Hide shutter, hide image view. } } override fun onImageAvailable(presentationTimeUs: Long, bitmap: Bitmap) { // Show shutter, set image and show image view. }
Java
@Override public void onEvents(Player player, Events events) { if (events.contains(Player.EVENT_TRACKS_CHANGED)) { // If no video or image track: show shutter, hide image view. // Otherwise: do nothing to wait for first frame or image. } if (events.contains(Player.EVENT_RENDERED_FIRST_FRAME)) { // Hide shutter, hide image view. } } @Override public void onImageAvailable(long presentationTimeUs, Bitmap bitmap) { // Show shutter, set image and show image view. }