झलक दिखाने वाला वीडियो, उपयोगकर्ताओं को टीवी ऐप्लिकेशन में डीप-लिंक करने के लिए बढ़ावा देने का एक बेहतरीन तरीका है. झलक में, छोटी क्लिप से लेकर पूरी फ़िल्मों के ट्रेलर तक शामिल हो सकते हैं.
झलक बनाते समय, इन दिशा-निर्देशों को ध्यान में रखें:
- झलक में विज्ञापन न दिखाएं. अगर क्लाइंट साइड पर विज्ञापन स्टिच करें, तो उन्हें झलक दिखाने वाले वीडियो में न जोड़ें. अगर सर्वर साइड पर विज्ञापन पिच किए जाते हैं, लोगों को बिना विज्ञापन के वीडियो देखने की सुविधा दें.
- सबसे अच्छी क्वालिटी के लिए, झलक दिखाने वाले वीडियो का अनुपात 16:9 या 4:3 होना चाहिए. यहां जाएं: वीडियो प्रोग्राम के एट्रिब्यूट झलक दिखाने वाले वीडियो के सुझाए गए साइज़ के लिए.
- जब झलक दिखाने वाले वीडियो और पोस्टर आर्ट का आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) अलग-अलग होता है, तो
झलक चलाने से पहले, होम स्क्रीन पोस्टर व्यू को वीडियो के आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) के हिसाब से बदल देती है.
वीडियो लेटरबॉक्स नहीं किया गया है. उदाहरण के लिए, अगर
पोस्टर आर्ट का अनुपात इतना है
ASPECT_RATIO_MOVIE_POSTER
(1:1.441) लेकिन वीडियो का अनुपात 16:9 है, तो पोस्टर व्यू 16:9 के क्षेत्र में बदल जाता है. - जब आप झलक बनाते हैं, तो इसका कॉन्टेंट सार्वजनिक तौर पर ऐक्सेस किया जा सकता है या डीआरएम के तहत सुरक्षित किया गया है. हर मामले में अलग-अलग प्रोसेस अपनाई जाती है. यह पेज दोनों का वर्णन करता है.
होम स्क्रीन पर झलक देखें
अगर आपने अलग-अलग तरह के वीडियो की झलक बनाई है, तो ExoPlayer के साथ काम करता है और झलक को सार्वजनिक तौर पर ऐक्सेस किया जा सकता है. साथ ही, उसकी झलक को सीधे होम स्क्रीन पर चलाया जा सकता है.
जब आप PreviewProgram बनाएं
setPreviewVideoUri()
को सार्वजनिक तौर पर ऐक्सेस किए जा सकने वाले एचटीटीपीएस के साथ इस्तेमाल करें
यूआरएल, जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है. झलक इनमें से कोई भी हो सकती है
video या
ऑडियो.
Kotlin
val previewVideoUrl = Uri.parse("https://www.example.com/preview.mp4") val builder = PreviewProgram.Builder() builder.setChannelId(channelId) // ... .setPreviewVideoUri(previewVideoUrl)
Java
Uri previewVideoUrl = Uri.parse("https://www.example.com/preview.mp4"); PreviewProgram.Builder builder = new PreviewProgram.Builder(); builder.setChannelId(channelId) // ... .setPreviewVideoUri(Uri.parse(previewVideoUrl));
किसी प्लैटफ़ॉर्म पर झलक रेंडर करें
अगर आपका वीडियो डीआरएम से सुरक्षित है या ऐसे मीडिया फ़ॉर्मैट में है जो YouTube TV पर काम नहीं करता
ExoPlayer, TvInputService
का इस्तेमाल करें.
Android TV की होम स्क्रीन, आपकी सेवा को Surface
पास करती है
onSetSurface()
पर कॉल करके. आपका ऐप्लिकेशन, onTune()
से सीधे इस प्लैटफ़ॉर्म पर वीडियो बनाता है.
डायरेक्ट सरफ़ेस रेंडरिंग से, आपके ऐप्लिकेशन को यह तय करने में मदद मिलती है कि क्या रेंडर किया जाए और उसे कैसे दिखाया जाए रेंडर किया गया. आप चैनल एट्रिब्यूशन जैसे मेटाडेटा को ओवरले कर सकते हैं.
मेनिफ़ेस्ट में अपने TvइनपुटService के बारे में बताएं
आपके ऐप्लिकेशन को TvInputService
को लागू करने की जानकारी देनी होगी
ताकि होम स्क्रीन पर झलक को रेंडर किया जा सके.
अपनी सेवा के एलान में, एक ऐसा इंटेंट फ़िल्टर शामिल करें जो
TvInputService
की मदद से,
इंटेंट. साथ ही, सेवा मेटाडेटा को एक अलग एक्सएमएल रिसॉर्स के तौर पर एलान करें. कॉन्टेंट बनाने
सेवा का एलान, इंटेंट फ़िल्टर, और सेवा मेटाडेटा का एलान दिखाया गया है
नीचे दिए गए उदाहरण में:
<service android:name=".rich.PreviewInputService" android:permission="android.permission.BIND_TV_INPUT"> <!-- Required filter used by the system to launch our account service. --> <intent-filter> <action android:name="android.media.tv.TvInputService" /> </intent-filter> <!-- An XML file which describes this input. --> <meta-data android:name="android.media.tv.input" android:resource="@xml/previewinputservice" /> </service>
सेवा मेटाडेटा को एक अलग एक्सएमएल फ़ाइल में तय करें.
सेवा मेटाडेटा फ़ाइल, एक्सएमएल रिसॉर्स डायरेक्ट्री में मौजूद है
के लिए डाउनलोड किया गया है और यह उस संसाधन के नाम से मेल खाना चाहिए जिसका एलान आपने
मेनिफ़ेस्ट. पिछले उदाहरण की मेनिफ़ेस्ट एंट्री का इस्तेमाल करके, आपको
res/xml/previewinputservice.xml
पर एक एक्सएमएल फ़ाइल बनाएं, जिसमें खाली जगह हो
tv-input
टैग:
<?xml version="1.0" encoding="utf-8"?>
<tv-input/>
टीवी इनपुट फ़्रेमवर्क में यह टैग होना ज़रूरी है. हालांकि, इसका इस्तेमाल सिर्फ़ लाइव चैनलों को कॉन्फ़िगर करने के लिए किया जाता है. वीडियो रेंडर किया जा रहा है, इसलिए टैग खाली होना चाहिए.
वीडियो यूआरआई बनाएं
यह बताने के लिए कि झलक दिखाने वाले वीडियो को
तो आपको PreviewProgram
के लिए वीडियो यूआरआई बनाना होगा.
यूआरआई के आखिर में वह आइडेंटिफ़ायर मौजूद होना चाहिए जिसका इस्तेमाल आपका ऐप्लिकेशन, कॉन्टेंट के लिए करता है, ताकि आप
बाद में, TvInputService
में कॉन्टेंट को वापस लाया जा सकता है.
अगर आपका आइडेंटिफ़ायर Long
टाइप है, तो इसका इस्तेमाल करें
TvConactCompat.buildPreviewProgramUri():
Kotlin
val id: Long = 1L // content identifier val componentName = new ComponentName(context, PreviewVideoInputService.class) val previewProgramVideoUri = TvContractCompat.buildPreviewProgramUri(id) .buildUpon() .appendQueryParameter("input", TvContractCompat.buildInputId(componentName)) .build()
Java
Long id = 1L; // content identifier ComponentName componentName = new ComponentName(context, PreviewVideoInputService.class); previewProgramVideoUri = TvContractCompat.buildPreviewProgramUri(id) .buildUpon() .appendQueryParameter("input", TvContractCompat.buildInputId(componentName)) .build();
अगर आपका आइडेंटिफ़ायर Long
टाइप नहीं है, तो यूआरआई बनाएं
Uri.withAppendedPath()
:
Kotlin
val previewProgramVideoUri = Uri.withAppendedPath(PreviewPrograms.CONTENT_URI, "content-identifier") .buildUpon() .appendQueryParameter("input", TvContractCompat.buildInputId(componentName)) .build()
Java
previewProgramVideoUri = Uri.withAppendedPath(PreviewPrograms.CONTENT_URI, "content-identifier") .buildUpon() .appendQueryParameter("input", TvContractCompat.buildInputId(componentName)) .build();
आपके ऐप्लिकेशन
onTune(Uri videoUri)
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
Android TV पर झलक दिखाने वाला वीडियो देखने के लिए.
सेवा बनाएं
यहां दिए गए उदाहरण में, TvInputService
को बढ़ाने का तरीका बताया गया है. इसकी मदद से, नया उदाहरण बनाया जा सकता है
PreviewInputService
. ध्यान दें कि सेवा चलाने के लिए MediaPlayer
का इस्तेमाल करती है,
लेकिन आपका कोड किसी भी उपलब्ध वीडियो प्लेयर का इस्तेमाल कर सकता है.
Kotlin
import android.content.Context import android.media.MediaPlayer import android.media.tv.TvInputService import android.net.Uri import android.util.Log import android.view.Surface import java.io.IOException class PreviewVideoInputService : TvInputService() { override fun onCreateSession(inputId: String): TvInputService.Session? { return PreviewSession(this) } private inner class PreviewSession( internal var context: Context ) : TvInputService.Session(context) { internal var mediaPlayer: MediaPlayer? = MediaPlayer() override fun onRelease() { mediaPlayer?.release() mediaPlayer = null } override fun onTune(uri: Uri): Boolean { // Let the TvInputService know that the video is being loaded. notifyVideoUnavailable(VIDEO_UNAVAILABLE_REASON_TUNING) // Fetch the stream url from the TV Provider database // for content://android.media.tv/preview_program/val id = uri.lastPathSegment // Load your video in the background. retrieveYourVideoPreviewUrl(id) { videoUri -> if (videoUri == null) { Log.d(TAG, "Could not find video $id") notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN) } try { mPlayer.setDataSource(getApplicationContext(), videoUri) mPlayer.prepare() mPlayer.start() notifyVideoAvailable() } catch (IOException e) { Log.e(TAG, "Could not prepare media player", e) notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN) } } return true } override fun onSetSurface(surface: Surface?): Boolean { mediaPlayer?.setSurface(surface) return true } override fun onSetStreamVolume(volume: Float) { // The home screen may fade in and out the video's volume. // Your player should be updated accordingly. mediaPlayer?.setVolume(volume, volume) } override fun onSetCaptionEnabled(b: Boolean) { // enable/disable captions here } } companion object { private const val TAG = "PreviewInputService" } }
Java
import android.content.Context; import android.media.MediaPlayer; import android.media.tv.TvInputService; import android.net.Uri; import android.support.annotation.Nullable; import android.util.Log; import android.view.Surface; import java.io.IOException; public class PreviewVideoInputService extends TvInputService { private static final String TAG = "PreviewVideoInputService"; @Nullable @Override public Session onCreateSession(String inputId) { return new PreviewSession(this); } private class PreviewSession extends TvInputService.Session { private MediaPlayer mPlayer; PreviewSession(Context context) { super(context); mPlayer = new MediaPlayer(); } @Override public boolean onTune(Uri channelUri) { // Let the TvInputService know that the video is being loaded. notifyVideoUnavailable(VIDEO_UNAVAILABLE_REASON_TUNING); // Fetch the stream url from the TV Provider database // for content://android.media.tv/preview_program/String id = uri.getLastPathSegment(); // Load your video in the background. retrieveYourVideoPreviewUrl(id, new MyCallback() { public void callback(Uri videoUri) { if (videoUri == null) { Log.d(TAG, "Could not find video" + id); notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN); } try { mPlayer.setDataSource(getApplicationContext(), videoUri); mPlayer.prepare(); mPlayer.start(); notifyVideoAvailable(); } catch (IOException e) { Log.e(TAG, "Could not prepare media player", e); notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN); } } }); return true; } @Override public boolean onSetSurface(@Nullable Surface surface) { if (mPlayer != null) { mPlayer.setSurface(surface); } return true; } @Override public void onRelease() { if (mPlayer != null) { mPlayer.release(); } mPlayer = null; } @Override public void onSetStreamVolume(float volume) { if (mPlayer != null) { // The home screen may fade in and out the video's volume. // Your player should be updated accordingly. mPlayer.setVolume(volume, volume); } } @Override public void onSetCaptionEnabled(boolean enabled) { // enable/disable captions here } } }