وقفههای تبلیغاتی
کیت توسعه نرمافزاری فرستنده iOS از تبلیغات لحظهای (Ad Breaks) و تبلیغات همراه در یک جریان رسانهای مشخص پشتیبانی میکند.
برای اطلاعات بیشتر در مورد نحوه عملکرد Ad Breakها، به مرور کلی Ad Breakهای گیرنده وب مراجعه کنید.
اگرچه میتوان وقفهها را هم در فرستنده و هم در گیرنده مشخص کرد، توصیه میشود که این وقفهها در گیرنده وب و گیرنده تلویزیون اندروید نیز مشخص شوند تا رفتار ثابتی در پلتفرمهای مختلف حفظ شود.
در iOS، با استفاده از GCKAdBreakClipInfo و GCKAdBreakInfo در یک دستور بارگذاری، Ad Breaks را مشخص کنید:
let breakClip1Builder = GCKAdBreakClipInfoBuilder(adBreakClipID: "bc0") breakClip1Builder.title = "Clip title" if let posterUrl = URL(string: "https://www.some.url") { breakClip1Builder.posterURL = posterUrl } breakClip1Builder.duration = 60 breakClip1Builder.whenSkippable = 5 // Set this field so that the ad is skippable let breakClip1 = breakClip1Builder.build() let breakClip2 = ... let breakClip3 = ... let break1 = GCKAdBreakInfoBuilder(adBreakID: "b0", adBreakClipIds: ["bc0", "bc1", "bc2"]).build() let mediaInfoBuilder = GCKMediaInformationBuilder(entity: "entity") ... mediaInfoBuilder.adBreaks = [break1] mediaInfoBuilder.adBreakClips = [breakClip1, breakClip2, breakClip3] ... mediaInformation = mediaInfoBuilder.build() let mediaLoadRequestDataBuilder = GCKMediaLoadRequestDataBuilder() mediaLoadRequestDataBuilder.mediaInformation = mediaInformation sessionManager.currentSession?.remoteMediaClient?.loadMedia(with: mediaLoadRequestDataBuilder.build())
GCKAdBreakClipInfoBuilder *breakClipInfoBuilder = [[GCKAdBreakClipInfoBuilder alloc] initWithAdBreakClipID:@"bc0"]; breakClipInfoBuilder.title = @"Clip title"; breakClipInfoBuilder.posterURL = [[NSURL alloc] initWithString:@"https://www.some.url"]; breakClipInfoBuilder.duration = 60; breakClipInfoBuilder.whenSkippable = 5; GCKAdBreakClipInfo *breakClip1 = breakClipInfoBuilder.build; GCKAdBreakClipInfo *breakClip2 = ... GCKAdBreakClipInfo *breakClip3 = ... GCKAdBreakInfo *break1 = [[GCKAdBreakInfoBuilder alloc] initWithAdBreakID:@"b0" adBreakClipIds:@[@"bc0", @"bc1", @"bc2"]].build; GCKMediaInformationBuilder *mediaInfoBuilder = [[GCKMediaInformationBuilder alloc] initWithEntity:@"entity"]; ... mediaInfoBuilder.adBreaks = @[break1]; mediaInfoBuilder.adBreakClips = @[breakClip1, breakClip2, breakClip3]; ... self.mediaInformation = [mediaInfoBuilder build]; GCKMediaLoadRequestDataBuilder *mediaLoadRequestDataBuilder = [[GCKMediaLoadRequestDataBuilder alloc] init]; mediaLoadRequestDataBuilder.mediaInformation = self.mediaInformation; // Send a load request to the remote media client. GCKRequest *request = [self.sessionManager.currentSession.remoteMediaClient loadMediaWithLoadRequestData:[mediaLoadRequestDataBuilder build]];
نرخ پخش متغیر
برنامه شما میتواند نرخ پخش را برای آیتم رسانهای فعلی نمایش داده و تغییر دهد. شما میتوانید نرخ را با استفاده از -[setPlaybackRate:] یا -[setPlaybackRate:customData:] از GCKRemoteMediaClient تنظیم کنید، با استفاده از playbackRateController از GCKUIMediaController GCKUIPlaybackRateController دسترسی پیدا کنید و با استفاده از playbackRate از GCKUIPlaybackRateController نرخ پخش فعلی را نمایش دهید.
کد نمونه
دو فایل زیر GCKUIPlaybackRateController را پیادهسازی میکنند که نرخ پخش را با استفاده از یک کنترل تقسیمشده که دارای دکمههای "عادی"، "نیم سرعت" و "دو برابر سرعت" است، کنترل میکند:
import GoogleCast /** * An implementation of GCKUIPlaybackRateController that controls playback rate * using a segmented control that has "normal", "half speed", and "double speed" * buttons. */ class SegmentedButtonPlaybackRateController: GCKUIPlaybackRateController { static let kSegmentNormal = 0; static let kSegmentHalfSpeed = 1; static let kSegmentDoubleSpeed = 2; var segmentedControl: UISegmentedControl! override var playbackRate: Float { didSet { var buttonIndex = 0 // Map the playback rate to one of our three supported speeds. if playbackRate == 1.0 { buttonIndex = SegmentedButtonPlaybackRateController.kSegmentNormal } else if playbackRate < 1.0 { buttonIndex = SegmentedButtonPlaybackRateController.kSegmentHalfSpeed } else { buttonIndex = SegmentedButtonPlaybackRateController.kSegmentDoubleSpeed } segmentedControl?.selectedSegmentIndex = buttonIndex } } override var inputEnabled: Bool { didSet { segmentedControl?.isEnabled = inputEnabled } } /** * Designated initializer. * * @param segmentedControl The segmented control for changing/displaying the * playback rate. */ convenience init(_ segmentedControl: UISegmentedControl) { self.init() self.segmentedControl = segmentedControl; segmentedControl.addTarget(self, action: #selector(segmentedControlTapped(sender:)), for: UIControl.Event.valueChanged) } @objc func segmentedControlTapped(sender: UISegmentedControl) { var playbackRate: Float = 1.0 switch segmentedControl?.selectedSegmentIndex { case SegmentedButtonPlaybackRateController.kSegmentHalfSpeed: playbackRate = 0.5; case SegmentedButtonPlaybackRateController.kSegmentDoubleSpeed: playbackRate = 2.0; case SegmentedButtonPlaybackRateController.kSegmentNormal: fallthrough default: playbackRate = 1.0; } self.playbackRate = playbackRate } }
SegmentedButtonPlaybackRateController.h
#import <GoogleCast/GoogleCast.h> #import <UIKit/UIKit.h> /** * An implementation of GCKUIPlaybackRateController that controls playback rate * using a segmented control that has "normal", "half speed", and "double speed" * buttons. */ @interface SegmentedButtonPlaybackRateController : GCKUIPlaybackRateController /** * Designated initializer. * * @param segmentedControl The segmented control for changing/displaying the * playback rate. */ - (instancetype)initWithSegmentedControl:(UISegmentedControl *)segmentedControl; @end
SegmentedButtonPlaybackRateController.m
#import "SegmentedButtonPlaybackRateController.h" @interface SegmentedButtonPlaybackRateController () { UISegmentedControl *_segmentedControl; } @end static const NSInteger kSegmentNormal = 0; static const NSInteger kSegmentHalfSpeed = 1; static const NSInteger kSegmentDoubleSpeed = 2; @implementation SegmentedButtonPlaybackRateController - (instancetype)initWithSegmentedControl:(UISegmentedControl *)segmentedControl { if (self = [super init]) { _segmentedControl = segmentedControl; [_segmentedControl addTarget:self action:@selector(segmentedControlTapped:) forControlEvents:UIControlEventValueChanged]; } return self; } - (void)setPlaybackRate:(float)playbackRate { [super setPlaybackRate:playbackRate]; NSInteger buttonIndex = 0; // Map the playback rate to one of our three supported speeds. if (playbackRate == 1.0) { buttonIndex = kSegmentNormal; } else if (playbackRate < 1.0) { buttonIndex = kSegmentHalfSpeed; } else { buttonIndex = kSegmentDoubleSpeed; } _segmentedControl.selectedSegmentIndex = buttonIndex; } - (void)setInputEnabled:(BOOL)inputEnabled { _segmentedControl.enabled = inputEnabled; [super setInputEnabled:inputEnabled]; } - (void)segmentedControlTapped:(id)sender { float playbackRate; switch (_segmentedControl.selectedSegmentIndex) { case kSegmentHalfSpeed: playbackRate = 0.5; break; case kSegmentDoubleSpeed: playbackRate = 2.0; break; case kSegmentNormal: default: playbackRate = 1.0; break; } self.playbackRate = playbackRate; } @end
اضافه کردن کانال سفارشی
چارچوب Cast دو راه برای ایجاد کانال جهت ارسال پیامهای سفارشی به یک گیرنده وب ارائه میدهد:
-
GCKCastChannelقرار است به زیرکلاسهایی تقسیم شود تا کانالهای غیربدیهی دارای وضعیت مرتبط را پیادهسازی کند. -
GCKGenericChannelبه عنوان جایگزینی برای زیرکلاسسازی ارائه شده است؛ این کلاس پیامهای دریافتی خود را به یک نماینده (delegate) ارسال میکند تا بتوان آنها را در جای دیگری پردازش کرد.
در اینجا مثالی از پیادهسازی GCKCastChannel آورده شده است:
class HGCTextChannel: GCKCastChannel { override func didReceiveTextMessage(_ message: String) { print("received message: \(message)") } }
HGCTextChannel.h
#import <GoogleCast/GCKCastChannel.h> @interface HGCTextChannel : GCKCastChannel @end
HGCTextChannel.m
#import "HGCTextChannel.h" @implementation HGCTextChannel - (void)didReceiveTextMessage:(NSString*)message { NSLog(@"received message: %@", message); } @end
یک کانال میتواند در هر زمانی ثبت شود؛ اگر جلسه در حال حاضر در حالت اتصال نباشد، کانال به طور خودکار هنگام اتصال خود جلسه متصل میشود، مشروط بر اینکه فضای نام کانال در فهرست ابردادههای فضای نام پشتیبانی شده برنامه گیرنده وب وجود داشته باشد.
هر کانال سفارشی توسط یک فضای نام منحصر به فرد تعریف میشود و باید با پیشوند urn:x-cast: شروع شود، برای مثال، urn:x-cast:com.example.custom . میتوان چندین کانال سفارشی داشت که هر کدام یک فضای نام منحصر به فرد داشته باشند. برنامه گیرنده وب همچنین میتواند پیامها را با استفاده از همان فضای نام ارسال و دریافت کند .
var error: GCKError? let textChannel = HGCTextChannel.init(namespace: "urn:x-cast:com.google.cast.sample.helloworld") sessionManager.currentCastSession?.add(textChannel) textChannel.sendTextMessage("Hello World", error: &error) if error != nil { print("Error sending text message \(error.debugDescription)") }
NSError *error; HGCTextChannel *textChannel = [[HGCTextChannel alloc] initWithNamespace:@"urn:x-cast:com.google.cast.sample.helloworld"]; [sessionManager.currentCastSession addChannel:textChannel]; [textChannel sendTextMessage:@"Hello World" error:&error]; if (error != nil) { NSLog(@"Error sending text message: %@", error); }
برای ارائه منطقی که باید هنگام اتصال یا قطع اتصال یک کانال خاص اجرا شود، در صورت استفاده از GCKCastChannel ، متدهای -[didConnect] و -[didDisconnect] را بازنویسی کنید، یا در صورت استفاده از GCKGenericChannel GCKGenericChannel پیادهسازیهایی برای متدهای -[castChannelDidConnect:] و -[castChannelDidDisconnect:] از GCKGenericChannelDelegate ارائه دهید.
پشتیبانی از پخش خودکار
به APIهای پخش خودکار و صفبندی مراجعه کنید.
انتخاب تصویر و ذخیره سازی را لغو کنید
اجزای مختلف این چارچوب (یعنی کادر محاورهای Cast، مینی کنترلر، کنترلر توسعهیافته و GCKUIMediaController در صورت پیکربندی) تصاویر هنری مربوط به رسانهی در حال پخش فعلی را نمایش میدهند. URLهای مربوط به تصاویر هنری معمولاً در GCKMediaMetadata مربوط به رسانه گنجانده شدهاند، اما برنامهی فرستنده ممکن است منبع جایگزینی برای URLها داشته باشد.
پروتکل GCKUIImagePicker ابزاری برای انتخاب یک تصویر مناسب برای کاربرد مشخص و اندازه دلخواه تعریف میکند. این پروتکل یک متد واحد به -[getImageWithHints:fromMetadata:] دارد که یک شیء GCKUIImageHints و یک شیء GCKMediaMetadata را به عنوان پارامتر میگیرد و یک شیء GCKImage را به عنوان نتیجه برمیگرداند. این چارچوب یک پیادهسازی پیشفرض از GCKUIImagePicker ارائه میدهد که همیشه اولین تصویر را در لیست تصاویر موجود در شیء GCKMediaMetadata انتخاب میکند، اما برنامه میتواند با تنظیم ویژگی imagePicker از تکلایتون GCKCastContext ، پیادهسازی جایگزینی ارائه دهد.
پروتکل GCKUIImageCache همچنین روشی برای ذخیرهسازی تصاویری که توسط فریمورک با استفاده از HTTPS دانلود میشوند، تعریف میکند. این فریمورک یک پیادهسازی پیشفرض از GCKUIImageCache ارائه میدهد که فایلهای تصویر دانلود شده را در دایرکتوری حافظه پنهان برنامه ذخیره میکند، اما برنامه میتواند با تنظیم ویژگی imageCache از سینگلتون GCKCastContext یک پیادهسازی جایگزین ارائه دهد.
مراحل بعدی
این پایان ویژگیهایی است که میتوانید به برنامهی فرستندهی iOS خود اضافه کنید. اکنون میتوانید یک برنامهی فرستنده برای پلتفرم دیگری ( اندروید یا وب ) بسازید، یا یک گیرندهی وب بسازید.