iOS音訊後台播放總結

來源:互聯網
上載者:User

標籤:

 在沒有網路的情況下,音訊後台播放比較簡單,google一下可以搜到很多資料,但是如果每次歌曲的請求都是通過網路,就不成了,有時可以也扛不了幾首,這裡總結下實現方法,可以實現像電台一樣的功能,後台播放,網路請求歌曲,Remote控制,鎖屏有封面,電話和聽歌打斷處理等。

 

 

 

初始化AudioSession和基本配置

音頻播放器採用的AVPlayer ,自己進行了功能封裝,暫且不談,在程式啟動的時候需要配置AudioSession,AudioSession負責應用音訊設定,比如支不支援後台,打斷等等,這一步很重要,比如在viewdidload裡初始化AVplayer以後要調用下面的函數:

-(void)setAudioSession{

//AudioSessionInitialize用於控制打斷 ,後面會說

AudioSessionInitialize (

NULL,                          // ‘NULL’ to use the default (main) run loop

NULL,                          // ‘NULL’ to use the default run loop mode

ASAudioSessionInterruptionListener,  // a reference to your interruption callback

NULL                       // data to pass to your interruption listener callback

);

//這種方式後台,可以連續播放非網路請求歌曲,遇到網路請求歌曲就廢,需要後台申請task

AVAudioSession *session = [AVAudioSession sharedInstance];

NSError *setCategoryError = nil;

BOOL success = [session setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];

if (!success)

{

/* handle the error condition */

return;

}

NSError *activationError = nil;

success = [session setActive:YES error:&activationError];

if (!success)

{

/* handle the error condition */

return;

}

}

AudioSessionInitialize用於處理中斷處理,AVAudioSession主要調用setCategory和setActive方法來進行設定,AVAudioSessionCategoryPlayback一般用於支援後台播放,在官方文檔可以看到其他的類型,每個分別適用於不同的場合:

 
123456789101112131415161718192021 NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryAmbient"]] ><blockquote]] > AVAudioSessionCategoryAmbient</blockquote]] ></a]] > ;NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategorySoloAmbient"]] ><blockquote]] > AVAudioSessionCategorySoloAmbient</blockquote]] ></a]] > ;NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryPlayback"]] ><blockquote]] > AVAudioSessionCategoryPlayback</blockquote]] ></a]] > ;NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryRecord"]] ><blockquote]] > AVAudioSessionCategoryRecord</blockquote]] ></a]] > ;NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryPlayAndRecord"]] ><blockquote]] > AVAudioSessionCategoryPlayAndRecord</blockquote]] ></a]] > ;NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryAudioProcessing"]] ><blockquote]] > AVAudioSessionCategoryAudioProcessing</blockquote]] ></a]] > ;NSString *const <a href="file:///Users/lipengxuan/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html#//apple_ref/doc/c_ref/AVAudioSessionCategoryMultiRoute"]] ><blockquote]] > AVAudioSessionCategoryMultiRoute</blockquote]] ></a]] > ;

 

 
1  

除了代碼的初始化,很重要的一步是對info-plist的設定,讓應用支援音訊後台播放

庫的引入包括:

AudioToolBox.framework

MediaPlayer.framework

CoreMedia.framework

AVFoundation.framework

 

後台播放

正常情況下,如果配置了AVAudioSessionCategoryPlayback這個方法並修改了info-plist檔案,應用就已經支援後台音頻播放了,但是如果每一首歌曲都不存在本地,在網路的話就不行了,需要申請背景工作來進行處理,首先修改:

- (void)applicationDidEnterBackground:(UIApplication *)application {

[application beginReceivingRemoteControlEvents];
}

然後在播放器的播放函數裡添加:

-(void)justPlay{

UIBackgroundTaskIdentifier bgTask = 0;

 

if([UIApplication sharedApplication].applicationState== UIApplicationStateBackground) {

NSLog(@”xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx後台播放”);

[thePlayer play];

UIApplication*app = [UIApplication sharedApplication];

UIBackgroundTaskIdentifier newTask = [app beginBackgroundTaskWithExpirationHandler:nil];

if(bgTask!= UIBackgroundTaskInvalid) {

[app endBackgroundTask: bgTask];

}

bgTask = newTask;

}

else {

NSLog(@”xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx前台播放”);

[thePlayer play];

}

}

這樣播放就可以進行前台或者背景判斷,支援網路後台播放了,一首一首連續播放。

Remote控制

在播放視圖的ViewController裡加上這兩個函數:

- (void)viewDidAppear:(BOOL)animated {

NSLog(@”viewDidAppear!!!”);

[super viewDidAppear:animated];

//Once the view has loaded then we can register to begin recieving controls and we can become the first responder

[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

[self becomeFirstResponder];

}

- (void)viewWillDisappear:(BOOL)animated {

NSLog(@”viewWillDisappear!!!”);

[super viewWillDisappear:animated];

//End recieving events

[[UIApplication sharedApplication] endReceivingRemoteControlEvents];

[self resignFirstResponder];

}

當然也可以同理放到delegate.m裡面的進入後台和回到前台的函數中,否則的話,上面的代碼只是允許當前視圖的情況下進入後台可以Remote控制

 

然後添加下面的代碼:

 

-(void)remoteControlReceivedWithEvent:(UIEvent *)event{

//if it is a remote control event handle it correctly

if (event.type == UIEventTypeRemoteControl) {

if (event.subtype == UIEventSubtypeRemoteControlTogglePlayPause) {

[self playerTap];

} else if (event.subtype == UIEventSubtypeRemoteControlNextTrack){

[self nextSongAuto];

[self configNowPlayingInfoCenter];

}

}

}

//Make sure we can recieve remote control events

- (BOOL)canBecomeFirstResponder {

return YES;

}

鎖屏封面

一般在每次切換歌曲或者更新資訊的時候要調用這個方法

- (void)configNowPlayingInfoCenter {

NSDictionary *albumDic=[currentParserSongArray objectAtIndex:songIndex];

if (NSClassFromString(@”MPNowPlayingInfoCenter”)) {

NSMutableDictionary * dict = [[NSMutableDictionary alloc] init];

[dict setObject:[albumDic objectForKey:@"name"] forKey:MPMediaItemPropertyTitle];

[dict setObject:[albumDic objectForKey:@"singer"] forKey:MPMediaItemPropertyArtist];

[dict setObject:[albumDic objectForKey:@"album"] forKey:MPMediaItemPropertyAlbumTitle];

MPMediaItemArtwork * mArt = [[MPMediaItemArtwork alloc] initWithImage:cdCoverImgView.image];

[dict setObject:mArt forKey:MPMediaItemPropertyArtwork];

[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = nil;

[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dict];

}

}

 

打斷處理

試用了官方文檔上的各種代理方法,打斷通知,都沒用,後來用C函數處理可以控制打斷,首先AudioToolBox.framework是需要引入的

在設定session的時候調用了ASAudioSessionInterruptionListener這個函數 ,就是處理打斷的,在所需加入的類的實現

@implementation前面加入這個靜態方法

static void ASAudioSessionInterruptionListener(void *inClientData, UInt32 inInterruptionState)

{

[[ToolManager defaultManager] handleInterruption:inInterruptionState];

}

每次打斷結束或者開始都會調用這個方法  ,inInterruptionState來判斷是開始還是結束,因為是C函數,不可以直接調用類中[self  xxx]方法,通知也沒用 ,故寫了個單例類,接收這個參數,然後進行判斷

- (void)handleInterruptionChangeToState:(NSNotification *)notification

{

AudioQueuePropertyID inInterruptionState=[[notification object] longValue];

 

if (inInterruptionState == kAudioSessionBeginInterruption)

{

NSLog(@”begin interruption——->”);

}

else if (inInterruptionState == kAudioSessionEndInterruption)

{

NSLog(@”end interruption——->”);

 

}

iOS音訊後台播放總結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.