इस डेवलपर गाइड में बताया गया है कि iOS भेजने वाले SDK टूल का इस्तेमाल करके अपने iOS भेजने वाले ऐप्लिकेशन में Google Cast सहायता कैसे जोड़ें.
मोबाइल डिवाइस या लैपटॉप भेजने वाला है जो प्लेबैक को कंट्रोल करता है और Google Cast डिवाइस पाने वाला होता है जो टीवी पर कॉन्टेंट दिखाता है.
भेजने वाले का फ़्रेमवर्क, कास्ट क्लास लाइब्रेरी की बाइनरी और उससे जुड़े रिसॉर्स के बारे में बताता है, जो भेजने वाले के रनटाइम के दौरान मौजूद होते हैं. भेजने वाले का ऐप्लिकेशन या कास्ट ऐप्लिकेशन का मतलब है कि भेजने वाले के पास मौजूद ऐप्लिकेशन भी चल रहा है. वेब रिसीवर ऐप्लिकेशन का मतलब है, वेब रिसीवर पर चल रहा एचटीएमएल ऐप्लिकेशन.
सेंडर फ़्रेमवर्क, भेजने वाले ऐप्लिकेशन को इवेंट की जानकारी देने और Cast ऐप्लिकेशन की लाइफ़साइकल की अलग-अलग स्थितियों के बीच ट्रांज़िशन के लिए, एसिंक्रोनस कॉलबैक डिज़ाइन का इस्तेमाल करता है.
ऐप्लिकेशन फ़्लो
नीचे दिए गए चरणों से, iOS ऐप्लिकेशन भेजने वाले लोगों के लिए, सामान्य तौर पर हाई-लेवल एक्ज़ीक्यूशन फ़्लो की जानकारी मिलती है:
- डिवाइसों को स्कैन करने के लिए, कास्ट फ़्रेमवर्क,
GCKCastOptions
में दी गई प्रॉपर्टी के आधार परGCKDiscoveryManager
शुरू होता है. - जब लोग 'कास्ट करें' बटन पर क्लिक करते हैं, तो फ़्रेमवर्क, खोजे गए कास्ट डिवाइसों की सूची के साथ कास्ट डायलॉग दिखाता है.
- जब उपयोगकर्ता कोई कास्ट डिवाइस चुनता है, तो फ़्रेमवर्क कास्ट डिवाइस पर वेब रिसीवर ऐप्लिकेशन को लॉन्च करने की कोशिश करता है.
- यह फ़्रेमवर्क, वेब रिसीवर ऐप्लिकेशन लॉन्च हो गया है या नहीं, इसकी पुष्टि करने के लिए भेजने वाले ऐप्लिकेशन में कॉलबैक को शुरू करता है.
- यह फ़्रेमवर्क, भेजने वाले और वेब रिसीवर ऐप्लिकेशन के बीच एक कम्यूनिकेशन चैनल बनाता है.
- यह फ़्रेमवर्क वेब रिसीवर पर मीडिया प्लेबैक को लोड और कंट्रोल करने के लिए कम्यूनिकेशन चैनल का इस्तेमाल करता है.
- फ़्रेमवर्क, मीडिया प्लेबैक स्थिति को भेजने वाले और वेब पाने वाले के बीच सिंक करता है: जब उपयोगकर्ता भेजने वाले के यूज़र इंटरफ़ेस (यूआई) से जुड़ी कार्रवाइयां करता है, तब फ़्रेमवर्क उन मीडिया कंट्रोल के अनुरोधों को वेब रिसीवर को पास करता है. जब वेब रिसीवर मीडिया की स्थिति के अपडेट भेजता है, तब फ़्रेमवर्क भेजने वाले के यूज़र इंटरफ़ेस (यूआई) की स्थिति को अपडेट करता है.
- जब कास्ट डिवाइस से डिसकनेक्ट करने के लिए उपयोगकर्ता, 'कास्ट करें' बटन पर क्लिक करता है, तो फ़्रेमवर्क भेजने वाले ऐप्लिकेशन को वेब रिसीवर से डिसकनेक्ट कर देगा.
भेजने वाले की समस्या हल करने के लिए, आपको लॉगिंग की सुविधा चालू करनी होगी.
Google Cast iOS फ़्रेमवर्क में सभी क्लास, तरीकों, और इवेंट की पूरी सूची देखने के लिए, Google Cast iOS API रेफ़रंस देखें. नीचे दिए सेक्शन में, iOS ऐप्लिकेशन में कास्ट को इंटिग्रेट करने का तरीका बताया गया है.
मुख्य थ्रेड से कॉल के तरीके
कास्ट कॉन्टेक्स्ट शुरू करें
कास्ट फ़्रेमवर्क में एक ग्लोबल सिंगलटन ऑब्जेक्ट, GCKCastContext
होता है. यह फ़्रेमवर्क की सभी गतिविधियों को कोऑर्डिनेट करता है. ऐप्लिकेशन के लाइफ़साइकल की शुरुआत में ही इस ऑब्जेक्ट को शुरू किया जाना चाहिए. आम तौर पर, ऐप्लिकेशन का ऐक्सेस देने के -[application:didFinishLaunchingWithOptions:]
तरीके से, इसे शुरू किया जाना चाहिए. इससे, भेजने वाले ऐप्लिकेशन के रीस्टार्ट होने पर, अपने-आप सेशन फिर से शुरू होने की सुविधा ठीक से ट्रिगर हो सकेगी.
GCKCastContext
को शुरू करते समय, GCKCastOptions
ऑब्जेक्ट देना ज़रूरी है.
इस क्लास में ऐसे विकल्प हैं जो फ़्रेमवर्क के व्यवहार पर असर डालते हैं. वेब रिसीवर ऐप्लिकेशन आईडी इनमें से सबसे ज़्यादा ज़रूरी है. इसका इस्तेमाल खोज नतीजों को फ़िल्टर करने और कास्ट सेशन शुरू होने पर वेब रिसीवर ऐप्लिकेशन को लॉन्च करने के लिए किया जाता है.
फ़्रेमवर्क से लॉगिंग मैसेज पाने के लिए, लॉग इन करने वाले किसी व्यक्ति को सेट अप करने के लिए भी -[application:didFinishLaunchingWithOptions:]
तरीका अच्छा विकल्प है.
इनसे, डीबग करने और समस्या हल करने में मदद मिल सकती है.
@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, GCKLoggerDelegate { let kReceiverAppID = kGCKDefaultMediaReceiverApplicationID let kDebugLoggingEnabled = true var window: UIWindow? func applicationDidFinishLaunching(_ application: UIApplication) { let criteria = GCKDiscoveryCriteria(applicationID: kReceiverAppID) let options = GCKCastOptions(discoveryCriteria: criteria) GCKCastContext.setSharedInstanceWith(options) // Enable logger. GCKLogger.sharedInstance().delegate = self ... } // MARK: - GCKLoggerDelegate func logMessage(_ message: String, at level: GCKLoggerLevel, fromFunction function: String, location: String) { if (kDebugLoggingEnabled) { print(function + " - " + message) } } }
AppDelegate.h
@interface AppDelegate () <GCKLoggerDelegate> @end
AppDelegate.m
@implementation AppDelegate static NSString *const kReceiverAppID = @"AABBCCDD"; static const BOOL kDebugLoggingEnabled = YES; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { GCKDiscoveryCriteria *criteria = [[GCKDiscoveryCriteria alloc] initWithApplicationID:kReceiverAppID]; GCKCastOptions *options = [[GCKCastOptions alloc] initWithDiscoveryCriteria:criteria]; [GCKCastContext setSharedInstanceWithOptions:options]; // Enable logger. [GCKLogger sharedInstance].delegate = self; ... return YES; } ... #pragma mark - GCKLoggerDelegate - (void)logMessage:(NSString *)message atLevel:(GCKLoggerLevel)level fromFunction:(NSString *)function location:(NSString *)location { if (kDebugLoggingEnabled) { NSLog(@"%@ - %@, %@", function, message, location); } } @end
Cast UX विजेट
Cast iOS SDK टूल में ये विजेट उपलब्ध होते हैं, जो Cast डिज़ाइन चेकलिस्ट का पालन करते हैं:
शुरुआती ओवरले:
GCKCastContext
क्लास में एक तरीका है,presentCastInstructionsViewControllerOnceWithCastButton
, जिसका इस्तेमाल वेब रिसीवर के पहली बार उपलब्ध होने पर कास्ट बटन को हाइलाइट करने के लिए किया जा सकता है. भेजने वाला ऐप्लिकेशन, टेक्स्ट, शीर्षक के टेक्स्ट की जगह, और 'खारिज करें' बटन को अपनी पसंद के मुताबिक बना सकता है.कास्ट करें बटन: Cast iOS भेजने वाले SDK टूल के 4.6.0 वर्शन में, भेजने वाले डिवाइस के वाई-फ़ाई से कनेक्ट होने पर कास्ट बटन हमेशा दिखता है. ऐप्लिकेशन चालू करने के बाद, जब उपयोगकर्ता पहली बार कास्ट बटन पर टैप करता है, तो एक अनुमति डायलॉग दिखता है. इससे उपयोगकर्ता, ऐप्लिकेशन को लोकल नेटवर्क पर मौजूद डिवाइसों को ऐक्सेस दे सकता है. इसके बाद, जब लोग कास्ट करें बटन पर टैप करते हैं, तब एक कास्ट डायलॉग दिखता है, जिसमें खोजे गए डिवाइसों की सूची होती है. डिवाइस से कनेक्ट होने के दौरान, जब उपयोगकर्ता कास्ट बटन पर टैप करता है, तो वह मौजूदा मीडिया मेटाडेटा (जैसे, टाइटल, रिकॉर्डिंग स्टूडियो का नाम, और थंबनेल इमेज) दिखाता है या उपयोगकर्ता को कास्ट डिवाइस से डिसकनेक्ट करने की अनुमति देता है. जब डिवाइस उपलब्ध न हों, तब जब लोग कास्ट बटन पर टैप करेंगे, तो उन्हें एक स्क्रीन दिखेगी. उपयोगकर्ता को डिवाइस नहीं मिलने की वजह और समस्या हल करने का तरीक़ा बताया जाएगा.
मिनी कंट्रोलर: जब उपयोगकर्ता, कॉन्टेंट को कास्ट कर रहा होता है और कॉन्टेंट भेजने वाले ऐप्लिकेशन में किसी दूसरी स्क्रीन पर जाता है, तो स्क्रीन पर सबसे नीचे मिनी कंट्रोलर दिखता है. इससे उपयोगकर्ता, कास्ट किए जा रहे मौजूदा मीडिया मेटाडेटा को देख सकता है और वीडियो को कंट्रोल कर सकता है.
बड़ा कंट्रोलर: कॉन्टेंट कास्ट करते समय, अगर उपयोगकर्ता मीडिया नोटिफ़िकेशन या मिनी कंट्रोलर पर क्लिक करता है, तो एक्सपैंडेड कंट्रोलर लॉन्च हो जाता है. इससे मीडिया का मौजूदा मेटाडेटा दिखता है और मीडिया प्लेबैक को कंट्रोल करने के लिए कई बटन मिलते हैं.
कास्ट बटन जोड़ें
यह फ़्रेमवर्क, UIButton
सब-क्लास के तौर पर कास्ट बटन कॉम्पोनेंट उपलब्ध कराता है. इसे UIBarButtonItem
में रैप करके, ऐप्लिकेशन के टाइटल बार में जोड़ा जा सकता है. एक सामान्य UIViewController
सब-क्लास, कास्ट बटन को इस तरह इंस्टॉल कर सकती है:
let castButton = GCKUICastButton(frame: CGRect(x: 0, y: 0, width: 24, height: 24)) castButton.tintColor = UIColor.gray navigationItem.rightBarButtonItem = UIBarButtonItem(customView: castButton)
GCKUICastButton *castButton = [[GCKUICastButton alloc] initWithFrame:CGRectMake(0, 0, 24, 24)]; castButton.tintColor = [UIColor grayColor]; self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:castButton];
डिफ़ॉल्ट रूप से, इस बटन पर टैप करने से 'कास्ट करें' डायलॉग बॉक्स खुलेगा, जो आपको फ़्रेमवर्क से मिला होगा.
GCKUICastButton
को सीधे स्टोरीबोर्ड में भी जोड़ा जा सकता है.
डिवाइस डिस्कवरी की सुविधा को कॉन्फ़िगर करें
फ़्रेमवर्क में डिवाइस को अपने-आप खोजा जाता है. जब तक कस्टम यूज़र इंटरफ़ेस (यूआई) लागू नहीं किया जाता, तब तक खोज की प्रोसेस को अलग से शुरू या बंद करने की ज़रूरत नहीं होती.
फ़्रेमवर्क में खोज की सुविधा को GCKDiscoveryManager
क्लास से मैनेज करता है, जो GCKCastContext
की प्रॉपर्टी है. फ़्रेमवर्क, डिवाइस चुनने और कंट्रोल के लिए डिफ़ॉल्ट कास्ट डायलॉग कॉम्पोनेंट उपलब्ध कराता है. डिवाइस की सूची, डिवाइस के साथ काम करने वाले नाम के हिसाब से शब्दकोश के मुताबिक क्रम में लगाई गई है.
सेशन मैनेजमेंट के काम करने का तरीका
Cast SDK टूल, कास्ट सेशन का कॉन्सेप्ट बताता है. इसमें बताया जाता है कि डिवाइस से कनेक्ट करने, वेब रिसीवर ऐप्लिकेशन को लॉन्च करने या उसमें शामिल होने, उस ऐप्लिकेशन से कनेक्ट होने, और मीडिया कंट्रोल चैनल को शुरू करने के चरण क्या हैं. कास्ट सेशन और वेब रिसीवर की लाइफ़ साइकल के बारे में ज़्यादा जानने के लिए, वेब रिसीवर पर ऐप्लिकेशन की लाइफ़ साइकल से जुड़ी गाइड देखें.
सेशन को क्लास GCKSessionManager
मैनेज करती है, जो GCKCastContext
की प्रॉपर्टी है.
अलग-अलग सेशन को क्लास के सब-क्लास से दिखाया जाता है
GCKSession
: उदाहरण के लिए,
GCKCastSession
कास्ट डिवाइसों वाले सेशन को दिखाता है. मौजूदा कास्ट सेशन (अगर कोई है) को GCKSessionManager
की currentCastSession
प्रॉपर्टी के तौर पर ऐक्सेस किया जा सकता है.
GCKSessionManagerListener
इंटरफ़ेस का इस्तेमाल, सेशन इवेंट को मॉनिटर करने के लिए किया जा सकता है. जैसे, सेशन बनाना, निलंबन, फिर से शुरू करना, और खत्म करना. जब भेजने वाला ऐप्लिकेशन बैकग्राउंड में जाता है, तो फ़्रेमवर्क अपने-आप सेशन को निलंबित कर देता है. साथ ही, जब ऐप्लिकेशन फ़ोरग्राउंड में वापस आता है,
या फिर सेशन के चालू रहने पर, असामान्य/अचानक ऐप्लिकेशन बंद होने पर, इसे फिर से लॉन्च करने की कोशिश करता है, तब
यह फ़्रेमवर्क सेशन को अपने-आप निलंबित कर देता है.
अगर 'कास्ट करें' डायलॉग का इस्तेमाल किया जा रहा है, तो उपयोगकर्ता के जेस्चर की वजह से, सेशन अपने-आप शुरू हो जाते हैं और बंद हो जाते हैं. ऐसा नहीं करने पर, ऐप्लिकेशन GCKSessionManager
पर मौजूद तरीकों की मदद से, सेशन को शुरू और खत्म कर सकता है.
अगर ऐप्लिकेशन को सेशन के लाइफ़साइकल इवेंट की वजह से खास प्रोसेसिंग की ज़रूरत होती है, तो वह GCKSessionManager
के साथ एक या एक से ज़्यादा GCKSessionManagerListener
इंस्टेंस रजिस्टर कर सकता है. GCKSessionManagerListener
एक प्रोटोकॉल है, जो ऐसे इवेंट के लिए कॉलबैक के बारे में बताता है, जैसे कि सेशन शुरू होना, सेशन खत्म होना वगैरह.
स्ट्रीम का डेटा ट्रांसफ़र करें
सेशन की स्थिति बनाए रखना, स्ट्रीम को ट्रांसफ़र करने का आधार है. इससे उपयोगकर्ता, बोलकर दिए जाने वाले निर्देशों, Google Home ऐप्लिकेशन या स्मार्ट डिसप्ले का इस्तेमाल करके, मौजूदा ऑडियो और वीडियो स्ट्रीम को अलग-अलग डिवाइसों पर ले जा सकते हैं. मीडिया एक डिवाइस (सोर्स) पर चलना बंद हो जाता है और दूसरे डिवाइस (डेस्टिनेशन) पर चलता रहता है. नए फ़र्मवेयर वाला कोई भी कास्ट डिवाइस, स्ट्रीम ट्रांसफ़र में सोर्स या डेस्टिनेशन के तौर पर काम कर सकता है.
स्ट्रीम ट्रांसफ़र के दौरान नया डेस्टिनेशन डिवाइस पाने के लिए, [sessionManager:didResumeCastSession:]
कॉलबैक के दौरान GCKCastSession#device
प्रॉपर्टी का इस्तेमाल करें.
ज़्यादा जानकारी के लिए, वेब रिसीवर पर स्ट्रीम ट्रांसफ़र देखें.
अपने-आप फिर से कनेक्ट होना
कास्ट फ़्रेमवर्क, रीकनेक्टेशन लॉजिक को जोड़ देता है, ताकि यह कई छोटे कॉर्नर केस में अपने-आप फिर से कनेक्ट होने की समस्या को हैंडल कर सके, जैसे:
- कुछ समय के लिए वाई-फ़ाई बंद हो जाने पर उसे रिकवर करना
- डिवाइस के स्लीप मोड में जाने से रिकवर होना
- ऐप्लिकेशन को बैकग्राउंड में चलने से रिकवर करें
- ऐप्लिकेशन क्रैश होने पर उसे रिकवर करना
मीडिया कंट्रोल के काम करने का तरीका
अगर कास्ट सेशन को किसी ऐसे वेब रिसीवर ऐप्लिकेशन के साथ बनाया गया है जो मीडिया
नेमस्पेस के साथ काम करता है, तो फ़्रेमवर्क के ज़रिए GCKRemoteMediaClient
का एक इंस्टेंस अपने-आप बन जाएगा. इसे GCKCastSession
इंस्टेंस की remoteMediaClient
प्रॉपर्टी के तौर पर ऐक्सेस किया जा सकता है.
GCKRemoteMediaClient
पर मौजूद जिन तरीकों से वेब रिसीवर को समस्या आती है वे सभी GCKRequest
ऑब्जेक्ट दिखाएंगे. इसका इस्तेमाल उस अनुरोध को ट्रैक करने के लिए किया जा सकता है. कार्रवाई के आखिरी नतीजे के बारे में सूचनाएं पाने के लिए, इस ऑब्जेक्ट को GCKRequestDelegate
असाइन किया जा सकता है.
उम्मीद की जाती है कि GCKRemoteMediaClient
के इंस्टेंस को ऐप्लिकेशन के कई हिस्सों में शेयर किया जा सकता है और फ़्रेमवर्क के कुछ अंदरूनी कॉम्पोनेंट, जैसे कि कास्ट डायलॉग और मिनी मीडिया कंट्रोल भी इस इंस्टेंस को शेयर करते हैं. खत्म होने के बाद, GCKRemoteMediaClient
एक से ज़्यादा GCKRemoteMediaClientListener
के रजिस्ट्रेशन की सुविधा देता है.
मीडिया मेटाडेटा सेट करें
GCKMediaMetadata
क्लास, उस मीडिया आइटम के बारे में जानकारी दिखाती है जिसे आपको कास्ट करना है. नीचे दिए गए उदाहरण से, मूवी का एक नया GCKMediaMetadata
इंस्टेंस बनाया जाता है. साथ ही, टाइटल, सबटाइटल, रिकॉर्डिंग स्टूडियो का नाम, और दो इमेज सेट की जाती हैं.
let metadata = GCKMediaMetadata() metadata.setString("Big Buck Bunny (2008)", forKey: kGCKMetadataKeyTitle) metadata.setString("Big Buck Bunny tells the story of a giant rabbit with a heart bigger than " + "himself. When one sunny day three rodents rudely harass him, something " + "snaps... and the rabbit ain't no bunny anymore! In the typical cartoon " + "tradition he prepares the nasty rodents a comical revenge.", forKey: kGCKMetadataKeySubtitle) metadata.addImage(GCKImage(url: URL(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg")!, width: 480, height: 360))
GCKMediaMetadata *metadata = [[GCKMediaMetadata alloc] initWithMetadataType:GCKMediaMetadataTypeMovie]; [metadata setString:@"Big Buck Bunny (2008)" forKey:kGCKMetadataKeyTitle]; [metadata setString:@"Big Buck Bunny tells the story of a giant rabbit with a heart bigger than " "himself. When one sunny day three rodents rudely harass him, something " "snaps... and the rabbit ain't no bunny anymore! In the typical cartoon " "tradition he prepares the nasty rodents a comical revenge." forKey:kGCKMetadataKeySubtitle]; [metadata addImage:[[GCKImage alloc] initWithURL:[[NSURL alloc] initWithString:@"https://commondatastorage.googleapis.com/" "gtv-videos-bucket/sample/images/BigBuckBunny.jpg"] width:480 height:360]];
मीडिया मेटाडेटा के साथ इमेज इस्तेमाल करने के बारे में जानने के लिए, इमेज चुनना और कैश मेमोरी में सेव करना सेक्शन देखें.
मीडिया लोड करें
मीडिया आइटम लोड करने के लिए, मीडिया के मेटाडेटा का इस्तेमाल करके
GCKMediaInformation
इंस्टेंस बनाएं. इसके बाद, मौजूदा
GCKCastSession
पाएं और
रिसीवर ऐप्लिकेशन पर मीडिया लोड करने के लिए, इसके
GCKRemoteMediaClient
का इस्तेमाल करें. इसके बाद, रिसीवर पर चल रहे मीडिया प्लेयर ऐप्लिकेशन को कंट्रोल करने के लिए, GCKRemoteMediaClient
का इस्तेमाल किया जा सकता है. जैसे, चलाना, रोकना, और बंद करना.
let url = URL.init(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4") guard let mediaURL = url else { print("invalid mediaURL") return } let mediaInfoBuilder = GCKMediaInformationBuilder.init(contentURL: mediaURL) mediaInfoBuilder.streamType = GCKMediaStreamType.none; mediaInfoBuilder.contentType = "video/mp4" mediaInfoBuilder.metadata = metadata; mediaInformation = mediaInfoBuilder.build() guard let mediaInfo = mediaInformation else { print("invalid mediaInformation") return } if let request = sessionManager.currentSession?.remoteMediaClient?.loadMedia(mediaInfo) { request.delegate = self }
GCKMediaInformationBuilder *mediaInfoBuilder = [[GCKMediaInformationBuilder alloc] initWithContentURL: [NSURL URLWithString:@"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"]]; mediaInfoBuilder.streamType = GCKMediaStreamTypeNone; mediaInfoBuilder.contentType = @"video/mp4"; mediaInfoBuilder.metadata = metadata; self.mediaInformation = [mediaInfoBuilder build]; GCKRequest *request = [self.sessionManager.currentSession.remoteMediaClient loadMedia:self.mediaInformation]; if (request != nil) { request.delegate = self; }
मीडिया ट्रैक इस्तेमाल करने के बारे में सेक्शन भी देखें.
4K वीडियो फ़ॉर्मैट
यह तय करने के लिए कि आपका मीडिया किस फ़ॉर्मैट में है, GCKVideoInfo
का मौजूदा इंस्टेंस पाने के लिए, GCKMediaStatus
की videoInfo
प्रॉपर्टी का इस्तेमाल करें.
इस इंस्टेंस में एचडीआर टीवी फ़ॉर्मैट का टाइप और पिक्सल में ऊंचाई और चौड़ाई
शामिल होती है. 4K फ़ॉर्मैट वाले वैरिएंट, hdrType
प्रॉपर्टी में enum वैल्यू GCKVideoInfoHDRType
से दिखाए जाते हैं.
मिनी कंट्रोलर जोड़ें
कास्ट डिज़ाइन चेकलिस्ट के मुताबिक, भेजने वाले ऐप्लिकेशन को एक परसिस्टेंट कंट्रोल उपलब्ध कराना चाहिए, जिसे मिनी कंट्रोलर कहा जाता है. यह कंट्रोल तब दिखना चाहिए, जब उपयोगकर्ता मौजूदा कॉन्टेंट वाले पेज से बाहर चला जाता है. मिनी कंट्रोलर मौजूदा कास्ट सेशन के लिए तुरंत ऐक्सेस और दिखने वाला रिमाइंडर देता है.
कास्ट फ़्रेमवर्क में एक कंट्रोल बार GCKUIMiniMediaControlsViewController
होता है. इसे उन सीन में जोड़ा जा सकता है जिनमें मिनी कंट्रोलर दिखाना है.
जब आपका ऐप्लिकेशन कोई वीडियो या ऑडियो लाइव स्ट्रीम चला रहा होता है, तो SDK टूल, मिनी कंट्रोलर में चलाएं/रोकें बटन की जगह अपने-आप एक प्ले/बंद करें बटन दिखाता है.
iOS भेजने वाले का यूज़र इंटरफ़ेस पसंद के मुताबिक बनाएं देखें और जानें कि भेजने वाला आपका ऐप्लिकेशन, कास्ट विजेट के साथ कैसा दिखेगा.
मिनी कंट्रोलर को सेंडर ऐप्लिकेशन में जोड़ने के दो तरीके हैं:
- अपने मौजूदा व्यू कंट्रोलर को अपने व्यू कंट्रोलर से रैप करके, कास्ट फ़्रेमवर्क को मिनी कंट्रोलर का लेआउट मैनेज करने दें.
- मिनी कंट्रोलर विजेट को स्टोरीबोर्ड में सबव्यू देकर, अपने मौजूदा व्यू कंट्रोलर में जोड़कर उसका लेआउट खुद मैनेज करें.
GCKUICastContainerViewController का इस्तेमाल करके रैप करें
पहला तरीका है: GCKUICastContainerViewController
का इस्तेमाल करें, जो दूसरे व्यू कंट्रोलर को रैप करता है और सबसे नीचे GCKUIMiniMediaControlsViewController
जोड़ता है. यह तरीका इस मामले में सीमित है कि आप ऐनिमेशन को पसंद के मुताबिक नहीं बना सकते और कंटेनर व्यू कंट्रोलर के व्यवहार को कॉन्फ़िगर नहीं कर सकते.
आम तौर पर, ऐप्लिकेशन का ऐक्सेस देने के लिए इस्तेमाल किए जाने वाले -[application:didFinishLaunchingWithOptions:]
तरीके में, पहला तरीका इस्तेमाल किया जाता है:
func applicationDidFinishLaunching(_ application: UIApplication) { ... // Wrap main view in the GCKUICastContainerViewController and display the mini controller. let appStoryboard = UIStoryboard(name: "Main", bundle: nil) let navigationController = appStoryboard.instantiateViewController(withIdentifier: "MainNavigation") let castContainerVC = GCKCastContext.sharedInstance().createCastContainerController(for: navigationController) castContainerVC.miniMediaControlsItemEnabled = true window = UIWindow(frame: UIScreen.main.bounds) window!.rootViewController = castContainerVC window!.makeKeyAndVisible() ... }
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ... // Wrap main view in the GCKUICastContainerViewController and display the mini controller. UIStoryboard *appStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; UINavigationController *navigationController = [appStoryboard instantiateViewControllerWithIdentifier:@"MainNavigation"]; GCKUICastContainerViewController *castContainerVC = [[GCKCastContext sharedInstance] createCastContainerControllerForViewController:navigationController]; castContainerVC.miniMediaControlsItemEnabled = YES; self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds]; self.window.rootViewController = castContainerVC; [self.window makeKeyAndVisible]; ... }
var castControlBarsEnabled: Bool { set(enabled) { if let castContainerVC = self.window?.rootViewController as? GCKUICastContainerViewController { castContainerVC.miniMediaControlsItemEnabled = enabled } else { print("GCKUICastContainerViewController is not correctly configured") } } get { if let castContainerVC = self.window?.rootViewController as? GCKUICastContainerViewController { return castContainerVC.miniMediaControlsItemEnabled } else { print("GCKUICastContainerViewController is not correctly configured") return false } } }
AppDelegate.h
@interface AppDelegate : UIResponder <UIApplicationDelegate> @property (nonatomic, strong) UIWindow *window; @property (nonatomic, assign) BOOL castControlBarsEnabled; @end
AppDelegate.m
@implementation AppDelegate ... - (void)setCastControlBarsEnabled:(BOOL)notificationsEnabled { GCKUICastContainerViewController *castContainerVC; castContainerVC = (GCKUICastContainerViewController *)self.window.rootViewController; castContainerVC.miniMediaControlsItemEnabled = notificationsEnabled; } - (BOOL)castControlBarsEnabled { GCKUICastContainerViewController *castContainerVC; castContainerVC = (GCKUICastContainerViewController *)self.window.rootViewController; return castContainerVC.miniMediaControlsItemEnabled; } ... @end
मौजूदा व्यू कंट्रोलर में एम्बेड करें
दूसरा तरीका है, createMiniMediaControlsViewController
का इस्तेमाल करके, मिनी कंट्रोलर को सीधे अपने मौजूदा व्यू कंट्रोलर से जोड़ें GCKUIMiniMediaControlsViewController
इंस्टेंस बनाने के लिए और फिर उसे कंटेनर व्यू कंट्रोलर में सबव्यू के तौर पर जोड़ें.
ऐप्लिकेशन डेलिगेट में अपना व्यू कंट्रोलर सेट अप करें:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { ... GCKCastContext.sharedInstance().useDefaultExpandedMediaControls = true window?.clipsToBounds = true let rootContainerVC = (window?.rootViewController as? RootContainerViewController) rootContainerVC?.miniMediaControlsViewEnabled = true ... return true }
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ... [GCKCastContext sharedInstance].useDefaultExpandedMediaControls = YES; self.window.clipsToBounds = YES; RootContainerViewController *rootContainerVC; rootContainerVC = (RootContainerViewController *)self.window.rootViewController; rootContainerVC.miniMediaControlsViewEnabled = YES; ... return YES; }
अपने रूट व्यू कंट्रोलर में, GCKUIMiniMediaControlsViewController
इंस्टेंस बनाएं और उसे कंटेनर व्यू कंट्रोलर में सबव्यू के तौर पर जोड़ें:
let kCastControlBarsAnimationDuration: TimeInterval = 0.20 @objc(RootContainerViewController) class RootContainerViewController: UIViewController, GCKUIMiniMediaControlsViewControllerDelegate { @IBOutlet weak private var _miniMediaControlsContainerView: UIView! @IBOutlet weak private var _miniMediaControlsHeightConstraint: NSLayoutConstraint! private var miniMediaControlsViewController: GCKUIMiniMediaControlsViewController! var miniMediaControlsViewEnabled = false { didSet { if self.isViewLoaded { self.updateControlBarsVisibility() } } } var overriddenNavigationController: UINavigationController? override var navigationController: UINavigationController? { get { return overriddenNavigationController } set { overriddenNavigationController = newValue } } var miniMediaControlsItemEnabled = false override func viewDidLoad() { super.viewDidLoad() let castContext = GCKCastContext.sharedInstance() self.miniMediaControlsViewController = castContext.createMiniMediaControlsViewController() self.miniMediaControlsViewController.delegate = self self.updateControlBarsVisibility() self.installViewController(self.miniMediaControlsViewController, inContainerView: self._miniMediaControlsContainerView) } func updateControlBarsVisibility() { if self.miniMediaControlsViewEnabled && self.miniMediaControlsViewController.active { self._miniMediaControlsHeightConstraint.constant = self.miniMediaControlsViewController.minHeight self.view.bringSubview(toFront: self._miniMediaControlsContainerView) } else { self._miniMediaControlsHeightConstraint.constant = 0 } UIView.animate(withDuration: kCastControlBarsAnimationDuration, animations: {() -> Void in self.view.layoutIfNeeded() }) self.view.setNeedsLayout() } func installViewController(_ viewController: UIViewController?, inContainerView containerView: UIView) { if let viewController = viewController { self.addChildViewController(viewController) viewController.view.frame = containerView.bounds containerView.addSubview(viewController.view) viewController.didMove(toParentViewController: self) } } func uninstallViewController(_ viewController: UIViewController) { viewController.willMove(toParentViewController: nil) viewController.view.removeFromSuperview() viewController.removeFromParentViewController() } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "NavigationVCEmbedSegue" { self.navigationController = (segue.destination as? UINavigationController) } } ...
RootContainerViewController.h
static const NSTimeInterval kCastControlBarsAnimationDuration = 0.20; @interface RootContainerViewController () <GCKUIMiniMediaControlsViewControllerDelegate> { __weak IBOutlet UIView *_miniMediaControlsContainerView; __weak IBOutlet NSLayoutConstraint *_miniMediaControlsHeightConstraint; GCKUIMiniMediaControlsViewController *_miniMediaControlsViewController; } @property(nonatomic, weak, readwrite) UINavigationController *navigationController; @property(nonatomic, assign, readwrite) BOOL miniMediaControlsViewEnabled; @property(nonatomic, assign, readwrite) BOOL miniMediaControlsItemEnabled; @end
RootContainerViewController.m
@implementation RootContainerViewController - (void)viewDidLoad { [super viewDidLoad]; GCKCastContext *castContext = [GCKCastContext sharedInstance]; _miniMediaControlsViewController = [castContext createMiniMediaControlsViewController]; _miniMediaControlsViewController.delegate = self; [self updateControlBarsVisibility]; [self installViewController:_miniMediaControlsViewController inContainerView:_miniMediaControlsContainerView]; } - (void)setMiniMediaControlsViewEnabled:(BOOL)miniMediaControlsViewEnabled { _miniMediaControlsViewEnabled = miniMediaControlsViewEnabled; if (self.isViewLoaded) { [self updateControlBarsVisibility]; } } - (void)updateControlBarsVisibility { if (self.miniMediaControlsViewEnabled && _miniMediaControlsViewController.active) { _miniMediaControlsHeightConstraint.constant = _miniMediaControlsViewController.minHeight; [self.view bringSubviewToFront:_miniMediaControlsContainerView]; } else { _miniMediaControlsHeightConstraint.constant = 0; } [UIView animateWithDuration:kCastControlBarsAnimationDuration animations:^{ [self.view layoutIfNeeded]; }]; [self.view setNeedsLayout]; } - (void)installViewController:(UIViewController *)viewController inContainerView:(UIView *)containerView { if (viewController) { [self addChildViewController:viewController]; viewController.view.frame = containerView.bounds; [containerView addSubview:viewController.view]; [viewController didMoveToParentViewController:self]; } } - (void)uninstallViewController:(UIViewController *)viewController { [viewController willMoveToParentViewController:nil]; [viewController.view removeFromSuperview]; [viewController removeFromParentViewController]; } - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"NavigationVCEmbedSegue"]) { self.navigationController = (UINavigationController *)segue.destinationViewController; } } ... @end
GCKUIMiniMediaControlsViewControllerDelegate
से, होस्ट व्यू कंट्रोलर को यह पता चलता है कि मिनी कंट्रोलर कब दिखेगा:
func miniMediaControlsViewController(_: GCKUIMiniMediaControlsViewController, shouldAppear _: Bool) { updateControlBarsVisibility() }
- (void)miniMediaControlsViewController: (GCKUIMiniMediaControlsViewController *)miniMediaControlsViewController shouldAppear:(BOOL)shouldAppear { [self updateControlBarsVisibility]; }
बड़ा किया गया कंट्रोलर जोड़ें
Google Cast की डिज़ाइन चेकलिस्ट को लागू करने के लिए ज़रूरी है कि भेजने वाले ऐप्लिकेशन में, कास्ट किए जा रहे मीडिया के लिए बड़ा किया गया कंट्रोलर उपलब्ध कराया जाए. बड़ा किया गया कंट्रोलर, मिनी कंट्रोलर का फ़ुल स्क्रीन वर्शन है.
बड़ा किया गया कंट्रोलर फ़ुल स्क्रीन व्यू है, जो रिमोट मीडिया प्लेबैक का पूरा कंट्रोल देता है. इस व्यू से कास्ट करने वाले ऐप्लिकेशन को, कास्ट सेशन के हर मैनेज किए जा सकने वाले पहलू को मैनेज करने की अनुमति मिलनी चाहिए. हालांकि, वेब रिसीवर वॉल्यूम कंट्रोल और सेशन लाइफ़साइकल (कास्ट करना बंद या कनेक्ट करना) को छोड़कर. इसमें मीडिया सेशन की स्थिति की भी सभी जानकारी मौजूद होती है. जैसे, आर्टवर्क, टाइटल, सबटाइटल वगैरह.
इस व्यू के फ़ंक्शन को GCKUIExpandedMediaControlsViewController
क्लास से लागू किया जाता है.
आपको सबसे पहले कास्ट के कॉन्टेक्स्ट में डिफ़ॉल्ट एक्सपैंडेड कंट्रोलर को चालू करना होगा. डिफ़ॉल्ट बड़े किए गए कंट्रोलर को चालू करने के लिए, ऐक्सेस देने वाले व्यक्ति की जानकारी में बदलाव करें:
func applicationDidFinishLaunching(_ application: UIApplication) { .. GCKCastContext.sharedInstance().useDefaultExpandedMediaControls = true ... }
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ... [GCKCastContext sharedInstance].useDefaultExpandedMediaControls = YES; .. }
जब लोग वीडियो कास्ट करना शुरू करें, तब बड़े किए गए कंट्रोलर को लोड करने के लिए, अपने व्यू कंट्रोलर में यह कोड जोड़ें:
func playSelectedItemRemotely() { GCKCastContext.sharedInstance().presentDefaultExpandedMediaControls() ... // Load your media sessionManager.currentSession?.remoteMediaClient?.loadMedia(mediaInformation) }
- (void)playSelectedItemRemotely { [[GCKCastContext sharedInstance] presentDefaultExpandedMediaControls]; ... // Load your media [self.sessionManager.currentSession.remoteMediaClient loadMedia:mediaInformation]; }
जब उपयोगकर्ता मिनी कंट्रोलर पर टैप करेगा, तो बड़ा किया गया कंट्रोलर भी अपने-आप लॉन्च हो जाएगा.
जब भेजने वाला ऐप्लिकेशन कोई वीडियो या ऑडियो लाइव स्ट्रीम चला रहा होता है, तो SDK टूल बड़े किए गए कंट्रोलर में चलाएं/रोकें बटन की जगह अपने-आप एक प्ले/बंद करें बटन दिखाता है.
अपने iOS ऐप्लिकेशन पर कस्टम स्टाइल लागू करना लेख पढ़ें. इससे आपको पता चलेगा कि भेजने वाला ऐप्लिकेशन, Cast विजेट के दिखने के तरीके को कैसे कॉन्फ़िगर कर सकता है.
वॉल्यूम कंट्रोल
कास्ट फ़्रेमवर्क, भेजने वाले ऐप्लिकेशन का वॉल्यूम अपने-आप मैनेज करता है. फ़्रेमवर्क, दिए गए यूज़र इंटरफ़ेस (यूआई) विजेट के लिए वेब रिसीवर की आवाज़ के साथ अपने-आप सिंक हो जाता है. ऐप्लिकेशन के दिए गए स्लाइडर को सिंक करने के लिए, GCKUIDeviceVolumeController
का इस्तेमाल करें.
फ़िज़िकल बटन की आवाज़ को कम या ज़्यादा करना
भेजने वाले डिवाइस के फ़िज़िकल वॉल्यूम बटन का इस्तेमाल करके, वेब रिसीवर पर कास्ट सेशन की आवाज़ में बदलाव किया जा सकता है. ऐसा करने के लिए, GCKCastOptions
पर मौजूद physicalVolumeButtonsWillControlDeviceVolume
फ़्लैग का इस्तेमाल किया जा सकता है, जो GCKCastContext
पर सेट होता है.
let criteria = GCKDiscoveryCriteria(applicationID: kReceiverAppID) let options = GCKCastOptions(discoveryCriteria: criteria) options.physicalVolumeButtonsWillControlDeviceVolume = true GCKCastContext.setSharedInstanceWith(options)
GCKDiscoveryCriteria *criteria = [[GCKDiscoveryCriteria alloc] initWithApplicationID:kReceiverAppID]; GCKCastOptions *options = [[GCKCastOptions alloc] initWithDiscoveryCriteria :criteria]; options.physicalVolumeButtonsWillControlDeviceVolume = YES; [GCKCastContext setSharedInstanceWithOptions:options];
गड़बड़ियां ठीक करना
भेजने वाले ऐप्लिकेशन के लिए यह बहुत ज़रूरी है कि वे सभी गड़बड़ी कॉलबैक को हैंडल करें और कास्ट की लाइफ़ साइकल के हर चरण के लिए सबसे सही रिस्पॉन्स तय करें. ऐप्लिकेशन, उपयोगकर्ता को गड़बड़ी वाले डायलॉग दिखा सकता है या यह कास्ट सेशन को खत्म करने का फ़ैसला ले सकता है.
लॉगिंग
GCKLogger
एक सिंगलटन है, जिसका इस्तेमाल फ़्रेमवर्क से लॉग करने के लिए किया जाता है. लॉग मैसेज को मैनेज करने का तरीका पसंद के मुताबिक बनाने के लिए, GCKLoggerDelegate
का इस्तेमाल करें.
GCKLogger
का इस्तेमाल करके, SDK टूल डीबग मैसेज, गड़बड़ियों, और चेतावनियों के तौर पर
लॉगिंग आउटपुट बनाता है. ये लॉग मैसेज डीबग करने में मदद करते हैं.
साथ ही, इनसे समस्याओं को हल करने और उनकी पहचान करने में मदद मिलती है. डिफ़ॉल्ट रूप से, लॉग आउटपुट को सीमित कर दिया जाता है, लेकिन GCKLoggerDelegate
असाइन करने पर, भेजने वाले ऐप्लिकेशन को SDK टूल से ये मैसेज मिल सकते हैं और वह सिस्टम कंसोल में लॉग कर सकता है.
@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, GCKLoggerDelegate { let kReceiverAppID = kGCKDefaultMediaReceiverApplicationID let kDebugLoggingEnabled = true var window: UIWindow? func applicationDidFinishLaunching(_ application: UIApplication) { ... // Enable logger. GCKLogger.sharedInstance().delegate = self ... } // MARK: - GCKLoggerDelegate func logMessage(_ message: String, at level: GCKLoggerLevel, fromFunction function: String, location: String) { if (kDebugLoggingEnabled) { print(function + " - " + message) } } }
AppDelegate.h
@interface AppDelegate () <GCKLoggerDelegate> @end
AppDelegate.m
@implementation AppDelegate static NSString *const kReceiverAppID = @"AABBCCDD"; static const BOOL kDebugLoggingEnabled = YES; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ... // Enable logger. [GCKLogger sharedInstance].delegate = self; ... return YES; } ... #pragma mark - GCKLoggerDelegate - (void)logMessage:(NSString *)message atLevel:(GCKLoggerLevel)level fromFunction:(NSString *)function location:(NSString *)location { if (kDebugLoggingEnabled) { NSLog(@"%@ - %@, %@", function, message, location); } } @end
डीबग और वर्बोस मैसेज को भी चालू करने के लिए, डेलिगेट को सेट करने के बाद इस लाइन को कोड में जोड़ें (पहले दिखाया गया):
let filter = GCKLoggerFilter.init() filter.minimumLevel = GCKLoggerLevel.verbose GCKLogger.sharedInstance().filter = filter
GCKLoggerFilter *filter = [[GCKLoggerFilter alloc] init]; [filter setMinimumLevel:GCKLoggerLevelVerbose]; [GCKLogger sharedInstance].filter = filter;
GCKLogger
के बनाए गए लॉग मैसेज को भी फ़िल्टर किया जा सकता है.
हर क्लास के लिए लॉग इन करने का कम से कम लेवल सेट करें, उदाहरण के लिए:
let filter = GCKLoggerFilter.init() filter.setLoggingLevel(GCKLoggerLevel.verbose, forClasses: ["GCKUICastButton", "GCKUIImageCache", "NSMutableDictionary"]) GCKLogger.sharedInstance().filter = filter
GCKLoggerFilter *filter = [[GCKLoggerFilter alloc] init]; [filter setLoggingLevel:GCKLoggerLevelVerbose forClasses:@[@"GCKUICastButton", @"GCKUIImageCache", @"NSMutableDictionary" ]]; [GCKLogger sharedInstance].filter = filter;
क्लास के नाम, लिटरल नाम या ग्लोब पैटर्न हो सकते हैं. उदाहरण के लिए, GCKUI\*
और GCK\*Session
.