Аудио закадровый голос, когда iPhone заблокирован

Решение ниже

Я работаю над работающим приложением, которое дает инструкции за кадром в начале каждого упражнения. Он работает по назначению, когда устройство активно, но не работает, когда телефон заблокирован. [Текущий звук продолжается, но не воспроизводится в будущем.]

Вопрос Как я могу начать воспроизведение закадрового голоса, когда iPhone пользователя заблокирован.

В настоящее время я отслеживаю тренировку, используя Timer.scheduledTimer для двух таймеров, которые я показываю [текущая активность и общая тренировка]. Когда таймер достигает заранее заданного времени ближе к концу одного действия, воспроизводится голос за кадром, чтобы представить следующее действие. Срабатывание таймера запускает звук, и я считаю, что проблема в этом. Я могу приостанавливать тренировку, пропускать разделы, и все работает нормально - пока устройство не заблокируется.

Если при нажатии кнопки «Домой» или блокировке iPhone воспроизводится закадровый голос, он продолжает воспроизводиться должным образом. Проблема в том, что таймер не срабатывает, поэтому следующая озвучка [скажем, через 90 секунд] никогда не воспроизводится.

В некоторых ответах и ​​комментариях, которые я прочитал, говорится, что эта функция просто невозможна в iOS. Приложение Couch to 5k https://itunes.apple.com/gb/app/one-you-couch-to-5k/id1082307672?mt=8 использует эту функцию, поэтому я знаю, что этого можно достичь, но я просто не знаю, как они » повторю это. [Это будет специальный участник, который загрузит его, чтобы понять, что я имею в виду :)]

Из поиска SO Я прочитал много сообщений, в которых говорится, что Timer или NSTimer не могут работать, когда приложение находится в фоновом режиме или телефон заблокирован. Любые сообщения, в которых говорится, что это может работать, старые и основаны на iOS4 / 5.

Я читал о предложениях использовать тишину и, по сути, иметь один длинный аудиофайл. Хотя это создало бы некоторые новые проблемы для пропуска разделов тренировки, я также читал комментарии, в которых говорится, что такое поведение не пройдет тестирование Apple для приложения для AppStore. Третий недостаток в том, что размер моего аудиофайла увеличится.

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

Как я могу достичь той же функциональности, что и приложение Couch to 5k?

Спасибо


person Steve Hancocks    schedule 29.01.2019    source источник


Ответы (2)


Хорошо, я разработал решение для воспроизведения звуковых подсказок пользователю в течение 30-минутной тренировки, даже если iPhone заблокирован или приложение работает в фоновом режиме. Приложение было отправлено и одобрено для размещения в AppStore.

Чтобы приложение работало должным образом, я использую 2 AVAudioPlayers; один воспроизводит закадровый голос, другой - 15-минутную дорожку тишины [так как это отдельная дорожка и просто без звука, это низкий качество .mp3 и только добавление 900 КБ к размеру приложения]. 15 минут намного превышают любой интервал между озвучкой, так что это отлично работает.

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

Когда закадровый голос заканчивается, вызывается AVAudioPlayerDelegate метод audioPlayerDidFinishPlaying. С помощью этого метода я сбрасываю свойства звука [я вскоре объясню почему], создаю экземпляр своего беззвучного AVAudioPlayer и начинаю проигрывать 15-минутный трек молчания. Воспроизведение другой дорожки с использованием этого метода делегата означает, что в фоновом звуке нет реального прерывания, поэтому приложение остается в рабочем состоянии. Когда приложение "живо", таймер продолжает обратный отсчет. Когда приходит время наложения голоса, таймер вызывает метод, который сбрасывает категорию аудио, создает экземпляр моего голоса за кадром AVAudioPlayer и воспроизводит голос за кадром. Этот процесс повторяется до финального озвучивания. Когда это завершится, тишина больше не воспроизводится, и приложение может быть безопасно отключено.

Закадровый голос должен заглушать музыку пользователей [уменьшает громкость музыки, чтобы звук был отчетливо слышен]. Беззвучный звук не должен этого делать, музыка должна продолжать играть на полной громкости. Поскольку оба AVAudioPlayer используют AVAudioSession.sharedInstance, я обнаружил, что мне пришлось деактивировать sharedInstance, сбросить свойства с .duckOthers или без него, а затем повторно активировать sharedInstance перед созданием моего AVAudioSession. Это дало мне желаемый результат. Постоянный фоновый звук, который заглушает музыку пользователей только при воспроизведении голоса за кадром.

do{
    try AVAudioSession.sharedInstance().setActive(false)
    try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.interruptSpokenAudioAndMixWithOthers, .duckOthers])
    try AVAudioSession.sharedInstance().setActive(true)
} catch{
        print(error.localizedDescription)
}

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

person Steve Hancocks    schedule 12.06.2019

Мое понимание VoiceOver приводит меня к тому, что только приложение переднего плана может контролировать то, что оно читает.

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

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

person XLE_22    schedule 05.06.2019
comment
Спасибо XLE ???????? Я действительно нашел способ получить желаемый результат, который был одобрен для App Store. Ваш ответ побудил меня добавить свое решение, если оно понадобится другим в будущем. Я напишу исчерпывающий ответ сегодня вечером. - person Steve Hancocks; 05.06.2019