1.前言
蘋果投屏功能主要基于 AirPlay,可以隔空播放音視頻和圖片。蘋果原生的 AirPlay 有發(fā)送端和接收端之分,分別為以下設(shè)備
發(fā)送端
- iPhone
- iPad
- iPod touch
- Mac
接收端
Apple TV
2.Airplay使用模式
- Mirror device's screen (屏幕鏡像)
- AirPlay video (隔空播放音視頻)
1.Mirror device's screen
在該模式下,手機(jī)上顯示什么,TV 上就顯示什么,直接將手機(jī)內(nèi)容展示到 TV 的顯示器上面。
雖然這種模式叫鏡像模式,但是,其實(shí)在這種模式下,APP 內(nèi)部可以寫代碼檢測(cè)是否開啟了鏡像模式,可以針對(duì) Apple TV 的屏幕寫一屏新的 UI,也就是手機(jī)和 TV 的顯示屏展示內(nèi)容可以不同,相當(dāng)于外接了一個(gè)屏幕,展示新的內(nèi)容。通過這種方法,可以把手機(jī)頁面作為一個(gè)遙控器,真正展示內(nèi)容可以放到 TV 的屏幕。
在使用鏡像模式的時(shí)候,如果手機(jī)鎖屏,TV 端也看不到任何內(nèi)容了。也就是說,在這種模式下,手機(jī)必須一直是常亮的。個(gè)人認(rèn)為這種模式比較適合用來做操作演示,不太適合用來播放視頻。
鏡像方式開啟方法:https://support.apple.com/zh-cn/HT204289#mirroriOS
2.AirPlay video
隔空播放的方式其實(shí)是在嵌入在某個(gè) APP 內(nèi)部的,在 APP 內(nèi)部進(jìn)行操作之后,可以隔空將音視頻和圖片投送到 TV 上播放。
把一個(gè)文件推送到 TV 端,然后用 TV 的屏幕進(jìn)行播放
該方式需要 APP 開發(fā)者在軟件內(nèi)部寫一些代碼來支持投屏,比較適合單個(gè)視頻的播放。比如用騰訊視頻看電影的時(shí)候就可以把視頻投到 TV 上去播放,這個(gè)時(shí)候手機(jī)是可以直接鎖屏的,投放的效果也非常不錯(cuò)。
但是這種方式僅僅是對(duì)文件的隔空播放,尚未發(fā)現(xiàn)可以自定義 TV 端播放頁面的 API。
隔空播放開啟方法:https://support.apple.com/zh-cn/HT204289#iOS
3.Apple TV 之外的設(shè)備接收 AirPlay
一般來說只能用 Apple TV 作為接收端,不過有很多第三方破解了蘋果的傳輸協(xié)議,所以很多平臺(tái)通過安裝一個(gè)接收端軟件來模仿 Apple TV 接收 iPhone 等設(shè)備投送的數(shù)據(jù)。
3.代碼實(shí)現(xiàn)
3.1 初始化MPVolumeView
@property (nonatomic, strong) XBVectorButton * tvScreenBtn ;//投屏按鈕
@property (nonatomic, strong) MPVolumeView *volumeView;//投屏按鈕
@property (nonatomic, strong) MPVolumeView *mpVolumeView;//音量調(diào)節(jié)View
//初始化
mainRect.origin.x = 1434*scale_lY;
mainRect.origin.y = 53 *scale_l;
mainRect.size.width = buttonWidth;
mainRect.size.height = buttonWidth;
_tvScreenBtn = [[XBVectorButton alloc]initWithFrame:mainRect
ImageText:@"\U0000e935"
imageFontSize:fontSize
target:self
action:@selector(buttonClick:)];
_tvScreenBtn.tag = XBVideoSmallScreenSettingTypeTVScreen;
//初始化 MPVolumeView
_volumeView = [[MPVolumeView alloc] initWithFrame:mainRect] ;
for (UIView *view in _volumeView.subviews) {
if ([view.class.description isEqualToString:@"MPVolumeSlider"]) {
_mpVolumeSlider = (UISlider *)view;
}else if ([view isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)view;
[button setImage:nil forState:0];
[button setImage:nil forState:UIControlStateSelected];
[button setTitle:@"\U0000e935" forState:0];
[button setTitle:@"\U0000e935" forState:UIControlStateSelected];
[button.titleLabel setFont: [UIFont fontWithName:@"icomoon" size:fontSize]];
[button sizeToFit];
}
}
NSLog(@"%f", _mpVolumeSlider.value);
[_volumeView setShowsVolumeSlider:NO];
[_volumeView routeButtonRectForBounds:mainRect];
3.2 監(jiān)聽投屏狀態(tài)
//添加通知
[HKNotiCenter addObserver:self selector:@selector(pmVolumeViewWirelessRouteActiveDidChangeNoti:) name:MPVolumeViewWirelessRouteActiveDidChangeNotification object:nil];
- (void)pmVolumeViewWirelessRouteActiveDidChangeNoti:(NSNotification*)noti {
if (_volumeView.wirelessRouteActive) {
//是否在投屏
[self tvActive:YES];
}else {
[self tvActive:NO];
}
NSLog(@"pmVolumeViewWirelessRouteActiveDidChangeNoti===Userinfo:%@",noti.userInfo);
}
-(void)tvActive:(BOOL)isActive{
if (isActive) {
//投屏中
NSLog(@"投屏");
if (!self.playerView.isTVActive) {
[self.playerView fullScreen:NO];
self.playerView.isTVActive = YES;
// [self.playerView pause];
_tvActiveView.hidden = NO;
if (self.playManager.videoList.count) {
[HKVideoPlayManager saveHistorySeeTime:_slider.value];
}
[self showOtherMenu];
}
}else{
if ( self.playerView.isTVActive) {
NSLog(@"退出投屏");
//[self.playerView playWithVideo:self.playManager.currentPlayItem];
[self.playerView endTV];
self.playerView.isTVActive = NO;
_tvActiveView.hidden = YES;
[self showNormalMenu];
}
}
}
3.3 激活投屏
- (void)refreshTV{
[_tvScreenBtn removeFromSuperview];
[self addSubview:_volumeView];
[self insertSubview:_volumeView aboveSubview:_bgImageView];
}
4.其他補(bǔ)充
Mac/iPhone 投屏
- 前提 Mac 和 投屏電視在同一網(wǎng)絡(luò)(WIFI)下
- 在頂部狀態(tài)欄會(huì)顯示投屏按鈕
- iPhone 直接使用屏幕鏡像即可
