इस डेवलपर गाइड में अपने Android में Google Cast सहायता जोड़ने का तरीका बताया गया है Android सेंडर SDK टूल का इस्तेमाल करने वाला ऐप्लिकेशन.
मोबाइल डिवाइस या लैपटॉप भेजने वाले का होता है, जो वीडियो को कंट्रोल करता है और Google Cast डिवाइस पाने वाला है, जो टीवी पर कॉन्टेंट दिखाता है.
भेजने वाले का फ़्रेमवर्क, Cast क्लास लाइब्रेरी की बाइनरी और उससे जुड़े डेटा के बारे में बताता है भेजने वाले के रनटाइम के दौरान मौजूद संसाधन. भेजने वाले का ऐप्लिकेशन या Cast ऐप्लिकेशन एक ऐसे ऐप्लिकेशन का संदर्भ देता है, जो भेजने वाले पर भी चल रहा है. वेब रिसीवर ऐप्लिकेशन का मतलब है, Cast की सुविधा वाले डिवाइस पर चल रहे एचटीएमएल ऐप्लिकेशन.
भेजने वाले का फ़्रेमवर्क, ईमेल भेजने वाले को जानकारी देने के लिए एसिंक्रोनस कॉलबैक डिज़ाइन का इस्तेमाल करता है इवेंट का ऐप्लिकेशन और Cast ऐप्लिकेशन की लाइफ़ की अलग-अलग स्थितियों के बीच ट्रांज़िशन करने के लिए साइकल.
ऐप्लिकेशन फ़्लो
यहां दिए गए चरण, ईमेल भेजने वाले किसी व्यक्ति के लिए, आम तौर पर इस्तेमाल किए जाने वाले हाई-लेवल कार्ड के एक्ज़ीक्यूशन फ़्लो के बारे में बताते हैं Android ऐप्लिकेशन:
- कास्ट फ़्रेमवर्क अपने-आप शुरू हो जाता है
MediaRouter
डिवाइस को खोजने की प्रक्रिया,Activity
लाइफ़साइकल के आधार पर तय की गई है. - जब कोई उपयोगकर्ता 'कास्ट करें' बटन पर क्लिक करता है, तो फ़्रेमवर्क, कास्ट को दिखाता है खोजे गए कास्ट डिवाइसों की सूची के साथ डायलॉग बॉक्स.
- जब कोई उपयोगकर्ता किसी कास्ट डिवाइस को चुनता है, तो फ़्रेमवर्क कास्ट डिवाइस पर वेब रिसीवर ऐप्लिकेशन.
- फ़्रेमवर्क, सेंडर ऐप्लिकेशन में कॉलबैक शुरू करता है, ताकि यह पुष्टि की जा सके कि रिसीवर ऐप्लिकेशन लॉन्च किया गया.
- यह फ़्रेमवर्क, ईमेल भेजने वाले व्यक्ति और वेब पर बातचीत करने का चैनल बनाता है पाने वाले के ऐप्लिकेशन.
- यह फ़्रेमवर्क, मीडिया को लोड और कंट्रोल करने के लिए कम्यूनिकेशन चैनल का इस्तेमाल करता है वेब रिसीवर पर चलाया जा सकता है.
- यह फ़्रेमवर्क, मीडिया चलाने की स्थिति को मैसेज भेजने वाले व्यक्ति और उसकी रिपोर्ट के बीच सिंक करता है वेब रिसीवर: जब उपयोगकर्ता, ईमेल भेजने वाले के लिए यूज़र इंटरफ़ेस (यूआई) से जुड़ी कार्रवाइयां करता है, तो फ़्रेमवर्क पास हो जाता है वेब रिसीवर को किए गए वे मीडिया कंट्रोल अनुरोध और जब वेब रिसीवर को मीडिया की स्थिति के अपडेट भेजता है. साथ ही, फ़्रेमवर्क, भेजने वाले के यूज़र इंटरफ़ेस (यूआई) की स्थिति अपडेट करता है.
- जब उपयोगकर्ता किसी कास्ट डिवाइस से डिसकनेक्ट करने के लिए, 'कास्ट करें' बटन पर क्लिक करता है, फ़्रेमवर्क, भेजने वाले ऐप्लिकेशन को वेब रिसीवर से डिसकनेक्ट कर देगा.
Google Cast में सभी क्लास, तरीकों, और इवेंट की पूरी सूची देखने के लिए Android SDK टूल, Android. Android ऐप्लिकेशन में Cast को जोड़ने का तरीका नीचे बताया गया है.
Android मेनिफ़ेस्ट कॉन्फ़िगर करें
आपके ऐप्लिकेशन की AndroidManifest.xml फ़ाइल में, आपको इन्हें कॉन्फ़िगर करना होगा Cast SDK टूल के एलिमेंट:
एसडीके का इस्तेमाल
वे कम से कम और टारगेट Android API लेवल सेट करें जो Cast SDK पर काम करते हैं. फ़िलहाल, यह कम से कम एपीआई लेवल 23 पर सेट किया गया है और टारगेट यह है एपीआई लेवल 34.
<uses-sdk
android:minSdkVersion="23"
android:targetSdkVersion="34" />
android:theme
Android SDK के कम से कम वर्शन के आधार पर अपने ऐप्लिकेशन की थीम सेट करें. उदाहरण के लिए, अगर
आप अपनी स्वयं की थीम लागू नहीं कर रहे हैं, तो आपको
Android SDK के कम से कम वर्शन को टारगेट करने पर Theme.AppCompat
प्री-Lollipop.
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat" >
...
</application>
कास्ट कॉन्टेक्स्ट शुरू करें
फ़्रेमवर्क में ग्लोबल सिंगलटन ऑब्जेक्ट होता है, जिसे CastContext
कहते हैं. यह कोऑर्डिनेट है
फ़्रेमवर्क के सभी इंटरैक्शन को ट्रैक करने में मदद मिलती है.
आपके ऐप्लिकेशन को
OptionsProvider
शुरू करने के लिए ज़रूरी विकल्प उपलब्ध कराने वाला इंटरफ़ेस
CastContext
सिंगलटन. OptionsProvider
से पता चलता है कि
CastOptions
इसमें ऐसे विकल्प शामिल होते हैं जो फ़्रेमवर्क के व्यवहार पर असर डालते हैं. सबसे ज़्यादा
इनमें से सबसे ज़रूरी है वेब रिसीवर ऐप्लिकेशन आईडी. इसका इस्तेमाल फ़िल्टर करने के लिए किया जाता है
खोज के नतीजे पाने और कास्ट सेशन के चालू होने पर वेब रिसीवर ऐप्लिकेशन को लॉन्च करने के लिए
शुरू किया गया.
class CastOptionsProvider : OptionsProvider { override fun getCastOptions(context: Context): CastOptions { return Builder() .setReceiverApplicationId(context.getString(R.string.app_id)) .build() } override fun getAdditionalSessionProviders(context: Context): List<SessionProvider>? { return null } }
public class CastOptionsProvider implements OptionsProvider { @Override public CastOptions getCastOptions(Context context) { CastOptions castOptions = new CastOptions.Builder() .setReceiverApplicationId(context.getString(R.string.app_id)) .build(); return castOptions; } @Override public List<SessionProvider> getAdditionalSessionProviders(Context context) { return null; } }
आपको लागू किए गए OptionsProvider
का पूरी तरह क्वालिफ़ाइड नाम बताना होगा
भेजने वाले ऐप्लिकेशन की AndroidManifest.xml फ़ाइल में, मेटाडेटा फ़ील्ड के तौर पर:
<application>
...
<meta-data
android:name=
"com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="com.foo.CastOptionsProvider" />
</application>
CastContext.getSharedInstance()
जब CastContext
को लेज़ीली प्रोसेस से शुरू करता है, तो
को कॉल किया जाता है.
class MyActivity : FragmentActivity() { override fun onCreate(savedInstanceState: Bundle?) { val castContext = CastContext.getSharedInstance(this) } }
public class MyActivity extends FragmentActivity { @Override public void onCreate(Bundle savedInstanceState) { CastContext castContext = CastContext.getSharedInstance(this); } }
Cast UX विजेट
कास्ट फ़्रेमवर्क ऐसे विजेट उपलब्ध कराता है जो Cast डिज़ाइन का अनुपालन करते हैं चेकलिस्ट:
शुरुआती ओवरले: यह फ़्रेमवर्क एक कस्टम व्यू,
IntroductoryOverlay
, यह दिखाती है कि 'कास्ट करें' बटन पर उपयोगकर्ता का ध्यान खींचने के लिए जब कोई रिसीवर पहली बार उपलब्ध होता है. भेजने वाला ऐप्लिकेशन ये काम कर सकता है टेक्स्ट और टाइटल की पोज़िशन को पसंद के मुताबिक बनाएं टेक्स्ट.कास्ट करें बटन: कास्ट डिवाइस उपलब्ध होने पर भी 'कास्ट करें' बटन दिखता है. जब उपयोगकर्ता पहली बार 'कास्ट करें' बटन पर क्लिक करता है, तो 'कास्ट करें' डायलॉग दिखता है इसमें, खोजे गए डिवाइसों की सूची दी जाती है. जब उपयोगकर्ता 'कास्ट करें' बटन पर क्लिक करता है जब डिवाइस कनेक्ट होता है, तो यह वर्तमान मीडिया मेटाडेटा (जैसे उसके टाइटल, रिकॉर्डिंग स्टूडियो का नाम, और थंबनेल इमेज) या उपयोगकर्ताओं को कास्ट डिवाइस से डिसकनेक्ट करने के लिए. "कास्ट करें बटन" को कभी-कभी यह कहा जाता है इसे "कास्ट करें" आइकॉन पर क्लिक करें.
मिनी कंट्रोलर: जब कोई व्यक्ति कॉन्टेंट को कास्ट कर रहा हो और मौजूदा समय से बाहर चला गया हो भेजने वाले ऐप्लिकेशन की दूसरी स्क्रीन पर कॉन्टेंट पेज या बड़ा किया गया कंट्रोलर ऐक्सेस किया हो, तो स्क्रीन के सबसे नीचे मिनी कंट्रोलर दिखाया गया है, ताकि उपयोगकर्ता इन कामों को कर सके मीडिया कास्ट करने वाले मौजूदा मेटाडेटा को देखने और प्लेबैक को कंट्रोल करने के लिए.
एक्सपैंडेड कंट्रोलर: जब कोई उपयोगकर्ता कॉन्टेंट को कास्ट कर रहा हो, अगर वह मीडिया की सूचना पर क्लिक करे या मिनी कंट्रोलर, तो एक्सपैंडेड कंट्रोलर लॉन्च होता है, जो इस समय मीडिया मेटाडेटा चलाया जा रहा है और इसमें कंट्रोल करने के लिए कई बटन मौजूद हैं मीडिया प्लेबैक.
सूचना: सिर्फ़ Android के लिए. जब कोई व्यक्ति कॉन्टेंट को कास्ट कर रहा होता है और भेजने वाला ऐप्लिकेशन, मीडिया नोटिफ़िकेशन दिखाई देता है, जिसमें कास्ट किया जा रहा वर्तमान डिवाइस दिखता है मीडिया मेटाडेटा और प्लेबैक कंट्रोल.
लॉक स्क्रीन: सिर्फ़ Android के लिए. जब उपयोगकर्ता कॉन्टेंट को कास्ट कर रहा हो और डिवाइस को नेविगेट कर रहा हो समय) के लिए, लॉक स्क्रीन पर, एक मीडिया लॉक स्क्रीन नियंत्रण कास्ट किए जा रहे मीडिया मेटाडेटा और प्लेबैक कंट्रोल को दिखाता है.
नीचे दी गई गाइड में इन विजेट को जोड़ने के तरीके के बारे में बताया गया है आपका ऐप्लिकेशन.
'कास्ट करें' बटन जोड़ें
Android
MediaRouter
एपीआई को, सेकंडरी डिवाइसों पर मीडिया दिखाने और चलाने के लिए डिज़ाइन किया गया है.
MediaRouter
एपीआई का इस्तेमाल करने वाले Android ऐप्लिकेशन में 'कास्ट करें' बटन शामिल होना चाहिए
के यूज़र इंटरफ़ेस में शामिल किया गया है. इसकी मदद से लोग, मीडिया चलाने के लिए कोई मीडिया रूट चुन सकते हैं
कास्ट डिवाइस जैसा कोई दूसरा डिवाइस.
यह फ़्रेमवर्क
MediaRouteButton
इस रूप में
Cast button
बहुत आसान लगा. आपको सबसे पहले एक्सएमएल में कोई मेन्यू आइटम या MediaRouteButton
जोड़ना चाहिए
ऐसी फ़ाइल चुनें जो आपके मेन्यू को परिभाषित करती हो. साथ ही,
CastButtonFactory
ताकि इसे फ़्रेमवर्क के साथ अलाइन किया जा सके.
// To add a Cast button, add the following snippet.
// menu.xml
<item
android:id="@+id/media_route_menu_item"
android:title="@string/media_route_menu_title"
app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
app:showAsAction="always" />
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
// Then override the onCreateOptionMenu() for each of your activities. // MyActivity.kt override fun onCreateOptionsMenu(menu: Menu): Boolean { super.onCreateOptionsMenu(menu) menuInflater.inflate(R.menu.main, menu) CastButtonFactory.setUpMediaRouteButton( applicationContext, menu, R.id.media_route_menu_item ) return true }
// Then override the onCreateOptionMenu() for each of your activities. // MyActivity.java @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.main, menu); CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), menu, R.id.media_route_menu_item); return true; }
इसके बाद, अगर आपका Activity
यहां से इनहेरिट होता है
FragmentActivity
,
तुम जोड़ सकती हो
MediaRouteButton
भी शामिल हो सकते हैं.
// activity_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal" >
<androidx.mediarouter.app.MediaRouteButton
android:id="@+id/media_route_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:mediaRouteTypes="user"
android:visibility="gone" />
</LinearLayout>
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
// MyActivity.kt override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_layout) mMediaRouteButton = findViewById<View>(R.id.media_route_button) as MediaRouteButton CastButtonFactory.setUpMediaRouteButton(applicationContext, mMediaRouteButton) mCastContext = CastContext.getSharedInstance(this) }
// MyActivity.java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_layout); mMediaRouteButton = (MediaRouteButton) findViewById(R.id.media_route_button); CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), mMediaRouteButton); mCastContext = CastContext.getSharedInstance(this); }
किसी थीम का इस्तेमाल करके, 'कास्ट करें' बटन को दिखाने का तरीका सेट करने के लिए, देखें 'कास्ट करें' बटन को पसंद के मुताबिक बनाएं.
डिवाइस खोज कॉन्फ़िगर करें
डिवाइस को खोजने की सुविधा पूरी तरह से
CastContext
.
CastContext शुरू करते समय, भेजने वाले का ऐप्लिकेशन, वेब पाने वाले की जानकारी देता है
ऐप्लिकेशन आईडी शामिल कर सकता है और वैकल्पिक रूप से सेटिंग के ज़रिए नेमस्पेस फ़िल्टर करने का अनुरोध कर सकता है
supportedNamespaces
इंच
CastOptions
.
CastContext
के पास MediaRouter
का रेफ़रंस होता है और यह शुरू हो जाएगा
कुछ इस तरह की जानकारी उपलब्ध कराती है:
- यह एल्गोरिदम एक ऐसे एल्गोरिदम पर आधारित है जिसे डिवाइस खोजने में लगने वाले समय और बैटरी ख़र्च, खोजने की सुविधा कभी-कभी अपने-आप शुरू हो जाएगी. भेजने वाला ऐप्लिकेशन फ़ोरग्राउंड में आ जाता है.
- 'कास्ट करें' डायलॉग खुला हुआ है.
- Cast SDK टूल, कास्ट सेशन को वापस पाने की कोशिश कर रहा है.
कास्ट डायलॉग बंद होने पर या भेजने वाला ऐप्लिकेशन बैकग्राउंड में चला जाता है.
class CastOptionsProvider : OptionsProvider { companion object { const val CUSTOM_NAMESPACE = "urn:x-cast:custom_namespace" } override fun getCastOptions(appContext: Context): CastOptions { val supportedNamespaces: MutableList<String> = ArrayList() supportedNamespaces.add(CUSTOM_NAMESPACE) return CastOptions.Builder() .setReceiverApplicationId(context.getString(R.string.app_id)) .setSupportedNamespaces(supportedNamespaces) .build() } override fun getAdditionalSessionProviders(context: Context): List<SessionProvider>? { return null } }
class CastOptionsProvider implements OptionsProvider { public static final String CUSTOM_NAMESPACE = "urn:x-cast:custom_namespace"; @Override public CastOptions getCastOptions(Context appContext) { List<String> supportedNamespaces = new ArrayList<>(); supportedNamespaces.add(CUSTOM_NAMESPACE); CastOptions castOptions = new CastOptions.Builder() .setReceiverApplicationId(context.getString(R.string.app_id)) .setSupportedNamespaces(supportedNamespaces) .build(); return castOptions; } @Override public List<SessionProvider> getAdditionalSessionProviders(Context context) { return null; } }
सेशन मैनेजमेंट के काम करने का तरीका
Cast SDK टूल में, कास्ट सेशन का कॉन्सेप्ट दिखाया गया है, डिवाइस से कनेक्ट करने, वेब लॉन्च करने (या उसमें जुड़ने) के चरणों को जोड़कर बनाया जाता है पाने वाले ऐप्लिकेशन, उससे कनेक्ट करने, और मीडिया कंट्रोल चैनल शुरू करने की प्रोसेस. वेब रिसीवर देखें ऐप्लिकेशन की लाइफ़ साइकल से जुड़ी गाइड कास्ट सेशन और वेब रिसीवर की लाइफ़ साइकल के बारे में ज़्यादा जानें.
सेशन को क्लास मैनेज करती है
SessionManager
,
आपका ऐप्लिकेशन इसके ज़रिए ऐक्सेस कर सकता है
CastContext.getSessionManager()
.
अलग-अलग सेशन को क्लास के सब-क्लास के तौर पर दिखाया जाता है
Session
.
उदाहरण के लिए,
CastSession
कास्ट डिवाइसों वाले सेशन के बारे में बताता है. आपका ऐप्लिकेशन मौजूदा मोड को ऐक्सेस कर सकता है
इसके ज़रिए कास्ट सेशन
SessionManager.getCurrentCastSession()
.
आपका ऐप्लिकेशन
SessionManagerListener
क्लास इवेंट को मॉनिटर करने के लिए क्लास, जैसे कि बनाना, निलंबित करना, फिर से शुरू करना, और
समाप्ति. फ़्रेमवर्क अपने-आप ही
सेशन के दौरान असामान्य/अचानक बंद हो जाना.
उपयोगकर्ता के जेस्चर (हाव-भाव) के हिसाब से, सेशन अपने-आप बनते हैं और उनकी संख्या अपने-आप कम हो जाती है
MediaRouter
डायलॉग से लिया जा सकता है.
कास्ट शुरू करने से जुड़ी गड़बड़ियों को बेहतर ढंग से समझने के लिए, ऐप्लिकेशन
CastContext#getCastReasonCodeForCastStatusCode(int)
सत्र संबंधी शुरुआती गड़बड़ी को इसमें बदलने के लिए
CastReasonCodes
.
कृपया ध्यान दें कि सेशन शुरू होने से जुड़ी कुछ गड़बड़ियां (जैसे, CastReasonCodes#CAST_CANCELLED
)
मकसद तय करना हो और उसे किसी गड़बड़ी के तौर पर लॉग नहीं करना चाहिए.
अगर आपको सेशन की स्थिति में हुए बदलावों के बारे में जानकारी है, तो
SessionManagerListener
. इस उदाहरण में,
Activity
में CastSession
.
class MyActivity : Activity() { private var mCastSession: CastSession? = null private lateinit var mCastContext: CastContext private lateinit var mSessionManager: SessionManager private val mSessionManagerListener: SessionManagerListener<CastSession> = SessionManagerListenerImpl() private inner class SessionManagerListenerImpl : SessionManagerListener<CastSession?> { override fun onSessionStarting(session: CastSession?) {} override fun onSessionStarted(session: CastSession?, sessionId: String) { invalidateOptionsMenu() } override fun onSessionStartFailed(session: CastSession?, error: Int) { val castReasonCode = mCastContext.getCastReasonCodeForCastStatusCode(error) // Handle error } override fun onSessionSuspended(session: CastSession?, reason Int) {} override fun onSessionResuming(session: CastSession?, sessionId: String) {} override fun onSessionResumed(session: CastSession?, wasSuspended: Boolean) { invalidateOptionsMenu() } override fun onSessionResumeFailed(session: CastSession?, error: Int) {} override fun onSessionEnding(session: CastSession?) {} override fun onSessionEnded(session: CastSession?, error: Int) { finish() } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mCastContext = CastContext.getSharedInstance(this) mSessionManager = mCastContext.sessionManager mSessionManager.addSessionManagerListener(mSessionManagerListener, CastSession::class.java) } override fun onResume() { super.onResume() mCastSession = mSessionManager.currentCastSession } override fun onDestroy() { super.onDestroy() mSessionManager.removeSessionManagerListener(mSessionManagerListener, CastSession::class.java) } }
public class MyActivity extends Activity { private CastContext mCastContext; private CastSession mCastSession; private SessionManager mSessionManager; private SessionManagerListener<CastSession> mSessionManagerListener = new SessionManagerListenerImpl(); private class SessionManagerListenerImpl implements SessionManagerListener<CastSession> { @Override public void onSessionStarting(CastSession session) {} @Override public void onSessionStarted(CastSession session, String sessionId) { invalidateOptionsMenu(); } @Override public void onSessionStartFailed(CastSession session, int error) { int castReasonCode = mCastContext.getCastReasonCodeForCastStatusCode(error); // Handle error } @Override public void onSessionSuspended(CastSession session, int reason) {} @Override public void onSessionResuming(CastSession session, String sessionId) {} @Override public void onSessionResumed(CastSession session, boolean wasSuspended) { invalidateOptionsMenu(); } @Override public void onSessionResumeFailed(CastSession session, int error) {} @Override public void onSessionEnding(CastSession session) {} @Override public void onSessionEnded(CastSession session, int error) { finish(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mCastContext = CastContext.getSharedInstance(this); mSessionManager = mCastContext.getSessionManager(); mSessionManager.addSessionManagerListener(mSessionManagerListener, CastSession.class); } @Override protected void onResume() { super.onResume(); mCastSession = mSessionManager.getCurrentCastSession(); } @Override protected void onDestroy() { super.onDestroy(); mSessionManager.removeSessionManagerListener(mSessionManagerListener, CastSession.class); } }
स्ट्रीम को ट्रांसफ़र करें
सेशन की स्थिति को बनाए रखना, स्ट्रीम ट्रांसफ़र का आधार होता है, जहां उपयोगकर्ता, बोलकर निर्देश देने की सुविधा और Google Home का इस्तेमाल करके, मौजूदा ऑडियो और वीडियो स्ट्रीम को सभी डिवाइसों पर ले जा सकते हैं ऐप्लिकेशन या स्मार्ट डिसप्ले. मीडिया एक डिवाइस (सोर्स) पर चलना बंद हो जाता है और दूसरे डिवाइस पर चलता रहता है ( गंतव्य). सबसे नए फ़र्मवेयर वाला कोई भी कास्ट डिवाइस, स्ट्रीम ट्रांसफ़र करने के लिए किया जा सकता है.
स्ट्रीम ट्रांसफ़र या उसे बढ़ाने के दौरान, नया डिवाइस पाने के लिए,
रजिस्टर करो
Cast.Listener
इसका इस्तेमाल करके
CastSession#addCastListener
.
फिर कॉल करें
CastSession#getCastDevice()
onDeviceNameChanged
कॉलबैक के दौरान.
यहां जाएं: वेब रिसीवर पर स्ट्रीम ट्रांसफ़र करना हमारा वीडियो देखें.
अपने-आप फिर से कनेक्ट होने की सुविधा
यह फ़्रेमवर्क,
ReconnectionService
जिसे मैसेज भेजने वाले ऐप्लिकेशन की मदद से चालू किया जा सकता है, ताकि वे आसानी से फिर से कनेक्ट कर सकें
कोने के केस, जैसे:
- कुछ समय के लिए वाई-फ़ाई बंद हो जाने के बाद, डेटा वापस पाएं
- डिवाइस की स्लीप मोड से रिकवर करें
- ऐप्लिकेशन के बैकग्राउंड में बदलाव करके उसे वापस पाएं
- ऐप्लिकेशन क्रैश होने पर रिकवर करना
यह सेवा डिफ़ॉल्ट रूप से चालू होती है. इसे
CastOptions.Builder
.
अपने-आप मर्ज होने पर, यह सेवा आपके ऐप्लिकेशन के मेनिफ़ेस्ट में अपने-आप मर्ज हो सकती है आपकी gradle फ़ाइल में चालू है.
मीडिया सेशन होने पर फ़्रेमवर्क, सेवा को शुरू करेगा और उसे बंद कर देगा मीडिया सेशन खत्म हो जाएगा.
मीडिया कंट्रोल कैसे काम करता है
Cast फ़्रेमवर्क
RemoteMediaPlayer
नई क्लास के पक्ष में Cast 2.x से क्लास
RemoteMediaClient
जो ज़्यादा सुविधाजनक एपीआई के सेट में एक जैसी सुविधाएं देता है और
GoogleApiClient में पास करने की ज़रूरत से बचाता है.
जब आपका ऐप्लिकेशन
CastSession
मीडिया नेमस्पेस के साथ काम करने वाले वेब रिसीवर ऐप्लिकेशन के साथ, उदाहरण के लिए:
RemoteMediaClient
, फ़्रेमवर्क से अपने-आप बन जाएगा; आपका ऐप्लिकेशन ये काम कर सकता है
इसे ऐक्सेस करने के लिए, CastSession
पर getRemoteMediaClient()
तरीके को कॉल करें
इंस्टेंस.
वेब पाने वाले को अनुरोध भेजने वाले RemoteMediaClient
के सभी तरीकों से
नतीजे के तौर पर एक ऐसा ऑब्जेक्ट दें जिसका इस्तेमाल उस अनुरोध को ट्रैक करने के लिए किया जा सके.
उम्मीद है कि RemoteMediaClient
का इंस्टेंस इसे शेयर किया जा सकता है
कई हिस्सों में मौजूद होने चाहिए. साथ ही, इसमें कुछ इंटरनल कॉम्पोनेंट भी शामिल हैं
फ़्रेमवर्क, जैसे कि परसिस्टेंट मिनी कंट्रोलर और
सूचना देने वाली सेवा के बारे में जानकारी.
इसके लिए, इस इंस्टेंस में
RemoteMediaClient.Listener
.
मीडिया मेटाडेटा सेट करें
कॉन्टेंट बनाने
MediaMetadata
क्लास एक मीडिया आइटम की जानकारी दिखाती है, जिसे आप कास्ट करना चाहते हैं. कॉन्टेंट बनाने
नीचे दिया गया उदाहरण किसी मूवी का एक नया MediaMetadata इंस्टेंस बनाता है और
टाइटल, सबटाइटल, और दो इमेज.
val movieMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE) movieMetadata.putString(MediaMetadata.KEY_TITLE, mSelectedMedia.getTitle()) movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, mSelectedMedia.getStudio()) movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia.getImage(0)))) movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia.getImage(1))))
MediaMetadata movieMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE); movieMetadata.putString(MediaMetadata.KEY_TITLE, mSelectedMedia.getTitle()); movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, mSelectedMedia.getStudio()); movieMetadata.addImage(new WebImage(Uri.parse(mSelectedMedia.getImage(0)))); movieMetadata.addImage(new WebImage(Uri.parse(mSelectedMedia.getImage(1))));
यहां जाएं: इमेज चुनना के बारे में बात करते हैं.
मीडिया लोड करें
आपका ऐप्लिकेशन मीडिया आइटम लोड कर सकता है, जैसा कि इस कोड में दिखाया गया है. पहली बार इस्तेमाल किए जाने की तारीख
MediaInfo.Builder
मीडिया के मेटाडेटा के साथ किया जा सकता है.
MediaInfo
इंस्टेंस. पाएं
RemoteMediaClient
इसके बाद, मौजूदा CastSession
से MediaInfo
को लोड करें.
RemoteMediaClient
. चलाने, रोकने वगैरह के लिए RemoteMediaClient
का इस्तेमाल करें
वेब रिसीवर पर चल रहे मीडिया प्लेयर ऐप्लिकेशन को कंट्रोल करने के लिए.
val mediaInfo = MediaInfo.Builder(mSelectedMedia.getUrl()) .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) .setContentType("videos/mp4") .setMetadata(movieMetadata) .setStreamDuration(mSelectedMedia.getDuration() * 1000) .build() val remoteMediaClient = mCastSession.getRemoteMediaClient() remoteMediaClient.load(MediaLoadRequestData.Builder().setMediaInfo(mediaInfo).build())
MediaInfo mediaInfo = new MediaInfo.Builder(mSelectedMedia.getUrl()) .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) .setContentType("videos/mp4") .setMetadata(movieMetadata) .setStreamDuration(mSelectedMedia.getDuration() * 1000) .build(); RemoteMediaClient remoteMediaClient = mCastSession.getRemoteMediaClient(); remoteMediaClient.load(new MediaLoadRequestData.Builder().setMediaInfo(mediaInfo).build());
इस पर भी सेक्शन देखें मीडिया ट्रैक इस्तेमाल करके.
4K वीडियो फ़ॉर्मैट
यह देखने के लिए कि आपका मीडिया किस वीडियो फ़ॉर्मैट में है, इसका इस्तेमाल करें
getVideoInfo()
हाल ही का इंस्टेंस पाने के लिए, MediaStatus में
VideoInfo
.
इस इंस्टेंस में, एचडीआर टीवी के फ़ॉर्मैट का टाइप और डिसप्ले की ऊंचाई शामिल है
और चौड़ाई को पिक्सल में बदलें. 4K फ़ॉर्मैट वाले वैरिएंट को कॉन्सटेंट के हिसाब से दिखाया जाता है
HDR_TYPE_*
.
एक से ज़्यादा डिवाइसों पर रिमोट कंट्रोल की सुविधा
जब कोई उपयोगकर्ता कास्ट कर रहा होता है, तो एक ही नेटवर्क पर मौजूद दूसरे Android डिवाइसों को सूचना भेज दी जाएगी, ताकि वे वीडियो को कंट्रोल कर सकें. ऐसा कोई भी व्यक्ति जिसका डिवाइस अगर आपको इस तरह की सूचनाएं मिलती हैं, तो सेटिंग में जाकर उस डिवाइस के लिए सूचनाओं को बंद कर सकती है ऐप्लिकेशन डाउनलोड करें > Google Cast > रिमोट कंट्रोल से जुड़ी सूचनाएं दिखाना. (सूचनाओं में सेटिंग ऐप्लिकेशन का शॉर्टकट शामिल होता है.) ज़्यादा जानकारी के लिए, यह देखें रिमोट कंट्रोल से सूचनाएं कास्ट करने की सुविधा.
मिनी कंट्रोलर जोड़ें
Cast के डिज़ाइन के हिसाब से चेकलिस्ट, सेंडर ऐप्लिकेशन में लगातार एक कंट्रोल दिया जाना चाहिए, जिसे मिनी कंट्रोलर जो तब दिखनी चाहिए, जब उपयोगकर्ता मौजूदा कॉन्टेंट वाले पेज से किसी दूसरी जगह पर जाता है भेजने वाले ऐप्लिकेशन के किसी अन्य हिस्से का इस्तेमाल करता है. मिनी कंट्रोलर से दिखने वाला रिमाइंडर मिलता है मौजूदा कास्ट सेशन के उपयोगकर्ता को दिखता है. मिनी कंट्रोलर पर टैप करके, उपयोगकर्ता, कास्ट फ़ुल-स्क्रीन बड़े किए गए कंट्रोलर व्यू पर वापस जा सकता है.
यह फ़्रेमवर्क, एक कस्टम व्यू, MiniControllerफ़्रैगमेंट उपलब्ध कराता है, जिसे आप लेआउट फ़ाइल के निचले हिस्से पर सेव करें, जिसमें आप मिनी कंट्रोलर.
<fragment
android:id="@+id/castMiniController"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:visibility="gone"
class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment" />
जब आपका भेजने वाला ऐप्लिकेशन कोई वीडियो या ऑडियो लाइव स्ट्रीम चला रहा होता है, तो SDK टूल इसके बाद, 'चलाएं/रोकें' बटन के बजाय, अपने-आप एक 'चलाएं/बंद करें' बटन दिखाता है ट्रैक करने में मदद मिलती है.
इस कस्टम व्यू के टाइटल और सबटाइटल का टेक्स्ट, लेआउट सेट करने के लिए, और बटन चुनने के लिए, मिनी कंट्रोलर को पसंद के मुताबिक बनाएं.
बड़ा किया गया कंट्रोलर जोड़ें
Google Cast डिज़ाइन चेकलिस्ट के लिए आवश्यक है कि भेजने वाला ऐप्लिकेशन विस्तृत कंट्रोलर कास्ट किए जा रहे मीडिया के लिए. बड़ा किया गया कंट्रोलर, इसका फ़ुल स्क्रीन वर्शन है .
Cast SDK टूल, बड़े किए गए कंट्रोलर के लिए एक विजेट उपलब्ध कराता है
ExpandedControllerActivity
.
यह एक ऐब्स्ट्रैक्ट क्लास है, जिसे कास्ट बटन जोड़ने के लिए आपको सब-क्लास की ज़रूरत होती है.
सबसे पहले, बड़े किए गए कंट्रोलर के लिए एक नई मेन्यू रिसॉर्स फ़ाइल बनाएं, ताकि कास्ट बटन:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/media_route_menu_item"
android:title="@string/media_route_menu_title"
app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
app:showAsAction="always"/>
</menu>
ExpandedControllerActivity
का दायरा बढ़ाने वाली नई क्लास बनाएं.
class ExpandedControlsActivity : ExpandedControllerActivity() { override fun onCreateOptionsMenu(menu: Menu): Boolean { super.onCreateOptionsMenu(menu) menuInflater.inflate(R.menu.expanded_controller, menu) CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_menu_item) return true } }
public class ExpandedControlsActivity extends ExpandedControllerActivity { @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.expanded_controller, menu); CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_menu_item); return true; } }
अब ऐप्लिकेशन मेनिफ़ेस्ट में, application
टैग में अपनी नई गतिविधि के बारे में बताएं:
<application>
...
<activity
android:name=".expandedcontrols.ExpandedControlsActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:theme="@style/Theme.CastVideosDark"
android:screenOrientation="portrait"
android:parentActivityName="com.google.sample.cast.refplayer.VideoBrowserActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
...
</application>
CastOptionsProvider
में बदलाव करें और NotificationOptions
को बदलें. साथ ही,
टारगेट गतिविधि को अपनी नई गतिविधि के लिए सेट करने के लिए CastMediaOptions
:
override fun getCastOptions(context: Context): CastOptions? { val notificationOptions = NotificationOptions.Builder() .setTargetActivityClassName(ExpandedControlsActivity::class.java.name) .build() val mediaOptions = CastMediaOptions.Builder() .setNotificationOptions(notificationOptions) .setExpandedControllerActivityClassName(ExpandedControlsActivity::class.java.name) .build() return CastOptions.Builder() .setReceiverApplicationId(context.getString(R.string.app_id)) .setCastMediaOptions(mediaOptions) .build() }
public CastOptions getCastOptions(Context context) { NotificationOptions notificationOptions = new NotificationOptions.Builder() .setTargetActivityClassName(ExpandedControlsActivity.class.getName()) .build(); CastMediaOptions mediaOptions = new CastMediaOptions.Builder() .setNotificationOptions(notificationOptions) .setExpandedControllerActivityClassName(ExpandedControlsActivity.class.getName()) .build(); return new CastOptions.Builder() .setReceiverApplicationId(context.getString(R.string.app_id)) .setCastMediaOptions(mediaOptions) .build(); }
LocalPlayerActivity
loadRemoteMedia
तरीका अपडेट करें, ताकि
रिमोट मीडिया के लोड होने पर नई गतिविधि:
private fun loadRemoteMedia(position: Int, autoPlay: Boolean) { val remoteMediaClient = mCastSession?.remoteMediaClient ?: return remoteMediaClient.registerCallback(object : RemoteMediaClient.Callback() { override fun onStatusUpdated() { val intent = Intent(this@LocalPlayerActivity, ExpandedControlsActivity::class.java) startActivity(intent) remoteMediaClient.unregisterCallback(this) } }) remoteMediaClient.load( MediaLoadRequestData.Builder() .setMediaInfo(mSelectedMedia) .setAutoplay(autoPlay) .setCurrentTime(position.toLong()).build() ) }
private void loadRemoteMedia(int position, boolean autoPlay) { if (mCastSession == null) { return; } final RemoteMediaClient remoteMediaClient = mCastSession.getRemoteMediaClient(); if (remoteMediaClient == null) { return; } remoteMediaClient.registerCallback(new RemoteMediaClient.Callback() { @Override public void onStatusUpdated() { Intent intent = new Intent(LocalPlayerActivity.this, ExpandedControlsActivity.class); startActivity(intent); remoteMediaClient.unregisterCallback(this); } }); remoteMediaClient.load(new MediaLoadRequestData.Builder() .setMediaInfo(mSelectedMedia) .setAutoplay(autoPlay) .setCurrentTime(position).build()); }
जब आपका भेजने वाला ऐप्लिकेशन कोई वीडियो या ऑडियो लाइव स्ट्रीम चला रहा होता है, तो SDK टूल इसके बाद, 'चलाएं/रोकें' बटन के बजाय, अपने-आप एक 'चलाएं/बंद करें' बटन दिखाता है का विकल्प भी चुना जा सकता है.
थीम का इस्तेमाल करके थीम सेट करने के लिए, चुनें कि कौनसे बटन दिखाने हैं. कस्टम बटन जोड़ने या कस्टम बटन जोड़ने के लिए, एक्सपैंडेड कंट्रोलर को पसंद के मुताबिक बनाएं.
आवाज़ कंट्रोल करें
यह फ़्रेमवर्क, ईमेल भेजने वाले ऐप्लिकेशन की आवाज़ को अपने-आप मैनेज करता है. फ़्रेमवर्क भेजने वाले और वेब पाने वाले ऐप्लिकेशन को अपने-आप सिंक कर देता है, ताकि भेजने वाला यूज़र इंटरफ़ेस (यूआई), वेब रिसीवर के तय किए गए वॉल्यूम को हमेशा रिपोर्ट करता है.
फ़िज़िकल बटन की आवाज़ को कम या ज़्यादा करने का बटन
Android पर, भेजने वाले के डिवाइस पर मौजूद फ़िज़िकल बटन का इस्तेमाल करके, का उपयोग करने वाले किसी भी डिवाइस के लिए डिफ़ॉल्ट रूप से वेब रिसीवर पर कास्ट सत्र की मात्रा जैली बीन या उसके बाद का वर्शन.
जैली बीन से पहले वास्तविक बटन वॉल्यूम नियंत्रण
वेब रिसीवर डिवाइस वॉल्यूम को चालू करने के लिए भौतिक वॉल्यूम कुंजियों का उपयोग करने के लिए
जैली बीन से पुराने Android डिवाइस, भेजने वाले ऐप्लिकेशन को ओवरराइड करना चाहिए
dispatchKeyEvent
उनकी गतिविधियों में और
CastContext.onDispatchVolumeKeyEventBeforeJellyBean()
:
class MyActivity : FragmentActivity() { override fun dispatchKeyEvent(event: KeyEvent): Boolean { return (CastContext.getSharedInstance(this) .onDispatchVolumeKeyEventBeforeJellyBean(event) || super.dispatchKeyEvent(event)) } }
class MyActivity extends FragmentActivity { @Override public boolean dispatchKeyEvent(KeyEvent event) { return CastContext.getSharedInstance(this) .onDispatchVolumeKeyEventBeforeJellyBean(event) || super.dispatchKeyEvent(event); } }
सूचना और लॉक स्क्रीन पर मीडिया कंट्रोल जोड़ें
केवल Android पर, Google Cast डिज़ाइन चेकलिस्ट के लिए यह आवश्यक है कि
किसी वीडियो या विज्ञापन इन्वेंट्री में
सूचना
और लॉक में
स्क्रीन,
जहां कॉन्टेंट कास्ट किया जा रहा हो, लेकिन भेजने वाले के ऐप्लिकेशन पर फ़ोकस न हो. कॉन्टेंट बनाने
फ़्रेमवर्क उपलब्ध कराता है
MediaNotificationService
और
MediaIntentReceiver
सूचना और लॉक सेटिंग में, सेंडर ऐप्लिकेशन को मीडिया कंट्रोल बनाने में मदद करने के लिए
स्क्रीन.
जब भेजने वाला व्यक्ति कास्ट कर रहा होता है, तब MediaNotificationService
चलता है. साथ ही, यह
इमेज के थंबनेल के साथ सूचना और मौजूदा कास्टिंग के बारे में जानकारी
आइटम, चलाएं/रोकें बटन, और 'रोकें' बटन.
MediaIntentReceiver
एक BroadcastReceiver
है, जो उपयोगकर्ता की कार्रवाइयों को मैनेज करता है
सूचना पर टैप करें.
आपका ऐप्लिकेशन, लॉक स्क्रीन से सूचना और मीडिया कंट्रोल करने की सुविधा को कॉन्फ़िगर कर सकता है
NotificationOptions
.
आपका ऐप्लिकेशन यह कॉन्फ़िगर कर सकता है कि सूचना में कौनसे कंट्रोल बटन दिखाए जाएं और
उपयोगकर्ता के सूचना पर टैप करने पर कौनसा Activity
खोलना होगा. अगर कार्रवाइयां
साफ़ तौर पर नहीं दिए गए हैं, डिफ़ॉल्ट वैल्यू,
MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK
और
MediaIntentReceiver.ACTION_STOP_CASTING
का इस्तेमाल किया जाएगा.
// Example showing 4 buttons: "rewind", "play/pause", "forward" and "stop casting". val buttonActions: MutableList<String> = ArrayList() buttonActions.add(MediaIntentReceiver.ACTION_REWIND) buttonActions.add(MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK) buttonActions.add(MediaIntentReceiver.ACTION_FORWARD) buttonActions.add(MediaIntentReceiver.ACTION_STOP_CASTING) // Showing "play/pause" and "stop casting" in the compat view of the notification. val compatButtonActionsIndices = intArrayOf(1, 3) // Builds a notification with the above actions. Each tap on the "rewind" and "forward" buttons skips 30 seconds. // Tapping on the notification opens an Activity with class VideoBrowserActivity. val notificationOptions = NotificationOptions.Builder() .setActions(buttonActions, compatButtonActionsIndices) .setSkipStepMs(30 * DateUtils.SECOND_IN_MILLIS) .setTargetActivityClassName(VideoBrowserActivity::class.java.name) .build()
// Example showing 4 buttons: "rewind", "play/pause", "forward" and "stop casting". List<String> buttonActions = new ArrayList<>(); buttonActions.add(MediaIntentReceiver.ACTION_REWIND); buttonActions.add(MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK); buttonActions.add(MediaIntentReceiver.ACTION_FORWARD); buttonActions.add(MediaIntentReceiver.ACTION_STOP_CASTING); // Showing "play/pause" and "stop casting" in the compat view of the notification. int[] compatButtonActionsIndices = new int[]{1, 3}; // Builds a notification with the above actions. Each tap on the "rewind" and "forward" buttons skips 30 seconds. // Tapping on the notification opens an Activity with class VideoBrowserActivity. NotificationOptions notificationOptions = new NotificationOptions.Builder() .setActions(buttonActions, compatButtonActionsIndices) .setSkipStepMs(30 * DateUtils.SECOND_IN_MILLIS) .setTargetActivityClassName(VideoBrowserActivity.class.getName()) .build();
सूचना और लॉक स्क्रीन पर, मीडिया कंट्रोल दिखाने की सुविधा इन चीज़ों से चालू है
डिफ़ॉल्ट है और इसे
setNotificationOptions
खाली है
CastMediaOptions.Builder
.
फ़िलहाल, लॉक स्क्रीन की सुविधा तब तक चालू रहती है, जब तक सूचना पाने की सुविधा चालू नहीं होती
चालू है.
// ... continue with the NotificationOptions built above val mediaOptions = CastMediaOptions.Builder() .setNotificationOptions(notificationOptions) .build() val castOptions: CastOptions = Builder() .setReceiverApplicationId(context.getString(R.string.app_id)) .setCastMediaOptions(mediaOptions) .build()
// ... continue with the NotificationOptions built above CastMediaOptions mediaOptions = new CastMediaOptions.Builder() .setNotificationOptions(notificationOptions) .build(); CastOptions castOptions = new CastOptions.Builder() .setReceiverApplicationId(context.getString(R.string.app_id)) .setCastMediaOptions(mediaOptions) .build();
जब आपका भेजने वाला ऐप्लिकेशन कोई वीडियो या ऑडियो लाइव स्ट्रीम चला रहा होता है, तो SDK टूल इसके बाद, 'चलाएं/रोकें' बटन के बजाय, अपने-आप एक 'चलाएं/बंद करें' बटन दिखाता है सूचना नियंत्रण पर हैं, लेकिन लॉक स्क्रीन नियंत्रण पर नहीं.
ध्यान दें: प्री-Lollipop डिवाइसों पर लॉक स्क्रीन कंट्रोल दिखाने के लिए,
RemoteMediaClient
आपकी ओर से ऑडियो फ़ोकस का अनुरोध अपने-आप करेगा.
गड़बड़ियां ठीक करना
भेजने वाले ऐप्लिकेशन के लिए यह बहुत ज़रूरी है कि वे सभी गड़बड़ी के कॉलबैक को हैंडल करें और तय करें कास्ट लाइफ़ साइकल के हर स्टेज के लिए सबसे सही जवाब. ऐप्लिकेशन, यह जानकारी दिखा सकता है उपयोगकर्ता को गड़बड़ी वाले डायलॉग दिखाए जा सकते हैं या वह इसके साथ कनेक्शन को बंद कर सकता है वेब रिसीवर.