Cast को अपने iOS ऐप्लिकेशन में इंटिग्रेट करें

इस डेवलपर गाइड में iOS सेंडर SDK टूल का इस्तेमाल करके, आपके iOS डिवाइस पर डेटा भेजने वाले ऐप्लिकेशन में Google Cast सहायता जोड़ने का तरीका बताया गया है.

मोबाइल डिवाइस या लैपटॉप भेजने वाला होता है, जो वीडियो को कंट्रोल करता है. साथ ही, Google Cast डिवाइस रिसीवर होता है जो टीवी पर कॉन्टेंट दिखाता है.

भेजने वाले का फ़्रेमवर्क, कास्ट क्लास लाइब्रेरी की बाइनरी और उससे जुड़े रिसॉर्स के बारे में बताता है जो मैसेज भेजने वाले के रनटाइम के दौरान मौजूद होते हैं. भेजने वाले का ऐप्लिकेशन या कास्ट ऐप्लिकेशन उस ऐप्लिकेशन को दिखाता है जो भेजने वाले पर भी चल रहा है. वेब पाने वाले ऐप्लिकेशन का मतलब वेब पाने वाले पर चल रहे एचटीएमएल ऐप्लिकेशन से है.

भेजने वाले का फ़्रेमवर्क एसिंक्रोनस कॉलबैक डिज़ाइन का इस्तेमाल करता है. इसकी मदद से, भेजने वाले के ऐप्लिकेशन को इवेंट की जानकारी दी जाती है. साथ ही, Cast ऐप्लिकेशन की लाइफ़साइकल की अलग-अलग स्थितियों के बीच ट्रांज़िशन भी किया जाता है.

ऐप्लिकेशन फ़्लो

नीचे दिए गए चरण, भेजने वाले के iOS ऐप्लिकेशन के सामान्य हाई-लेवल एक्ज़ीक्यूशन फ़्लो के बारे में बताते हैं:

  • कास्ट फ़्रेमवर्क, GCKCastOptions में दी गई प्रॉपर्टी के आधार पर GCKDiscoveryManager शुरू होता है. इससे डिवाइसों को स्कैन करना शुरू किया जाता है.
  • जब उपयोगकर्ता 'कास्ट करें' बटन पर क्लिक करता है, तो फ़्रेमवर्क, कास्ट किए गए डायलॉग बॉक्स में, खोजे गए कास्ट डिवाइसों की सूची दिखाता है.
  • जब उपयोगकर्ता किसी कास्ट डिवाइस को चुनता है, तो फ़्रेमवर्क उस कास्ट डिवाइस पर वेब रिसीवर ऐप्लिकेशन को लॉन्च करने की कोशिश करता है.
  • यह फ़्रेमवर्क, सेंडर ऐप्लिकेशन में कॉलबैक शुरू करता है, ताकि यह पुष्टि की जा सके कि Web रिसीवर ऐप्लिकेशन लॉन्च हो चुका है.
  • यह फ़्रेमवर्क, ईमेल भेजने वाले और वेब पाने वाले ऐप्लिकेशन के बीच कम्यूनिकेशन चैनल बनाता है.
  • यह फ़्रेमवर्क, वेब रिसीवर पर मीडिया प्लेबैक को लोड और कंट्रोल करने के लिए कम्यूनिकेशन चैनल का इस्तेमाल करता है.
  • फ़्रेमवर्क, मीडिया चलाने की स्थिति को भेजने वाले और वेब पाने वाले के बीच सिंक करता है: जब कोई उपयोगकर्ता, ईमेल भेजने वाले की यूज़र इंटरफ़ेस (यूआई) कार्रवाइयां करता है, तो फ़्रेमवर्क मीडिया कंट्रोल के उन अनुरोधों को वेब रिसीवर को पास करता है. साथ ही, जब वेब रिसीवर मीडिया स्टेटस अपडेट भेजता है, तो फ़्रेमवर्क, भेजने वाले के यूज़र इंटरफ़ेस (यूआई) की स्थिति अपडेट करता है.
  • जब उपयोगकर्ता कास्ट डिवाइस से डिसकनेक्ट करने के लिए 'कास्ट करें' बटन पर क्लिक करता है, तो फ़्रेमवर्क भेजने वाले ऐप्लिकेशन को वेब रिसीवर से डिसकनेक्ट कर देगा.

मैसेज भेजने वाले लोगों की समस्या हल करने के लिए, आपको लॉग इन करने की सुविधा चालू करनी होगी.

Google Cast iOS फ़्रेमवर्क में मौजूद सभी क्लास, तरीकों, और इवेंट की पूरी सूची देखने के लिए, Google Cast iOS API रेफ़रंस देखें. नीचे दिए गए सेक्शन में, iOS ऐप्लिकेशन में Cast को इंटिग्रेट करने का तरीका बताया गया है.

मुख्य थ्रेड से कॉल करने के तरीके

कास्ट कॉन्टेक्स्ट शुरू करें

कास्ट फ़्रेमवर्क में एक ग्लोबल सिंगलटन ऑब्जेक्ट 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)
    }
  }
}
Objective-C

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 जिसका इस्तेमाल करके वेब रिसीवर के उपलब्ध होने पर, 'कास्ट करें' बटन को स्पॉटलाइट किया जा सकता है. सेंडर ऐप्लिकेशन, टेक्स्ट, टाइटल की जगह, और 'खारिज करें' बटन को पसंद के मुताबिक बना सकता है.

  • कास्ट करने का बटन: कास्ट करने की सुविधा देने वाले 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)
Objective-C
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))
Objective-C
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
}
Objective-C
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 प्रॉपर्टी में, एनम की वैल्यू GCKVideoInfoHDRType के हिसाब से दिखाया जाता है.

मिनी कंट्रोलर जोड़ें

कास्ट डिज़ाइन चेकलिस्ट के मुताबिक, भेजने वाले ऐप्लिकेशन को लगातार एक कंट्रोल देना चाहिए, जिसे मिनी कंट्रोलर कहा जाता है. यह कंट्रोल तब दिखता है, जब उपयोगकर्ता मौजूदा कॉन्टेंट वाले पेज से बाहर जाए. मिनी कंट्रोलर की मदद से, मौजूदा कास्ट सेशन के लिए तुरंत ऐक्सेस और रिमाइंडर मिलता है.

कास्ट फ़्रेमवर्क से आपको एक कंट्रोल बार GCKUIMiniMediaControlsViewController मिलता है. इसे उन सीन में जोड़ा जा सकता है जिनमें आपको मिनी कंट्रोलर दिखाना है.

जब भेजने वाला ऐप्लिकेशन कोई वीडियो या ऑडियो लाइव स्ट्रीम चला रहा होता है, तब SDK टूल, मिनी कंट्रोलर में 'चलाएं/रोकें' बटन की जगह पर, 'चलाएं/बंद करें' बटन अपने-आप दिखाता है.

आपका भेजने वाला ऐप्लिकेशन कास्ट विजेट को किस तरह कॉन्फ़िगर कर सकता है, यह जानने के लिए iOS सेंडर यूज़र इंटरफ़ेस (यूआई) को पसंद के मुताबिक बनाएं देखें.

भेजने वाले ऐप्लिकेशन में मिनी कंट्रोलर जोड़ने के दो तरीके हैं:

  • Cast फ़्रेमवर्क को अपने मौजूदा व्यू कंट्रोलर को उसके खुद के व्यू कंट्रोलर से रैप करके, मिनी कंट्रोलर का लेआउट मैनेज करने दें.
  • स्टोरीबोर्ड में सबव्यू देकर, अपने मौजूदा व्यू कंट्रोलर में मिनी कंट्रोलर विजेट को जोड़कर उसका लेआउट खुद मैनेज करें.

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()

  ...
}
Objective-C
- (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
    }
  }
}
Objective-C

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
}
Objective-C
- (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)
    }
  }

...
Objective-C

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()
  }
Objective-C
- (void)miniMediaControlsViewController:
            (GCKUIMiniMediaControlsViewController *)miniMediaControlsViewController
                           shouldAppear:(BOOL)shouldAppear {
  [self updateControlBarsVisibility];
}

बड़ा किया गया कंट्रोलर जोड़ें

Google Cast डिज़ाइन चेकलिस्ट के लिए यह ज़रूरी है कि भेजने वाले ऐप्लिकेशन में कास्ट किए जा रहे मीडिया के लिए बड़ा किया गया नियंत्रक हो. बड़ा किया गया कंट्रोलर, मिनी कंट्रोलर का फ़ुल स्क्रीन वर्शन है.

बड़ा किया गया कंट्रोलर एक फ़ुल स्क्रीन व्यू है, जो रिमोट मीडिया प्लेबैक पर पूरा कंट्रोल देता है. इस व्यू में, कास्ट करने वाले ऐप्लिकेशन को कास्ट सेशन के मैनेज किए जा सकने वाले सभी पहलुओं को मैनेज करने की अनुमति देनी चाहिए. हालांकि, वेब रिसीवर की आवाज़ के कंट्रोल और सेशन की लाइफ़साइकल (कास्ट करना/बंद करना) को छोड़कर ऐसा किया जा सकता है. इससे मीडिया सेशन की स्थिति से जुड़ी सारी जानकारी भी मिलती है (आर्टवर्क, टाइटल, सबटाइटल वगैरह).

इस व्यू की सुविधा को GCKUIExpandedMediaControlsViewController क्लास लागू करती है.

आपको सबसे पहले, कास्ट के लिए दिए गए कॉन्टेक्स्ट में डिफ़ॉल्ट कंट्रोलर को चालू करना होगा. डिफ़ॉल्ट रूप से बड़े किए गए कंट्रोलर को चालू करने के लिए, ऐप्लिकेशन डेलिगेट में बदलाव करें:

स्विफ़्ट
func applicationDidFinishLaunching(_ application: UIApplication) {
  ..

  GCKCastContext.sharedInstance().useDefaultExpandedMediaControls = true

  ...
}
Objective-C
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  ...

  [GCKCastContext sharedInstance].useDefaultExpandedMediaControls = YES;

  ..
}

उपयोगकर्ता की ओर से वीडियो कास्ट करना शुरू करने पर, बड़े किए गए कंट्रोलर को लोड करने के लिए अपने व्यू कंट्रोलर में यह कोड जोड़ें:

स्विफ़्ट
func playSelectedItemRemotely() {
  GCKCastContext.sharedInstance().presentDefaultExpandedMediaControls()

  ...

  // Load your media
  sessionManager.currentSession?.remoteMediaClient?.loadMedia(mediaInformation)
}
Objective-C
- (void)playSelectedItemRemotely {
  [[GCKCastContext sharedInstance] presentDefaultExpandedMediaControls];

  ...

  // Load your media
  [self.sessionManager.currentSession.remoteMediaClient loadMedia:mediaInformation];
}

जब उपयोगकर्ता मिनी कंट्रोलर पर टैप करेगा, तो बड़ा किया गया कंट्रोलर भी अपने-आप लॉन्च हो जाएगा.

जब आपका भेजने वाला ऐप्लिकेशन कोई वीडियो या ऑडियो लाइव स्ट्रीम चला रहा होता है, तो SDK टूल बड़े किए गए कंट्रोलर में चलाएं/रोकें बटन की जगह पर अपने-आप एक चलाएं/बंद करें बटन दिखाता है.

आपका भेजने वाला ऐप्लिकेशन, Cast विजेट को किस तरह कॉन्फ़िगर कर सकता है, यह जानने के लिए अपने iOS ऐप्लिकेशन में कस्टम स्टाइल लागू करना लेख पढ़ें.

वॉल्यूम कंट्रोल

कास्ट फ़्रेमवर्क अपने आप भेजने वाले ऐप्लिकेशन के लिए वॉल्यूम को प्रबंधित करता है. फ़्रेमवर्क अपने आप आप दिए गए यूज़र इंटरफ़ेस (यूआई) विजेट के लिए वेब रिसीवर वॉल्यूम के साथ सिंक हो जाता है. ऐप्लिकेशन से मिले स्लाइडर को सिंक करने के लिए, GCKUIDeviceVolumeController का इस्तेमाल करें.

फ़िज़िकल बटन की आवाज़ को कम या ज़्यादा करने का बटन

भेजने वाले के डिवाइस पर वॉल्यूम वाले बटन का इस्तेमाल, वेब रिसीवर पर कास्ट सेशन की आवाज़ को कम या ज़्यादा करने के लिए किया जा सकता है. इसके लिए GCKCastOptions पर मौजूद physicalVolumeButtonsWillControlDeviceVolume फ़्लैग का इस्तेमाल करें. यह फ़्लैग GCKCastContext पर सेट होता है.

स्विफ़्ट
let criteria = GCKDiscoveryCriteria(applicationID: kReceiverAppID)
let options = GCKCastOptions(discoveryCriteria: criteria)
options.physicalVolumeButtonsWillControlDeviceVolume = true
GCKCastContext.setSharedInstanceWith(options)
Objective-C
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)
    }
  }
}
Objective-C

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
Objective-C
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
Objective-C
GCKLoggerFilter *filter = [[GCKLoggerFilter alloc] init];
[filter setLoggingLevel:GCKLoggerLevelVerbose
             forClasses:@[@"GCKUICastButton",
                          @"GCKUIImageCache",
                          @"NSMutableDictionary"
                          ]];
[GCKLogger sharedInstance].filter = filter;

क्लास के नाम, लिटरल नाम या ग्लोब पैटर्न हो सकते हैं. उदाहरण के लिए, GCKUI\* और GCK\*Session.