iOS Remote Control
前言
RemoteControl,這里就翻譯為遠程控制吧。
遠程控制是為用戶提供操作App多媒體的。遠程控制事件源于外部附件或由系統顯示的傳輸控制,并通過媒體播放器框架的類傳送到應用程序。播放音頻或視頻內容的應用程序使用這些事件來開始和停止播放,更改曲目,甚至速度的項目。所有的媒體應用程序應該支持這些事件。
除了支持遠程控制事件,應用程序可以使用媒體播放器框架,以提供播放信息的曲目。該系統在適當的地方顯示播放信息,如鎖屏和控制中心。有關媒體播放器框架類的更多信息,見媒體播放器框架參考 Media Player Framework Reference .
Remote Control功能
RemoteControl可以用來在不打開app的情況下控制app中的多媒體播放,主要包括:
- 鎖屏界面雙擊Home鍵后出現的播放操作區域
- iOS7之后控制中心的播放操作區域
- iOS7之前雙擊home鍵后出現的進程中向左滑動出現的播放操作區域
- AppleTV,AirPlay中顯示的播放操作區域
- 耳機線控
- 車載系統的設置
讓App支持Remote Control
要接收遠程控制事件,需要做到以下的幾點:
- 接收者必須可以成為第一響應者;
- 接收者必須顯示聲明接收RemoteControl事件;
- App必須是Now Playing App.
若應用程序還提供了正在播放的信息,使用 MPNowPlayingInfoCenter 對象在適當的時候更新信息。
環境準備
要使App支持Remote Control,需要設置一下info.plist文件,添加required background modes,并添加一個值為:
App playsaudioorstreamsaudio/videousingAirPlay
接下來,播放音頻之前先要設置AVAudioSession模式:
AVAudioSession *session = [AVAudioSession sharedInstance]; [sessionsetCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
擴展UIApplication作為第一響應者
在iOS上,響應者鏈如上圖,由圖可知,若其它視圖沒有處理,最終會傳到UIApplication,因此使用UIApplication作為第一響應者是最合適的。
擴展頭文件聲明,我們在監聽到對應的事件時,發送通知。
// // UIApplication+RemoteControl.h // IOSAudioRemoteControl // // Created by huangyibiao on 15/3/25. // Copyright (c) 2015年 huangyibiao. All rights reserved. // #import <UIKit/UIKit.h> // 播放 extern NSString *kRemoteControlPlayTapped; // 暫停 extern NSString *kRemoteControlPauseTapped; // 停止 extern NSString *kRemoteControlStopTapped; // 前一首 extern NSString *kRemoteControlPreviousTapped; // 后一首 extern NSString *kRemoteControlNextTapped; // 其它 extern NSString *kRemoteControlOtherTapped; @interface UIApplication (RemoteControl) /** * 注冊對remote control事件的監聽 * * @param observer 監聽者 * @param selector 回調 */ - (void)observeRemoteControl:(id)observerselector:(SEL)selector; @end
在實現文件中,我們需要處理監聽:
//
// UIApplication+RemoteControl.m
// IOSAudioRemoteControl
//
// Created by huangyibiao on 15/3/25.
// Copyright (c) 2015年 huangyibiao. All rights reserved.
//
#import "UIApplication+RemoteControl.h"
const NSString *kRemoteControlPlayTapped = @"kRemoteControlPlayTapped";
const NSString *kRemoteControlPauseTapped = @"kRemoteControlPauseTapped";
const NSString *kRemoteControlStopTapped = @"kRemoteControlStopTapped";
const NSString *kRemoteControlPreviousTapped = @"kRemoteControlForwardTapped";
const NSString *kRemoteControlNextTapped = @"kRemoteControlBackwardTapped";
const NSString *kRemoteControlOtherTapped = @"kRemoteControlOtherTapped";
@implementation UIApplication (RemoteControl)
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
switch (event.subtype) {
caseUIEventSubtypeRemoteControlPlay:
[selfpostNotification:kRemoteControlPlayTapped];
break;
caseUIEventSubtypeRemoteControlPause:
[selfpostNotification:kRemoteControlPauseTapped];
break;
caseUIEventSubtypeRemoteControlStop:
[selfpostNotification:kRemoteControlStopTapped];
break;
caseUIEventSubtypeRemoteControlNextTrack:
[selfpostNotification:kRemoteControlNextTapped];
break;
caseUIEventSubtypeRemoteControlPreviousTrack:
[selfpostNotification:kRemoteControlPreviousTapped];
break;
default:
[selfpostNotification:kRemoteControlOtherTapped];
break;
}
}
- (void)postNotification:(const NSString *)notificationName {
[[NSNotificationCenter defaultCenter]
postNotificationName:(NSString *)notificationNameobject:nil];
}
- (void)observeRemoteControl:(id)observerselector:(SEL)selector {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[centeraddObserver:observerselector:selectorname:(NSString *)kRemoteControlNextTappedobject:nil];
[centeraddObserver:observerselector:selectorname:(NSString *)kRemoteControlPauseTappedobject:nil];
[centeraddObserver:observerselector:selectorname:(NSString *)kRemoteControlStopTappedobject:nil];
[centeraddObserver:observerselector:selectorname:(NSString *)kRemoteControlPreviousTappedobject:nil];
[centeraddObserver:observerselector:selectorname:(NSString *)kRemoteControlPlayTappedobject:nil];
[centeraddObserver:observerselector:selectorname:(NSString *)kRemoteControlOtherTappedobject:nil];
}
@end
在播放audio視圖中監聽通知
在播放音頻的界面,可以是在UIViewController里,也只可以是某個UIView里,因此在對應的類在創建或者初始化時調用監聽:
UIApplication *app = [UIApplication sharedApplication]; [appobserveRemoteControl:self selector:@selector(onRemoteControleStateChanged:)];
然后處理一下事件回調:
#pragma mark - remote control
- (void)onRemoteControleStateChanged:(NSNotification *)notification {
if ([notification.nameisEqualToString:kRemoteControlPlayTapped]) {
[self play];
} else if ([notification.nameisEqualToString:kRemoteControlPauseTapped]) {
[self pause];
} else if ([notification.nameisEqualToString:kRemoteControlNextTapped]) {
[self playNext];
} else if ([notification.nameisEqualToString:kRemoteControlPreviousTapped]) {
} else if ([notification.nameisEqualToString:kRemoteControlStopTapped]) {
[self_requestPauseAudioPlaying:nil];
} else if ([notification.nameisEqualToString:kRemoteControlOtherTapped]) {
}
}
配置NowPlaying顯示數據
要想在當前播放中心中顯示當前播放的音頻的信息,需要通過 MPNowPlayingInfoCenter 類,它是一個單例。我們要顯示什么就在它的 nowPlayingInfo 屬性中設置相關配置數據。
要使用這個類及其相關屬性定義,需要引入這兩個頭文件:
#import <MediaPlayer/MPNowPlayingInfoCenter.h> #import <MediaPlayer/MPMediaItem.h>
這里只設置幾項,更多設置,請到MPMediaItem.h頭文件中查看:
NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];
// 設置歌曲播放時長
if (self.time != nil && self.time.length != 0) {
[dictsetObject:@(self.time.doubleValue)forKey:MPMediaItemPropertyPlaybackDuration];
}
// 設置歌曲名稱
if (self.title != nil && self.title.length != 0) {
[dictsetObject:self.titleforKey:MPMediaItemPropertyTitle];
}
// 設置鎖屏時的圖片
if (self.iconView.image && [self.iconView.imageisKindOfClass:[UIImage class]]) {
MPMediaItemArtwork *artwork = [[MPMediaItemArtwork alloc]initWithImage:self.iconView.image];
[dictsetObject:artworkforKey:MPMediaItemPropertyArtwork];
}
[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = dict;
到此就可以實現我們遠程控制的功能。不過這里只考慮實現,并不考慮什么時候接收,什么時候不再接收,而這里的做法時什么時候都接收遠程控制。這此事就留給大家去學習吧!
源代碼
大家可以到我的GITHUB下載demo: https://github.com/CoderJackyHuang/IOSAudioRemoteControl
參考
關注我
如果在使用過程中遇到問題,或者想要與我交流,可加入有問必答 QQ群: 324400294
關注微信公眾號: iOSDevShares
關注新浪微博賬號:標哥Jacky
標哥的GITHUB地址: CoderJackyHuang
支持并捐助
如果您覺得文章對您很有幫忙,希望得到您的支持。您的捐肋將會給予我最大的鼓勵,感謝您的支持!
| 支付寶捐助 | 微信捐助 |
|---|---|
|
|