Книга: iOS. Приемы программирования

Обсуждение

Обсуждение

В iOS приложение может запросить продолжить воспроизведение своих аудиофайлов, даже если оно само переходит в фоновый режим. В этом разделе мы воспользуемся плеером AVAudioPlayer, который прост и удобен в обращении. Наша задача — запустить аудиоплеер и воспроизвести простой трек, а пока играет музыка — нажать кнопку Home (Домой) и перевести приложение в фоновый режим. Если мы внесем в файл. plist нашего приложения ключ UIBackgroundModes, iOS продолжит воспроизводить музыку из аудиоплеера приложения, действующего в фоновом режиме. Пока плеер работает в фоновом режиме, мы должны просто воспроизводить музыку и предоставлять плееру те данные, которые необходимы ему для работы. Нам не придется выполнять никаких иных задач, например отображать новые экраны.

Вот объявление простого делегата приложения, запускающего AVAudioPlayer:

#import «AppDelegate.h»
#import <AVFoundation/AVFoundation.h>
@interface AppDelegate () <AVAudioPlayerDelegate>
@property (nonatomic, strong) AVAudioPlayer *audioPlayer;
@end
@implementation AppDelegate
<# Остаток вашего кода находится здесь #>

Когда приложение откроется, мы выделим и инициализируем аудиоплеер, считаем содержимое файла MySong.mp4 в экземпляр NSData и используем эти данные в процессе инициализации аудиоплеера:

— (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
dispatch_queue_t dispatchQueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(dispatchQueue, ^(void) {
NSError *audioSessionError = nil;
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
if ([audioSession setCategory: AVAudioSessionCategoryPlayback
error:&audioSessionError]){
NSLog(@"Successfully set the audio session.");
} else {
NSLog(@"Could not set the audio session");
}
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *filePath = [mainBundle pathForResource:@"MySong"
ofType:@"mp3"];
NSData *fileData = [NSData dataWithContentsOfFile: filePath];
NSError *error = nil;
/* Запускаем аудиоплеер. */
self.audioPlayer = [[AVAudioPlayer alloc] initWithData: fileData
error:&error];
/* Получили ли мы экземпляр AVAudioPlayer? */
if (self.audioPlayer!= nil){
/* Задаем делегат и начинаем воспроизведение. */
self.audioPlayer.delegate = self;
if ([self.audioPlayer prepareToPlay] &&
[self.audioPlayer play]){
NSLog(@"Successfully started playing…");
} else {
NSLog(@"Failed to play.");
}
} else {
/* Не удалось инстанцировать AVAudioPlayer. */
}
});
self.window = [[UIWindow alloc] initWithFrame:
[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}

В данном примере кода мы используем аудиосессии из фреймворка AV, чтобы сначала перевести в беззвучный режим другие приложения, воспроизводящие музыку (например, приложение iPod), и лишь потом переходим к воспроизведению аудио. Если тот аудиофайл, который воспроизводится в настоящее время (в фоновом режиме), завершается, можно запустить новый экземпляр AVAudioPlayer и приступить к проигрыванию нового аудиофайла. iOS откорректирует обработку информации с учетом такой ситуации. Но нет гарантии, что ваше приложение, работающее в фоновом режиме, получит от системы разрешение на выделение достаточного количества памяти, чтобы загрузить в нее данные нового аудиофайла.

Вы, наверное, заметили, что в приведенном примере кода мы делаем делегат нашего приложения делегатом аудиоплеера. Мы реализуем методы делегата аудиоплеера вот так:

— (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player{
/* Аудиосессия прервана.
Здесь мы ставим плеер на паузу */
}
— (void)audioPlayerEndInterruption:(AVAudioPlayer *)player
withOptions:(NSUInteger)flags{
/* Проверяем по флагам, можем ли мы возобновить воспроизведение аудио.
Если да, то делаем это здесь */
if (flags == AVAudioSessionInterruptionOptionShouldResume){
[player play];
}
}
— (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player
successfully:(BOOL)flag{
NSLog(@"Finished playing the song");
/* Параметр flag сообщает, удалось ли успешно закончить воспроизведение */
if ([player isEqual: self.audioPlayer]){
self.audioPlayer = nil;
} else {
/* Это не наш аудиоплеер! */
}
}

Кроме того, необходимо учитывать, что, когда приложение воспроизводит аудиофайл в фоновом режиме, не будет изменяться значение, возвращаемое свойством backgroundTimeRemaining класса UIApplication. Иными словами этот аспект можно описать так: приложение, запрашивающее возможность воспроизведения аудио в фоновом режиме, не запрашивает у операционной системы iOS, явно или неявно, дополнительное время на исполнение кода.

Оглавление книги

Оглавление статьи/книги

Генерация: 0.053. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз