Выполнение вибрации в приложении записи

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

  • Чтобы поддерживать воспроизведение и запись (вывод и ввод), мне нужно использовать AVAudioSessionCategoryPlayAndRecord
  • Заставить телефон вибрировать через AudioServicesPlaySystemSound (kSystemSoundID_Vibrate) не поддерживается ни в одной из категорий записи, включая AVAudioSessionCategoryPlayAndRecord,
  • Включить другие приложения для воспроизведения аудио можно, добавив параметр AVAudioSessionCategoryOptionMixWithOthers,

Поэтому я делаю это в моем делегате приложения:

NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionMixWithOthers error:&error];

Возможные решения для создания вибрации, которые я пробовал, но не смогли:

  • Деактивация общего AVAudioSession до вибрации, а затем активируйте его сразу после.

    [[AVAudioSession sharedInstance] setActive:NO error:nil];         
    AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
    [[AVAudioSession sharedInstance] setActive:YES error:nil];
    

    Это успешно выполняет вибрацию, но после этого, когда я пытаюсь записать фильм, звук приглушается (или что-то еще заставляет его быть очень тихим). Это также дает мне сообщение об ошибке, в котором говорится, что я не могу деактивировать сеанс без предварительного удаления его устройств ввода-вывода.

  • Изменение категории перед вибрацией, а затем ее изменение обратно.

    [[AVAudioSession sharedInstance] setActive:NO error:nil];
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
    [[AVAudioSession sharedInstance] setActive:YES error:nil];
    
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
    
    [[AVAudioSession sharedInstance] setActive:NO error:nil];
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionMixWithOthers error:nil];
    [[AVAudioSession sharedInstance] setActive:YES error:nil];
    

    Это решение приходит время от времени, но, похоже, не работает для меня. Вибрации не происходит, хотя категории, кажется, установлены. Это может быть правильным решением, если я установлю usesApplicationAudioSession = YES на моем AVCaptureSession, но я еще не заставил его работать.

Источники:

4 ответа

Итак, я недавно пытался воспроизвести простой звуковой сигнал в своем приложении, и один из методов, с которыми я столкнулся, это:

AudioServicesPlaySystemSound(SystemSoundID inSystemSoundID);

Это функция, которая воспроизводит системный звук /System/Library/Audio/UISounds/ поддерживается на всех версиях iOS.

Звук 1350 равняется RingerVibeChanged (Вибрация). Так..

AudioServicesPlaySystemSound(1350);

... вибрирует примерно 0,5 секунды.

Если вам интересно больше звуков, здесь есть ссылка на все воспроизводимые звуки и версии iOS, в которые они были добавлены: http://iphonedevwiki.net/index.php/AudioServices

Вы не сказали, каковы ваши требования к поддерживаемым устройствам, но для более новых устройств вы можете использовать новые API-интерфейсы Taptic Engine, такие как:

UIImpactFeedbackGenerator

UISelectionFeedbackGenerator

UINotificationFeedbackGenerator

https://developer.apple.com/reference/uikit/uifeedbackgenerator

Для справки я не пользуюсь AVCaptureSession но AVAudioEngine чтобы записать что-то, и для моего случая я указал на необходимость приостановить ввод, чтобы правильно воспроизвести вибрацию с AudioServicesPlaySystemSound во время записи сессии.

Так что в моем случае я сделал что-то вроде этого

audioEngine?.pause()
AudioServicesPlaySystemSound(1519)
do {
  try audioEngine.start()
} catch let error {
  print("An error occurred starting audio engine. \(error.localizedDescription)")
}

Я не уверен, будет ли это работать с чем-то похожим для AVCaptureSession (То есть, stopRunning() а также startRunning()), но оставив это здесь на случай, если кто-то захочет попробовать.

Вы можете попробовать установитьallowHapticsAndSystemSoundsDuringRecordingфлаг на AVAudioSessionв true (флаг по умолчанию имеет значение false ), вызвав

      sessionInstance.setAllowHapticsAndSystemSoundsDuringRecording(true)

Это сработало для меня.

Обратите внимание, что система предотвращает тактильную и звуковую обратную связь (например, от UIPickerViewили же UIDatePicker) во время воспроизведения, чтобы избежать неожиданного системного шума во время записи.

Другие вопросы по тегам