এই বিকাশকারী নির্দেশিকা বর্ণনা করে কিভাবে iOS প্রেরক SDK ব্যবহার করে আপনার iOS প্রেরক অ্যাপে Google Cast সমর্থন যোগ করতে হয়।
মোবাইল ডিভাইস বা ল্যাপটপ হল প্রেরক যা প্লেব্যাক নিয়ন্ত্রণ করে এবং Google Cast ডিভাইস হল রিসিভার যা টিভিতে সামগ্রী প্রদর্শন করে৷
প্রেরকের ফ্রেমওয়ার্ক কাস্ট ক্লাস লাইব্রেরি বাইনারি এবং প্রেরকের রানটাইমে উপস্থিত সংশ্লিষ্ট সংস্থানগুলিকে বোঝায়। প্রেরক অ্যাপ বা কাস্ট অ্যাপটি প্রেরকের উপরও চলমান একটি অ্যাপকে বোঝায়। ওয়েব রিসিভার অ্যাপটি ওয়েব রিসিভারে চলমান HTML অ্যাপ্লিকেশনকে বোঝায়।
প্রেরক ফ্রেমওয়ার্ক একটি অ্যাসিঙ্ক্রোনাস কলব্যাক ডিজাইন ব্যবহার করে প্রেরক অ্যাপকে ইভেন্টের তথ্য জানাতে এবং কাস্ট অ্যাপের জীবনচক্রের বিভিন্ন অবস্থার মধ্যে স্থানান্তর করতে।
অ্যাপ প্রবাহ
নিম্নলিখিত পদক্ষেপগুলি প্রেরকের iOS অ্যাপের জন্য সাধারণ উচ্চ-স্তরের কার্যকরী প্রবাহ বর্ণনা করে:
- কাস্ট ফ্রেমওয়ার্ক
GCKDiscoveryManager
শুরু করে ডিভাইসের জন্য স্ক্যান করা শুরু করার জন্যGCKCastOptions
এ প্রদত্ত বৈশিষ্ট্যের উপর ভিত্তি করে। - যখন ব্যবহারকারী কাস্ট বোতামে ক্লিক করেন, ফ্রেমওয়ার্ক কাস্ট ডায়ালগটি আবিষ্কৃত কাস্ট ডিভাইসের তালিকার সাথে উপস্থাপন করে।
- যখন ব্যবহারকারী একটি কাস্ট ডিভাইস নির্বাচন করেন, ফ্রেমওয়ার্ক কাস্ট ডিভাইসে ওয়েব রিসিভার অ্যাপ চালু করার চেষ্টা করে।
- ওয়েব রিসিভার অ্যাপ চালু হয়েছে তা নিশ্চিত করতে ফ্রেমওয়ার্ক প্রেরক অ্যাপে কলব্যাক আহ্বান করে।
- ফ্রেমওয়ার্ক প্রেরক এবং ওয়েব রিসিভার অ্যাপের মধ্যে একটি যোগাযোগের চ্যানেল তৈরি করে।
- ফ্রেমওয়ার্ক ওয়েব রিসিভারে মিডিয়া প্লেব্যাক লোড এবং নিয়ন্ত্রণ করতে যোগাযোগ চ্যানেল ব্যবহার করে।
- ফ্রেমওয়ার্ক প্রেরক এবং ওয়েব রিসিভারের মধ্যে মিডিয়া প্লেব্যাক স্টেটকে সিঙ্ক্রোনাইজ করে: যখন ব্যবহারকারী প্রেরক UI অ্যাকশন করে, ফ্রেমওয়ার্ক সেই মিডিয়া কন্ট্রোল রিকোয়েস্টগুলিকে ওয়েব রিসিভারের কাছে পাঠায়, এবং যখন ওয়েব রিসিভার মিডিয়া স্ট্যাটাস আপডেট পাঠায়, ফ্রেমওয়ার্ক সেই অবস্থা আপডেট করে। প্রেরক UI
- ব্যবহারকারী কাস্ট ডিভাইস থেকে সংযোগ বিচ্ছিন্ন করতে কাস্ট বোতামে ক্লিক করলে, ফ্রেমওয়ার্ক প্রেরক অ্যাপটিকে ওয়েব রিসিভার থেকে সংযোগ বিচ্ছিন্ন করবে।
আপনার প্রেরকের সমস্যা সমাধানের জন্য, আপনাকে লগিং সক্ষম করতে হবে৷
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 iOS SDK এই উইজেটগুলি প্রদান করে যা কাস্ট ডিজাইন চেকলিস্ট মেনে চলে:
পরিচায়ক ওভারলে :
GCKCastContext
ক্লাসে একটি পদ্ধতি রয়েছে,presentCastInstructionsViewControllerOnceWithCastButton
, যা প্রথমবার একটি ওয়েব রিসিভার উপলব্ধ হলে কাস্ট বোতামটি স্পটলাইট করতে ব্যবহার করা যেতে পারে। প্রেরক অ্যাপটি পাঠ্য, শিরোনাম পাঠ্যের অবস্থান এবং খারিজ বোতামটি কাস্টমাইজ করতে পারে।কাস্ট বোতাম : কাস্ট iOS প্রেরক SDK 4.6.0 দিয়ে শুরু করে, প্রেরক ডিভাইসটি Wi-Fi এর সাথে সংযুক্ত থাকলে কাস্ট বোতামটি সর্বদা দৃশ্যমান হয়৷ প্রাথমিকভাবে অ্যাপটি শুরু করার পরে ব্যবহারকারী প্রথমবার কাস্ট বোতামে ট্যাপ করলে, একটি অনুমতি ডায়ালগ উপস্থিত হয় যাতে ব্যবহারকারী নেটওয়ার্কের ডিভাইসগুলিতে অ্যাপটিকে স্থানীয় নেটওয়ার্ক অ্যাক্সেস প্রদান করতে পারে। পরবর্তীকালে, যখন ব্যবহারকারী কাস্ট বোতামে ট্যাপ করেন, তখন একটি কাস্ট ডায়ালগ প্রদর্শিত হয় যা আবিষ্কৃত ডিভাইসগুলির তালিকা করে। ডিভাইসটি সংযুক্ত থাকাকালীন ব্যবহারকারী কাস্ট বোতামে ট্যাপ করলে, এটি বর্তমান মিডিয়া মেটাডেটা (যেমন শিরোনাম, রেকর্ডিং স্টুডিওর নাম এবং একটি থাম্বনেইল চিত্র) প্রদর্শন করে বা ব্যবহারকারীকে কাস্ট ডিভাইস থেকে সংযোগ বিচ্ছিন্ন করার অনুমতি দেয়। কোনো ডিভাইস উপলব্ধ না থাকা অবস্থায় ব্যবহারকারী যখন কাস্ট বোতামে ট্যাপ করেন, তখন একটি স্ক্রীন প্রদর্শিত হবে যা ব্যবহারকারীকে কেন ডিভাইসগুলি খুঁজে পাওয়া যাচ্ছে না এবং কীভাবে সমস্যা সমাধান করতে হবে সে সম্পর্কে তথ্য দেয়৷
মিনি কন্ট্রোলার : যখন ব্যবহারকারী কন্টেন্ট কাস্ট করছেন এবং প্রেরক অ্যাপের বর্তমান কন্টেন্ট পৃষ্ঠা বা প্রসারিত কন্ট্রোলার থেকে অন্য স্ক্রিনে নেভিগেট করেন, তখন মিনি কন্ট্রোলারটি স্ক্রিনের নীচে প্রদর্শিত হয় যাতে ব্যবহারকারী বর্তমানে কাস্টিং মিডিয়া দেখতে পায়। মেটাডেটা এবং প্লেব্যাক নিয়ন্ত্রণ করতে।
সম্প্রসারিত কন্ট্রোলার : ব্যবহারকারী যখন বিষয়বস্তু ঢালাই করে, তারা মিডিয়া বিজ্ঞপ্তি বা মিনি কন্ট্রোলারে ক্লিক করলে, প্রসারিত কন্ট্রোলার চালু হয়, যা বর্তমানে বাজানো মিডিয়া মেটাডেটা প্রদর্শন করে এবং মিডিয়া প্লেব্যাক নিয়ন্ত্রণ করতে বেশ কয়েকটি বোতাম সরবরাহ করে।
একটি কাস্ট বোতাম যোগ করুন
ফ্রেমওয়ার্ক একটি 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
সরাসরি স্টোরিবোর্ডে যোগ করা যেতে পারে।
ডিভাইস আবিষ্কার কনফিগার করুন
কাঠামোর মধ্যে, ডিভাইস আবিষ্কার স্বয়ংক্রিয়ভাবে ঘটে। আপনি একটি কাস্টম UI প্রয়োগ না করা পর্যন্ত আবিষ্কার প্রক্রিয়াটি স্পষ্টভাবে শুরু বা বন্ধ করার দরকার নেই৷
কাঠামোর মধ্যে আবিষ্কার GCKDiscoveryManager
ক্লাস দ্বারা পরিচালিত হয়, যা GCKCastContext
এর একটি সম্পত্তি। ফ্রেমওয়ার্ক ডিভাইস নির্বাচন এবং নিয়ন্ত্রণের জন্য একটি ডিফল্ট কাস্ট ডায়ালগ উপাদান প্রদান করে। ডিভাইসের তালিকাটি ডিভাইস বান্ধব নামের দ্বারা অভিধানিকভাবে অর্ডার করা হয়েছে।
সেশন ম্যানেজমেন্ট কিভাবে কাজ করে
কাস্ট SDK একটি কাস্ট সেশনের ধারণা প্রবর্তন করে, যার প্রতিষ্ঠা একটি ডিভাইসের সাথে সংযোগ স্থাপন, একটি ওয়েব রিসিভার অ্যাপ চালু (বা যোগদান), সেই অ্যাপের সাথে সংযোগ স্থাপন এবং একটি মিডিয়া নিয়ন্ত্রণ চ্যানেল শুরু করার ধাপগুলিকে একত্রিত করে৷ কাস্ট সেশন এবং ওয়েব রিসিভার জীবনচক্র সম্পর্কে আরও তথ্যের জন্য ওয়েব রিসিভার অ্যাপ্লিকেশন লাইফ সাইকেল গাইড দেখুন৷
সেশনগুলি GCKSessionManager
ক্লাস দ্বারা পরিচালিত হয়, যা GCKCastContext
এর একটি সম্পত্তি। স্বতন্ত্র সেশনগুলিকে GCKSession
ক্লাসের সাবক্লাস দ্বারা প্রতিনিধিত্ব করা হয় : উদাহরণস্বরূপ, GCKCastSession
কাস্ট ডিভাইসগুলির সাথে সেশনগুলিকে প্রতিনিধিত্ব করে৷ আপনি GCKSessionManager
এর currentCastSession
কাস্ট সেশন সম্পত্তি হিসাবে বর্তমানে সক্রিয় কাস্ট সেশন (যদি থাকে) অ্যাক্সেস করতে পারেন।
GCKSessionManagerListener
ইন্টারফেস সেশন ইভেন্টগুলি নিরীক্ষণ করতে ব্যবহার করা যেতে পারে, যেমন সেশন তৈরি, সাসপেনশন, পুনরুদ্ধার এবং সমাপ্তি। প্রেরক অ্যাপটি ব্যাকগ্রাউন্ডে গেলে ফ্রেমওয়ার্ক স্বয়ংক্রিয়ভাবে সেশনগুলিকে স্থগিত করে এবং যখন অ্যাপটি ফোরগ্রাউন্ডে ফিরে আসে তখন সেগুলি পুনরায় চালু করার চেষ্টা করে (অথবা একটি সেশন সক্রিয় থাকাকালীন একটি অস্বাভাবিক/আচমকা অ্যাপ বন্ধ করার পরে পুনরায় চালু করা হয়)।
যদি কাস্ট ডায়ালগ ব্যবহার করা হয়, তাহলে সেশনগুলি তৈরি হয় এবং ব্যবহারকারীর অঙ্গভঙ্গির প্রতিক্রিয়াতে স্বয়ংক্রিয়ভাবে ছিঁড়ে যায়৷ অন্যথায়, অ্যাপটি GCKSessionManager
এর পদ্ধতির মাধ্যমে স্পষ্টভাবে সেশন শুরু ও শেষ করতে পারে।
সেশন লাইফসাইকেল ইভেন্টগুলির প্রতিক্রিয়া হিসাবে অ্যাপটিকে বিশেষ প্রক্রিয়াকরণের প্রয়োজন হলে, এটি GCKSessionManager
এর সাথে এক বা একাধিক GCKSessionManagerListener
দৃষ্টান্ত নিবন্ধন করতে পারে৷ GCKSessionManagerListener
হল একটি প্রোটোকল যা সেশন শুরু, সেশন শেষ ইত্যাদির মতো ইভেন্টগুলির জন্য কলব্যাককে সংজ্ঞায়িত করে।
স্ট্রিম স্থানান্তর
সেশন স্টেট সংরক্ষণ করা হল স্ট্রিম ট্রান্সফারের ভিত্তি, যেখানে ব্যবহারকারীরা ভয়েস কমান্ড, গুগল হোম অ্যাপ বা স্মার্ট ডিসপ্লে ব্যবহার করে ডিভাইস জুড়ে বিদ্যমান অডিও এবং ভিডিও স্ট্রিমগুলি সরাতে পারে। মিডিয়া এক ডিভাইসে (উৎস) বাজানো বন্ধ করে এবং অন্য ডিভাইসে (গন্তব্য) চালিয়ে যায়। লেটেস্ট ফার্মওয়্যার সহ যেকোনো কাস্ট ডিভাইস স্ট্রিম ট্রান্সফারে উৎস বা গন্তব্য হিসেবে কাজ করতে পারে।
স্ট্রিম ট্রান্সফারের সময় নতুন গন্তব্য ডিভাইস পেতে, [sessionManager:didResumeCastSession:]
কলব্যাকের সময় GCKCastSession#device
প্রপার্টি ব্যবহার করুন।
আরও তথ্যের জন্য ওয়েব রিসিভারে স্ট্রিম স্থানান্তর দেখুন।
স্বয়ংক্রিয় পুনঃসংযোগ
কাস্ট ফ্রেমওয়ার্ক অনেক সূক্ষ্ম কোণার ক্ষেত্রে স্বয়ংক্রিয়ভাবে পুনঃসংযোগ পরিচালনা করতে পুনরায় সংযোগের যুক্তি যোগ করে, যেমন:
- WiFi এর সাময়িক ক্ষতি থেকে পুনরুদ্ধার করুন
- ডিভাইসের ঘুম থেকে পুনরুদ্ধার করুন
- অ্যাপের ব্যাকগ্রাউন্ডিং থেকে পুনরুদ্ধার করুন
- অ্যাপটি ক্র্যাশ হলে পুনরুদ্ধার করুন
মিডিয়া নিয়ন্ত্রণ কিভাবে কাজ করে
যদি একটি কাস্ট সেশন একটি ওয়েব রিসিভার অ্যাপের সাথে প্রতিষ্ঠিত হয় যা মিডিয়া নেমস্পেস সমর্থন করে, তাহলে ফ্রেমওয়ার্ক দ্বারা 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
বৈশিষ্ট্য ব্যবহার করুন। এই উদাহরণে HDR টিভি ফর্ম্যাটের ধরন এবং পিক্সেলে উচ্চতা এবং প্রস্থ রয়েছে৷ 4K ফরম্যাটের ভেরিয়েন্টগুলি hdrType
প্রপার্টিতে enum মান GCKVideoInfoHDRType
দ্বারা নির্দেশিত হয়।
মিনি কন্ট্রোলার যোগ করুন
কাস্ট ডিজাইন চেকলিস্ট অনুসারে, একটি প্রেরক অ্যাপের একটি অবিচ্ছিন্ন নিয়ন্ত্রণ প্রদান করা উচিত যা মিনি কন্ট্রোলার নামে পরিচিত যা ব্যবহারকারীর বর্তমান বিষয়বস্তু পৃষ্ঠা থেকে দূরে নেভিগেট করার সময় উপস্থিত হওয়া উচিত। মিনি কন্ট্রোলার তাত্ক্ষণিক অ্যাক্সেস এবং বর্তমান কাস্ট সেশনের জন্য একটি দৃশ্যমান অনুস্মারক প্রদান করে৷
কাস্ট ফ্রেমওয়ার্ক একটি কন্ট্রোল বার প্রদান করে, GCKUIMiniMediaControlsViewController
, যা আপনি মিনি কন্ট্রোলারটি দেখাতে চান এমন দৃশ্যগুলিতে যোগ করা যেতে পারে।
যখন আপনার প্রেরক অ্যাপ একটি ভিডিও বা অডিও লাইভ স্ট্রিম চালায়, তখন মিনি কন্ট্রোলারে প্লে/পজ বোতামের জায়গায় SDK স্বয়ংক্রিয়ভাবে একটি প্লে/স্টপ বোতাম প্রদর্শন করে।
আপনার প্রেরক অ্যাপ কীভাবে কাস্ট উইজেটগুলির উপস্থিতি কনফিগার করতে পারে তার জন্য iOS প্রেরক UI কাস্টমাইজ করুন দেখুন৷
একটি প্রেরক অ্যাপে মিনি কন্ট্রোলার যোগ করার দুটি উপায় রয়েছে:
- আপনার বিদ্যমান ভিউ কন্ট্রোলারকে তার নিজস্ব ভিউ কন্ট্রোলার দিয়ে মোড়ানোর মাধ্যমে কাস্ট ফ্রেমওয়ার্ককে মিনি কন্ট্রোলারের লেআউট পরিচালনা করতে দিন।
- স্টোরিবোর্ডে একটি সাবভিউ প্রদান করে আপনার বিদ্যমান ভিউ কন্ট্রোলারে যোগ করে মিনি কন্ট্রোলার উইজেটের লেআউট নিজেই পরিচালনা করুন।
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
বিদ্যমান ভিউ কন্ট্রোলারে এম্বেড করুন
দ্বিতীয় উপায় হল একটি GCKUIMiniMediaControlsViewController
দৃষ্টান্ত তৈরি করতে createMiniMediaControlsViewController
ব্যবহার করে আপনার বিদ্যমান ভিউ কন্ট্রোলারে সরাসরি মিনি কন্ট্রোলার যোগ করা এবং তারপর একটি সাবভিউ হিসাবে কন্টেইনার ভিউ কন্ট্রোলারে যোগ করা।
অ্যাপ প্রতিনিধিতে আপনার ভিউ কন্ট্রোলার সেট আপ করুন:
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 অ্যাপে কাস্টম শৈলী প্রয়োগ করুন দেখুন৷
ভলিউম নিয়ন্ত্রণ
কাস্ট ফ্রেমওয়ার্ক স্বয়ংক্রিয়ভাবে প্রেরক অ্যাপের ভলিউম পরিচালনা করে। ফ্রেমওয়ার্ক স্বয়ংক্রিয়ভাবে সরবরাহকৃত UI উইজেটগুলির জন্য ওয়েব রিসিভার ভলিউমের সাথে সিঙ্ক্রোনাইজ করে। অ্যাপ দ্বারা প্রদত্ত একটি স্লাইডার সিঙ্ক করতে, 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
।