ExoPlayer लाइब्रेरी के कोर में, Player
इंटरफ़ेस मौजूद है. Player
पारंपरिक हाई-लेवल मीडिया प्लेयर की सुविधाओं को सार्वजनिक करने की सुविधा देता है. जैसे,
मीडिया बफ़र करें, चलाएं, रोकें, और सीक करें. लागू होने वाला डिफ़ॉल्ट ExoPlayer
है
इस बारे में कुछ अनुमान लगाने के लिए बनाया गया है (और इसलिए उन पर कुछ पाबंदियां लगाई जाती हैं)
चलाया जा रहा मीडिया किस तरह का है, यह कैसे और कहां सेव किया जाता है, और यह कैसे काम करता है
रेंडर किया गया. मीडिया को सीधे लोड और रेंडर करने के बजाय,
ExoPlayer
लागू करने की सुविधा, इस काम को इंजेक्ट किए गए कॉम्पोनेंट को सौंपती है
जब कोई प्लेयर बनाया जाता है या प्लेयर को नए मीडिया सोर्स पास किए जाते हैं.
ExoPlayer
को लागू करने के सभी तरीकों में ये कॉम्पोनेंट आम तौर पर शामिल हैं:
MediaSource
इंस्टेंस जो चलाए जाने के लिए मीडिया तय करते हैं, मीडिया लोड करते हैं, और जिससे लोड किए गए मीडिया को पढ़ा जा सके.MediaSource
इंस्टेंस बनाया गया प्लेयर के अंदर,MediaSource.Factory
सेMediaItem
से. वे यह भी कर सकते हैं मीडिया सोर्स पर आधारित प्लेलिस्ट एपीआई का इस्तेमाल करके, सीधे प्लेयर को पास किया जाना चाहिए.MediaSource.Factory
इंस्टेंस, जोMediaItem
कोMediaSource
में बदलता है. कॉन्टेंट बनाने प्लेयर बनाए जाने के बाद,MediaSource.Factory
को इंजेक्ट किया जाता है.Renderer
इंस्टेंस, जो मीडिया के अलग-अलग कॉम्पोनेंट को रेंडर करते हैं. ये हैं प्लेयर बनाते समय इंजेक्ट किया जाता है.- एक
TrackSelector
जोMediaSource
के दिए गए ट्रैक को हर उपलब्धRenderer
के इस्तेमाल करने वाले लोग.TrackSelector
इंजेक्ट किया गया है जब प्लेयर बनाया जाता है. LoadControl
, जो यह कंट्रोल करता है किMediaSource
कब ज़्यादा मीडिया बफ़र करता है और मीडिया कितनी बार बफ़र किया गया है.LoadControl
तब इंजेक्ट किया जाता है, जब प्लेयर बनाया गया.LivePlaybackSpeedControl
, जो लाइव स्ट्रीम के दौरान वीडियो चलाने की स्पीड को कंट्रोल करता है कॉन्फ़िगर किए गए लाइव ऑफ़सेट के करीब रहने के लिए, वीडियो चलाना. ऐप्लिकेशन प्लेयर बनाए जाने के बाद,LivePlaybackSpeedControl
को इंजेक्ट किया जाता है.
प्लेयर के हिस्सों को इंजेक्ट करने वाले कॉम्पोनेंट को इंजेक्ट करने का सिद्धांत फ़ंक्शन पूरी लाइब्रेरी में मौजूद है. डिफ़ॉल्ट रूप से लागू कुछ कॉम्पोनेंट, इंजेक्ट किए गए दूसरे कॉम्पोनेंट के लिए काम करते हैं. इससे कई लोग सब-कॉम्पोनेंट को अलग-अलग, ऐसे इंप्लीमेंटेशन से बदला जाएगा जिन्हें कस्टम तरीके से कॉन्फ़िगर किया गया है.
प्लेयर को पसंद के मुताबिक बनाएं
कॉम्पोनेंट को इंजेक्ट करके, प्लेयर को पसंद के मुताबिक बनाने के कुछ उदाहरण यहां दिए गए हैं जिनकी जानकारी नीचे दी गई है.
नेटवर्क स्टैक को कॉन्फ़िगर करना
हमारे पास ExoPlayer पर इस्तेमाल किए जाने वाले नेटवर्क स्टैक को पसंद के मुताबिक बनाने के बारे में एक पेज है.
नेटवर्क से लोड किए गए डेटा को कैश मेमोरी में सेव करना
इसके लिए, गाइड देखें कुछ समय के लिए तुरंत कैश मेमोरी में सेव होने की सुविधा और मीडिया डाउनलोड करना होगा.
सर्वर के इंटरैक्शन को पसंद के मुताबिक बनाना
ऐसा हो सकता है कि कुछ ऐप्लिकेशन, एचटीटीपी अनुरोधों और जवाबों को रोकना चाहें. आप शायद ये करना चाहें कस्टम अनुरोध हेडर इंजेक्ट करें, सर्वर के रिस्पॉन्स हेडर पढ़ें, और अनुरोध यूआरआई वगैरह. उदाहरण के लिए, आपका ऐप्लिकेशन इंजेक्ट करके खुद की पुष्टि कर सकता है मीडिया सेगमेंट का अनुरोध करते समय, हेडर के तौर पर टोकन.
नीचे दिए गए उदाहरण में, इन तरीकों को इस्तेमाल करने का तरीका बताया गया है
DefaultMediaSourceFactory
में पसंद के मुताबिक DataSource.Factory
को इंजेक्ट करना:
Kotlin
val dataSourceFactory = DataSource.Factory { val dataSource = httpDataSourceFactory.createDataSource() // Set a custom authentication request header. dataSource.setRequestProperty("Header", "Value") dataSource } val player = ExoPlayer.Builder(context) .setMediaSourceFactory( DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory) ) .build()
Java
DataSource.Factory dataSourceFactory = () -> { HttpDataSource dataSource = httpDataSourceFactory.createDataSource(); // Set a custom authentication request header. dataSource.setRequestProperty("Header", "Value"); return dataSource; }; ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory)) .build();
ऊपर दिए गए कोड स्निपेट में, इंजेक्ट किए गए HttpDataSource
में हेडर शामिल है
हर एचटीटीपी अनुरोध में "Header: Value"
. यह व्यवहार तय है,
किसी एचटीटीपी सोर्स के साथ इंटरैक्शन करना चाहिए.
ज़्यादा बारीकी से जानकारी पाने के लिए, 'टाइम-इन-टाइम' व्यवहार को इंजेक्ट किया जा सकता है. इसके लिए
ResolvingDataSource
. नीचे दिया गया कोड स्निपेट, इंजेक्ट करने का तरीका बताता है
किसी एचटीटीपी सोर्स के साथ इंटरैक्ट करने से ठीक पहले हेडर का अनुरोध करें:
Kotlin
val dataSourceFactory: DataSource.Factory = ResolvingDataSource.Factory(httpDataSourceFactory) { dataSpec: DataSpec -> // Provide just-in-time request headers. dataSpec.withRequestHeaders(getCustomHeaders(dataSpec.uri)) }
Java
DataSource.Factory dataSourceFactory = new ResolvingDataSource.Factory( httpDataSourceFactory, // Provide just-in-time request headers. dataSpec -> dataSpec.withRequestHeaders(getCustomHeaders(dataSpec.uri)));
आप यह काम करने के लिए ResolvingDataSource
का इस्तेमाल भी कर सकते हैं
यूआरआई का जस्ट-इन-टाइम संशोधन, जैसा कि नीचे दिए गए स्निपेट में दिखाया गया है:
Kotlin
val dataSourceFactory: DataSource.Factory = ResolvingDataSource.Factory(httpDataSourceFactory) { dataSpec: DataSpec -> // Provide just-in-time URI resolution logic. dataSpec.withUri(resolveUri(dataSpec.uri)) }
Java
DataSource.Factory dataSourceFactory = new ResolvingDataSource.Factory( httpDataSourceFactory, // Provide just-in-time URI resolution logic. dataSpec -> dataSpec.withUri(resolveUri(dataSpec.uri)));
गड़बड़ी ठीक करना पसंद के मुताबिक बनाना
कस्टम LoadErrorHandlingPolicy
लागू करने से, ऐप्लिकेशन
लोड करने में होने वाली गड़बड़ियों पर, ExoPlayer प्रतिक्रिया किस तरह देता है. उदाहरण के लिए, हो सकता है कि कोई ऐप्लिकेशन तेज़ी से काम न करे
का बार-बार प्रयास करने के बजाय या हो सकता है कि आप उस बैक-ऑफ़ लॉजिक को कस्टमाइज़ करना चाहें, जो
यह नीति कंट्रोल करती है कि हर कोशिश के बीच, प्लेयर कितनी देर इंतज़ार करेगा. नीचे दिया गया स्निपेट
कस्टम बैक-ऑफ़ लॉजिक को लागू करने का तरीका दिखाता है:
Kotlin
val loadErrorHandlingPolicy: LoadErrorHandlingPolicy = object : DefaultLoadErrorHandlingPolicy() { override fun getRetryDelayMsFor(loadErrorInfo: LoadErrorInfo): Long { // Implement custom back-off logic here. return 0 } } val player = ExoPlayer.Builder(context) .setMediaSourceFactory( DefaultMediaSourceFactory(context).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy) ) .build()
Java
LoadErrorHandlingPolicy loadErrorHandlingPolicy = new DefaultLoadErrorHandlingPolicy() { @Override public long getRetryDelayMsFor(LoadErrorInfo loadErrorInfo) { // Implement custom back-off logic here. return 0; } }; ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context) .setLoadErrorHandlingPolicy(loadErrorHandlingPolicy)) .build();
LoadErrorInfo
आर्ग्युमेंट में, लोड न हो पाने के बारे में ज़्यादा जानकारी मौजूद है
गड़बड़ी के टाइप या पूरे न हो पाने वाले अनुरोध के आधार पर लॉजिक को कस्टमाइज़ करें.
डेटा इकट्ठा करने वाले फ़्लैग को पसंद के मुताबिक बनाना
अलग-अलग फ़ॉर्मैट निकालने के तरीके को पसंद के मुताबिक बनाने के लिए, एक्सट्रैक्टर के फ़्लैग का इस्तेमाल किया जा सकता है
को ट्रैक किया जा सकता है. इन्हें इस DefaultExtractorsFactory
पर सेट किया जा सकता है:
DefaultMediaSourceFactory
को उपलब्ध कराया गया है. यहां दिए गए उदाहरण में, 14 साल
इसकी मदद से MP3 स्ट्रीम के लिए, इंडेक्स पर आधारित वीडियो खोजने की सुविधा चालू की जा सकती है.
Kotlin
val extractorsFactory = DefaultExtractorsFactory().setMp3ExtractorFlags(Mp3Extractor.FLAG_ENABLE_INDEX_SEEKING) val player = ExoPlayer.Builder(context) .setMediaSourceFactory(DefaultMediaSourceFactory(context, extractorsFactory)) .build()
Java
DefaultExtractorsFactory extractorsFactory = new DefaultExtractorsFactory().setMp3ExtractorFlags(Mp3Extractor.FLAG_ENABLE_INDEX_SEEKING); ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory(new DefaultMediaSourceFactory(context, extractorsFactory)) .build();
लगातार बिटरेट में वीडियो चलाने की सुविधा चालू करना
MP3, ADTS, और AMR से स्ट्रीम करने के लिए, किसी
FLAG_ENABLE_CONSTANT_BITRATE_SEEKING
फ़्लैग के साथ कॉन्सटेंट बिटरेट का अनुमान.
डेटा इकट्ठा करने वाले अलग-अलग टूल के लिए, ये फ़्लैग सेट किए जा सकते हैं. इसके लिए,
DefaultExtractorsFactory.setXyzExtractorFlags
तरीके हैं, जो ऊपर बताए गए हैं. यहां की यात्रा पर हूं
डेटा इकट्ठा करने वाले उन सभी टूल के लिए कॉन्स्टेंट बिटरेट की सुविधा चालू करें जो इस पर काम करते हैं. इसके लिए, इसका इस्तेमाल करें
DefaultExtractorsFactory.setConstantBitrateSeekingEnabled
.
Kotlin
val extractorsFactory = DefaultExtractorsFactory().setConstantBitrateSeekingEnabled(true)
Java
DefaultExtractorsFactory extractorsFactory = new DefaultExtractorsFactory().setConstantBitrateSeekingEnabled(true);
इसके बाद, DefaultMediaSourceFactory
के ज़रिए ExtractorsFactory
को इस तरह इंजेक्ट किया जा सकता है:
एक्सट्रैक्ट करने वाले फ़्लैग को पसंद के मुताबिक बनाने के बारे में ऊपर बताया गया है.
एसिंक्रोनस बफ़र सूची को चालू करना
एसिंक्रोनस बफ़र सूची बनाने की सुविधा, ExoPlayer की रेंडरिंग को बेहतर बनाती है
पाइपलाइन, जो एसिंक्रोनस मोड में MediaCodec
इंस्टेंस ऑपरेट करती है और
डेटा को डिकोड करने और रेंडर करने का शेड्यूल तय करने के लिए, अतिरिक्त थ्रेड का इस्तेमाल करता है. इसे चालू किया जा रहा है
वीडियो के हटाए जाने वाले फ़्रेम और ऑडियो की कमियों को कम किया जा सकता है.
Android 12 वर्शन वाले डिवाइसों पर, एसिंक्रोनस बफ़र सूची की सुविधा डिफ़ॉल्ट रूप से चालू होती है (एपीआई लेवल 31) और इसके बाद के वर्शन. Android 6.0 (एपीआई लेवल 23) और इसके बाद के वर्शन को मैन्युअल तरीके से चालू किया जा सकता है. इस सुविधा को उन खास डिवाइसों के लिए चालू करें जिन पर आपको परफ़ॉर्मेंस में गिरावट दिख रही है ऐसे फ़्रेम या ऑडियो जिनका इस्तेमाल नहीं हो पाया. खास तौर पर, ऐसा तब होता है, जब डीआरएम से सुरक्षित या ज़्यादा फ़्रेम-रेट वाला वीडियो चलाया जा रहा हो कॉन्टेंट.
सबसे आसान मामले में, आपकोDefaultRenderersFactory
प्लेयर इस तरह से सुनें:
Kotlin
val renderersFactory = DefaultRenderersFactory(context).forceEnableMediaCodecAsynchronousQueueing() val exoPlayer = ExoPlayer.Builder(context, renderersFactory).build()
Java
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(context).forceEnableMediaCodecAsynchronousQueueing(); ExoPlayer exoPlayer = new ExoPlayer.Builder(context, renderersFactory).build();
अगर आप रेंडरर को सीधे इंस्टैंशिएट कर रहे हैं, तो
AsynchronousMediaCodecAdapter.Factory
से MediaCodecVideoRenderer
और
MediaCodecAudioRenderer
कंस्ट्रक्टर.
ForwardingPlayer
की मदद से कॉल में रुकावट डालना
Player
इंस्टेंस के व्यवहार को पसंद के मुताबिक बनाया जा सकता है. इसके लिए, आपको इसे रैप करना होगा
इनमें से कोई भी काम करने के लिए, ForwardingPlayer
की सब-क्लास और ओवरराइडिंग मेथड का इस्तेमाल
निम्न:
- पैरामीटर को डेलिगेट
Player
को पास करने से पहले, उन्हें ऐक्सेस करें. - उसे लौटाने से पहले प्रतिनिधि
Player
से उसकी रिटर्न वैल्यू ऐक्सेस करें. - इस तरीके को पूरी तरह से फिर से लागू करें.
ForwardingPlayer
के तरीकों को ओवरराइड करते समय, पक्का करना ज़रूरी है कि
लागू करने की प्रोसेस अपने-आप लागू होती है और Player
के मुताबिक होती है
इंटरफ़ेस, खास तौर पर ऐसे तरीकों पर काम करता है जिनका मकसद
एक जैसा या मिलता-जुलता व्यवहार. उदाहरण के लिए:
- अगर आपको हर 'गेम' सेटिंग को बदलना है कार्रवाई के लिए, आपको दोनों को ओवरराइड करना होगा
ForwardingPlayer.play
औरForwardingPlayer.setPlayWhenReady
की वजह से कॉलर यह उम्मीद करेगा कि इन तरीकों का व्यवहार एक जैसा होगा, जबplayWhenReady = true
. - आगे-पीछे करने की सीमा में बदलाव करने के लिए, आपको दोनों को बदलना होगा
अपने कस्टमाइज़ किए गए वीडियो के साथ वीडियो में आगे/पीछे जाने की सुविधा इस्तेमाल करने के लिए
ForwardingPlayer.seekForward
औरForwardingPlayer.getSeekForwardIncrement
कॉलर के लिए कस्टमाइज़ की गई सही वृद्धि वापस ले सकता है. - अगर आपको यह कंट्रोल करना है कि कोई खिलाड़ी,
Player.Commands
किस तरह का विज्ञापन दिखाए उदाहरण के लिए, आपकोPlayer.getAvailableCommands()
औरPlayer.isCommandAvailable()
, और यह भी सुनें: इसकी सूचना पाने के लिए,Player.Listener.onAvailableCommandsChanged()
कॉलबैक दिए गए प्लेयर की सेटिंग से होने वाले बदलाव दिखेंगे.
MediaSource कस्टमाइज़ेशन
ऊपर दिए गए उदाहरण, सभी वीडियो चलाने के दौरान इस्तेमाल करने के लिए, पसंद के मुताबिक बनाए गए कॉम्पोनेंट इंजेक्ट करते हैं
MediaItem
ऑब्जेक्ट जो प्लेयर को पास किए जाते हैं. जहां छोटी सी पसंद है
इसलिए, ज़रूरत के हिसाब से बदले जा सकने वाले कॉम्पोनेंट को अलग-अलग इंजेक्ट करना भी मुमकिन है
MediaSource
इंस्टेंस, जिन्हें सीधे प्लेयर को भेजा जा सकता है. उदाहरण के लिए
नीचे बताया गया है कि ProgressiveMediaSource
को पसंद के मुताबिक कैसे बनाया जा सकता है.
DataSource.Factory
, ExtractorsFactory
, और LoadErrorHandlingPolicy
:
Kotlin
val mediaSource = ProgressiveMediaSource.Factory(customDataSourceFactory, customExtractorsFactory) .setLoadErrorHandlingPolicy(customLoadErrorHandlingPolicy) .createMediaSource(MediaItem.fromUri(streamUri))
Java
ProgressiveMediaSource mediaSource = new ProgressiveMediaSource.Factory(customDataSourceFactory, customExtractorsFactory) .setLoadErrorHandlingPolicy(customLoadErrorHandlingPolicy) .createMediaSource(MediaItem.fromUri(streamUri));
कस्टम कॉम्पोनेंट बनाना
लाइब्रेरी में, सबसे ऊपर दिए गए कॉम्पोनेंट को डिफ़ॉल्ट रूप से लागू करने की सुविधा मिलती है
इस पेज को पढ़ें. ExoPlayer
इन कॉम्पोनेंट का इस्तेमाल कर सकता है, लेकिन
कस्टम कार्यान्वयन का उपयोग करने के लिए भी बनाया जा सकता है, यदि गैर-मानक व्यवहार
आवश्यक. अपनी ज़रूरत के हिसाब से लागू करने के लिए, इस्तेमाल के कुछ उदाहरण यहां दिए गए हैं:
Renderer
– हो सकता है कि आप एक कस्टमRenderer
लागू करना चाहें मीडिया प्रकार लाइब्रेरी.TrackSelector
– पसंद के मुताबिकTrackSelector
लागू करने से, ऐप्लिकेशन को मंज़ूरी मिलती है डेवलपर कोMediaSource
में बिना अनुमति के सार्वजनिक किए गए ट्रैक को इस्तेमाल करने का तरीका बदलना होगा हर उपलब्धRenderer
के हिसाब से इस्तेमाल के लिए चुना गया.LoadControl
– पसंद के मुताबिकLoadControl
लागू करने से, ऐप्लिकेशन को मंज़ूरी मिलती है डेवलपर को प्लेयर की बफ़रिंग की नीति में बदलाव करना होगा.Extractor
– अगर आपको ऐसे कंटेनर फ़ॉर्मैट का इस्तेमाल करना है जो फ़िलहाल उपलब्ध नहीं है अगर लाइब्रेरी का इस्तेमाल किया जा सकता है, तो पसंद के मुताबिकExtractor
क्लास लागू करें.MediaSource
– कस्टमMediaSource
क्लास को लागू करने का तरीका तो तब ठीक होगा, जब आपको किसी रेंडरर में फ़ीड करने के लिए मीडिया के सैंपल चाहिए या अगर आपको कस्टमMediaSource
कंपोज़िटिंग लागू करनी है, तो व्यवहार.MediaSource.Factory
– पसंद के मुताबिकMediaSource.Factory
को लागू करना ऐप्लिकेशन कोMediaSource
बनाने के तरीके को पसंद के मुताबिक बनाने की अनुमति देता हैMediaItem
से मिला है.DataSource
– ExoPlayer के अपस्ट्रीम पैकेज में पहले से ही कई इस्तेमाल के अलग-अलग उदाहरणों के लिए,DataSource
को लागू करना. आप शायद ये करना चाहें डेटा को अन्य तरीके से लोड करने के लिए, अपनीDataSource
क्लास लागू करें, जैसे कि एक कस्टम प्रोटोकॉल, जो कस्टम एचटीटीपी स्टैक का इस्तेमाल कर रहा हो या किसी कस्टम स्थायी प्रॉपर्टी से हो कैश मेमोरी.
कस्टम कॉम्पोनेंट बनाते समय, हमारा सुझाव है कि आप ये काम करें:
- अगर किसी कस्टम कॉम्पोनेंट को इवेंट की शिकायत वापस ऐप्लिकेशन में करनी है, तो हमारा सुझाव है
आपको ऐसा करने के लिए, मौजूदा ExoPlayer के कॉम्पोनेंट वाले मॉडल का ही इस्तेमाल करना होगा,
उदाहरण के लिए,
EventDispatcher
क्लास का इस्तेमाल करना याHandler
को एक साथ पास करना कॉम्पोनेंट के कंस्ट्रक्टर को सुनने वाला. - हमारा सुझाव है कि कस्टम कॉम्पोनेंट और मौजूदा ExoPlayer, दोनों के लिए एक ही मॉडल का इस्तेमाल करें
के लिए कॉम्पोनेंट का इस्तेमाल किया जाता है, ताकि वीडियो चलने के दौरान ऐप्लिकेशन को फिर से कॉन्फ़िगरेशन करने की अनुमति मिल सके. ऐसा करने के लिए,
कस्टम कॉम्पोनेंट को
PlayerMessage.Target
लागू करना चाहिए औरhandleMessage
तरीके में कॉन्फ़िगरेशन के बदलाव. ऐप्लिकेशन कोड को यह करना चाहिए ExoPlayer केcreateMessage
तरीके को कॉल करके, कॉन्फ़िगरेशन में बदलाव करें, मैसेज को कॉन्फ़िगर करें और फिर इसका इस्तेमाल करके उसे कॉम्पोनेंट को भेजेंPlayerMessage.send
. प्लेबैक थ्रेड पर डिलीवर करने के लिए मैसेज भेजे जा रहे हैं यह पक्का करता है कि उन्हें क्रम से लागू किया जाए और इसके लिए कोई अन्य ऑपरेशन प्लेयर पर किया गया.