iOS Аудио фоновое воспроизведение && Отображение и управление экраном блокировки
iOS Аудио фоновое воспроизведение && Отображение и управление экраном блокировки

Отображение панели уведомлений экрана блокировки Play

фон

Я надеюсь, что при воспроизведении звука можно отобразить интерфейс уведомлений и управлять воспроизведением звука. Поскольку предыдущим требованием была приостановка воспроизведения при входе в фоновый режим, каждый раз, когда открывался интерфейс уведомлений, воспроизведение приостанавливалось, и не было никакого эффекта, подобного эффекту музыкального проигрывателя. Позже я обнаружил, что после удаления кода фоновой паузы плеер мог отображаться в интерфейсе уведомлений, но им нельзя было управлять и прогресса не было.

выполнить

Поддержка фонового воспроизведения

первая необходимость APP Поддержка фонового провести, то есть с одной стороны убрать запись За логика кода кулисами для паузы воспроизведения, с другой стороны, установка; Target -> Signing & Capabilities в, добавить Backgroud Режимы, открытые Audio, AirPlay, and Picture in Картина. Картина следующая:

Обратите внимание на настройкиAVAudioSession,играть Устанавливайте в соответствии с реальными потребностями,играть Закрыть после

AVAudioSessionCategoryтип

Тип категории

Отключить ли звук при нажатии «Отключить звук» или блокировке экрана

Можно ли его микшировать и воспроизводить с другими приложениями, поддерживающими микширование?

Поддерживать ли фон

Описание примера сценария

AVAudioSessionCategoryAmbient

да

да

нет

Обычно используется APP фоновый звук, например, вы также можете слушать музыку во время игры

AVAudioSessionCategorySoloAmbient

да

нет

нет

Тот же звук, что и дафон,Но да используется, когда вы не хотите слушать музыку во время игры.

AVAudioSessionCategoryPlayback

нет

Невозможно по умолчанию, но поддерживается

да

Воспроизведение музыки, вы также можете слушать музыку, когда экран заблокирован

AVAudioSessionCategoryRecord

нет

нет, могу только записывать

да

Диктофон, при записи другая музыка не может воспроизводиться

AVAudioSessionCategoryPlayAndRecord

нет

Да, по умолчанию вы можете записывать и воспроизводить

да

Запись во время трансляции, например VOIP

AVAudioSessionCategoryAudioProcessing

нет

нет,Аппаратное декодирование Аудио,не могуигратьи запись

да

для обработки аудиоформата

AVAudioSessionCategoryMultiRoute

нет

да, несколько входов и выходов

нет

Наушники и USB-устройства воспроизводятся одновременно

AVAudioSessionCategoryOptionтип

Категория Тип опции

описывать

Применимые категории

AVAudioSessionCategoryOptionMixWithOthers

Поддержка смешанного воспроизведения с другими приложениями

AVAudioSessionCategoryPlayAndRecord、AVAudioSessionCategoryPlayback、AVAudioSessionCategoryMultiRoute

AVAudioSessionCategoryOptionDuckOthers

Уменьшите громкость звука других приложений и выделите громкость этого приложения.

AVAudioSessionCategoryPlayAndRecord、AVAudioSessionCategoryPlayback、AVAudioSessionCategoryMultiRoute

AVAudioSessionCategoryOptionAllowBluetooth

Поддержка аудиовхода Bluetooth

AVAudioSessionCategoryRecord、AVAudioSessionCategoryPlayAndRecord

AVAudioSessionCategoryOptionDefaultToSpeaker

Установить вывод звука по умолчанию на динамики

AVAudioSessionCategoryPlayAndRecord

AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers

Приложение иногда использует воспроизведение звука и останавливает звук других приложений во время воспроизведения.

AVAudioSessionCategoryPlayback、AVAudioSessionCategoryPlayAndRecord、AVAudioSessionCategoryMultiRoute

AVAudioSessionCategoryOptionAllowBluetoothA2DP

Поддержка стерео Bluetooth

AVAudioSessionCategoryPlayAndRecord

AVAudioSessionCategoryOptionAllowAirPlay

Поддерживает устройства AirPlay

AVAudioSessionCategoryPlayAndRecord

Язык кода:javascript
копировать

func setupAudioSession() {
    do {
        // Установите .notifyOthersOnDeactivation, когда Active для false да вступает в силу, уведомляя систему о том, что воспроизведение этого приложения закончилось и вы можете продолжить другие APP играть
        try AVAudioSession.sharedInstance().setActive(true, options: AVAudioSession.SetActiveOptions.notifyOthersOnDeactivation)
        
        // Переключайте настройки в соответствии с реальными потребностями Category
        try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, options: AVAudioSession.CategoryOptions.duckOthers)
    } catch {
        print("set AudioSession error: %@", error)
    }
}

Отображение панели уведомлений на экране блокировки

APP Поддержка фонового воспроизведенияназад,Вы можете видеть, что панель уведомлений существования уже отображается.,Но в даиграть прогресса нет,нет названия,Нет фотографий,только APP имя и Маленькая иконка. Код для изменения этой информации выглядит следующим образом:

Язык кода:javascript
копировать
#import <MediaPlayer/MPNowPlayingInfoCenter.h>
#import <MediaPlayer/MPRemoteCommandCenter.h>
#import <MediaPlayer/MPRemoteCommand.h>
#import <MediaPlayer/MPMediaItem.h>

// Обновление отображения панели уведомлений
- (void)updateNowPlaingInfo {
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    // Установить название песни
    [dict setValue:@"Title" forKey:MPMediaItemPropertyTitle];
    // Установить имя певца
    [dict setValue:@"Artist" forKey:MPMediaItemPropertyArtist];
    // Установить название альбома
    [dict setValue:@"AlbumTItle" forKey:MPMediaItemPropertyAlbumTitle];
    // Установите отображаемое изображение
    MPMediaItemArtwork *artwork = [[MPMediaItemArtwork alloc] initWithImage:ArtImage];
    [dict setValue:artwork forKey:MPMediaItemPropertyArtwork];
    // Установить продолжительность песни
    NSTimeInterval duration = self.player.duration;
    [dict setValue:[NSNumber numberWithDouble:duration] forKey:MPMediaItemPropertyPlaybackDuration];
    // Установить продолжительность игры
    NSTimeInterval currentTime = self.player.currentTime;
    [dict setValue:[NSNumber numberWithDouble:currentTime] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
    // Установить скорость игры
    [dict setValue:@(1.0) forKey:MPNowPlayingInfoPropertyPlaybackRate];
    
    // возобновлять
    [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dict];
}

А если вы хотите не отображать его в панели уведомлений после завершения воспроизведения, вы можете настроить его следующим образом

Язык кода:javascript
копировать

[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:@{}];

Установить панель уведомлений для управления игрой пауза、Предыдущий эпизод、Следующий выпуск,установивMPRemoteCommandCenterсерединаиз Атрибуты могут управлять соответствующими функциями.данет Открыть,Существует два способа обработки события ответа:

  • Способ первый,проходитьremoteControlReceivedWithEvent:метод,Ответ соответствует событию
  • методдва:проходитьMPRemoteCommandCenterизCommandПриходитьaddTargetПриходитьобработка корреспонденциисобытие

Код для настройки панели уведомлений, соответствующей функции данет, выглядит следующим образом:

Язык кода:javascript
копировать

// существовать AppDelegate середина,или соответствующийигратьиз Controller , откройте приемную систему управлениясобытием
// Приемная система управлениясобытием
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];

- (void)setupCommandCenter {
    MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
    [commandCenter.playCommand removeTarget:self];
    [commandCenter.pauseCommand removeTarget:self];
    
    // Запрещать pre, next
    commandCenter.previousTrackCommand.enabled = NO;
    commandCenter.nextTrackCommand.enabled = NO;
    
    // играть
    commandCenter.playCommand.enabled = YES;
    
    // пауза
    commandCenter.pauseCommand.enabled = YES;
    
    // игра и пауза (управление через наушники)
    commandCenter.togglePlayPauseCommand.enabled = NO;

    // тащитьрасписание    commandCenter.changePlaybackPositionCommand.enable = YES;
}

Код для ответа на метод обработки событий 1 выглядит следующим образом:

Язык кода:javascript
копировать

// Ответ на удаленное событие
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
    if (event.type == UIEventTypeRemoteControl) {
        switch (event.subtype) {
            case UIEventSubtypeRemoteControlPlay:
            {
                NSLog(@"RemoteControlEvents: play");
            }
                break;
            case UIEventSubtypeRemoteControlPause:
            {
                NSLog(@"RemoteControlEvents: pause");
            }
                break;
            case UIEventSubtypeRemoteControlTogglePlayPause:
                NSLog(@"Управление наушниками: пауза||играть");
                break;
            case UIEventSubtypeRemoteControlNextTrack:
            {
                NSLog(@"RemoteControlEvents: next");
            }
                break;
            case UIEventSubtypeRemoteControlPreviousTrack:
            {
                NSLog(@"RemoteControlEvents: previous");
            }
                break;
            default:
                break;
        }
    }
}

Код ответа на метод обработки событий 2 выглядит следующим образом:

Язык кода:javascript
копировать

- (void)setupCommandCenter {
    MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter];

    // играть
    [commandCenter.playCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
        NSLog(@"play");
        return MPRemoteCommandHandlerStatusSuccess;
    }];

    // пауза
    [commandCenter.pauseCommand addTarget:self action:@selector(handlePauseCommand:)];

    // тащитьрасписание    [commandCenter.changePlaybackPositionCommand addTarget:self action:@selector(handlePlaybackPositionCommand:)];
}

- (MPRemoteCommandHandlerStatus):(id)sender {
    NSLog(@"pause");
    return MPRemoteCommandHandlerStatusSuccess;
}

- (MPRemoteCommandHandlerStatus)handlePlaybackPositionCommand:
(MPChangePlaybackPositionCommandEvent *) event

{
    [self.palyer seekToTime:CMTimeMakeWithSeconds(event.positionTime, 1)];

    NSLog(@"changePlaybackPosition to %f", event.positionTime);

    return MPRemoteCommandHandlerStatusSuccess;
}

вопрос

Не добавлятьbeginReceivingRemoteControlEventsчас,данет отобразит панель уведомлений,данет Влияет на двоихметодиметь дело с Ответ на метод обработки событий 2 будет идти дважды Ход пользовательского воспроизведения не соответствует прогрессу на панели уведомлений.

ссылка

boy illustration
Учебное пособие по Jetpack Compose для начинающих, базовые элементы управления и макет
boy illustration
Код js веб-страницы, фон частицы, код спецэффектов
boy illustration
【новый! Суперподробное】Полное руководство по свойствам компонентов Figma.
boy illustration
🎉Обязательно к прочтению новичкам: полное руководство по написанию мини-программ WeChat с использованием программного обеспечения Cursor.
boy illustration
[Забавный проект Docker] VoceChat — еще одно приложение для мгновенного чата (IM)! Может быть встроен в любую веб-страницу!
boy illustration
Как реализовать переход по странице в HTML (html переходит на указанную страницу)
boy illustration
Как решить проблему зависания и низкой скорости при установке зависимостей с помощью npm. Существуют ли доступные источники npm, которые могут решить эту проблему?
boy illustration
Серия From Zero to Fun: Uni-App WeChat Payment Practice WeChat авторизует вход в систему и украшает страницу заказа, создает интерфейс заказа и инициирует запрос заказа
boy illustration
Серия uni-app: uni.navigateЧтобы передать скачок значения
boy illustration
Апплет WeChat настраивает верхнюю панель навигации и адаптируется к различным моделям.
boy illustration
JS-время конвертации
boy illustration
Обеспечьте бесперебойную работу ChromeDriver 125: советы по решению проблемы chromedriver.exe не найдены
boy illustration
Поле комментария, щелчок мышью, специальные эффекты, js-код
boy illustration
Объект массива перемещения объекта JS
boy illustration
Как открыть разрешение на позиционирование апплета WeChat_Как использовать WeChat для определения местонахождения друзей
boy illustration
Я даю вам два набора из 18 простых в использовании фонов холста Power BI, так что вам больше не придется возиться с цветами!
boy illustration
Получить текущее время в js_Как динамически отображать дату и время в js
boy illustration
Вам необходимо изучить сочетания клавиш vsCode для форматирования и организации кода, чтобы вам больше не приходилось настраивать формат вручную.
boy illustration
У ChatGPT большое обновление. Всего за 45 минут пресс-конференция показывает, что OpenAI сделал еще один шаг вперед.
boy illustration
Copilot облачной разработки — упрощение разработки
boy illustration
Микросборка xChatGPT с низким кодом, создание апплета чат-бота с искусственным интеллектом за пять шагов
boy illustration
CUDA Out of Memory: идеальное решение проблемы нехватки памяти CUDA
boy illustration
Анализ кластеризации отдельных ячеек, который должен освоить каждый&MarkerгенетическийВизуализация
boy illustration
vLLM: мощный инструмент для ускорения вывода ИИ
boy illustration
CodeGeeX: мощный инструмент генерации кода искусственного интеллекта, который можно использовать бесплатно в дополнение к второму пилоту.
boy illustration
Машинное обучение Реальный бой LightGBM + настройка параметров случайного поиска: точность 96,67%
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция без кодирования и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
LM Studio для создания локальных больших моделей
boy illustration
Как определить количество слоев и нейронов скрытых слоев нейронной сети?
boy illustration
[Отслеживание целей] Подробное объяснение ByteTrack и детали кода