Android Audio

ОС Android обеспечивает обширную поддержку мультимедиа, охватывая как аудио, так и видео. В этом руководстве основное внимание уделяется аудио в Android и охватывает воспроизведение и запись звука с помощью встроенных классов аудиопроигрывателя и записей, а также НИЗКОуровневого API аудио. Он также охватывает работу с событиями аудио, транслироваемыми другими приложениями, чтобы разработчики могли создавать хорошо себя приложения.

Обзор

Современные мобильные устройства приняли функциональные возможности, которые ранее требовали бы выделенных частей оборудования — камеры, музыкальные проигрыватели и видеозаписи. Из-за этого мультимедийные платформы стали первоклассной функцией в мобильных API.

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

  1. Воспроизведение звука с помощью MediaPlayer — использование встроенного MediaPlayer класса для воспроизведения звука, в том числе локальных звуковых файлов и потоковых звуковых файлов с классом AudioTrack .

  2. Запись звука — использование встроенного MediaRecorder класса для записи звука.

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

  4. Работа с низким уровнем звука — воспроизведение звука с помощью AudioTrack класса путем записи непосредственно в буферы памяти. Запись звука с помощью AudioRecord класса и чтение непосредственно из буферов памяти.

Требования

Для этого руководства требуется Android 2.0 (уровень API 5) или более поздней версии. Обратите внимание, что отладка звука на Android должна выполняться на устройстве.

Необходимо запросить RECORD_AUDIO разрешения в AndroidManifest.XML:

Необходимые разрешения в манифесте Android с включенным RECORD_AUDIO

Воспроизведение звука с помощью класса MediaPlayer

Самый простой способ воспроизведения звука в Android — это встроенный класс MediaPlayer . MediaPlayer может воспроизводить локальные или удаленные файлы, передав путь к файлу. MediaPlayer Однако очень чувствительны к состоянию и вызов одного из его методов в неправильном состоянии приведет к возникновению исключения. Важно взаимодействовать с MediaPlayer этим в порядке, описанном ниже, чтобы избежать ошибок.

Инициализация и воспроизведение

Для воспроизведения звука требуется MediaPlayer следующая последовательность:

  1. Создайте экземпляр нового объекта MediaPlayer .

  2. Настройте файл для воспроизведения с помощью метода SetDataSource .

  3. Вызовите метод Prepare для инициализации проигрывателя.

  4. Вызовите метод Start, чтобы запустить воспроизведение звука.

В приведенном ниже примере кода показано следующее использование:

protected MediaPlayer player;
public void StartPlayer(String  filePath)
{
  if (player == null) {
    player = new MediaPlayer();
  } else {
    player.Reset();
    player.SetDataSource(filePath);
    player.Prepare();
    player.Start();
  }
}

Приостановка и возобновление воспроизведения

Воспроизведение можно приостановить, вызвав метод Pause :

player.Pause();

Чтобы возобновить приостановленное воспроизведение, вызовите метод Start . Это возобновляется из приостановленного расположения воспроизведения:

player.Start();

Вызов метода Stop на проигрывателе завершает текущее воспроизведение:

player.Stop();

Если проигрыватель больше не нужен, ресурсы должны быть освобождены путем вызова метода Release :

player.Release();

Использование класса MediaRecorder для записи звука

Corollary для MediaPlayer записи звука в Android — это класс MediaRecorder . Как и в случае MediaPlayerс состоянием, он учитывает состояние и переходит через несколько состояний, чтобы добраться до точки, где она может начать запись. Чтобы записать звук, RECORD_AUDIO необходимо задать разрешение. Инструкции по настройке разрешений приложения см. в статье "Работа с AndroidManifest.xml".

Инициализация и запись

Запись звука с MediaRecorder помощью следующих действий:

  1. Создайте экземпляр нового объекта MediaRecorder .

  2. Укажите, какое аппаратное устройство используется для записи входных данных звука с помощью метода SetAudioSource .

  3. Задайте формат звука выходного файла с помощью метода SetOutputFormat . Список поддерживаемых типов звука см. в поддерживаемых форматах мультимедиа Android.

  4. Вызовите метод SetAudioEncoder, чтобы задать тип кодирования звука.

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

  6. Вызовите метод Prepare для инициализации средства записи.

  7. Вызовите метод Start, чтобы начать запись.

В следующем примере кода показана эта последовательность:

protected MediaRecorder recorder;
void RecordAudio (String filePath)
{
  try {
    if (File.Exists (filePath)) {
      File.Delete (filePath);
    }
    if (recorder == null) {
      recorder = new MediaRecorder (); // Initial state.
    } else {
      recorder.Reset ();
      recorder.SetAudioSource (AudioSource.Mic);
      recorder.SetOutputFormat (OutputFormat.ThreeGpp);
      recorder.SetAudioEncoder (AudioEncoder.AmrNb);
      // Initialized state.
      recorder.SetOutputFile (filePath);
      // DataSourceConfigured state.
      recorder.Prepare (); // Prepared state
      recorder.Start (); // Recording state.
    }
  } catch (Exception ex) {
    Console.Out.WriteLine( ex.StackTrace);
  }
}

Остановка записи

Чтобы остановить запись, вызовите метод в Stop :MediaRecorder

recorder.Stop();

Очистка

MediaRecorder После остановки вызовите метод Reset, чтобы вернуть его в состояние простоя:

recorder.Reset();

MediaRecorder Если ресурс больше не нужен, его ресурсы должны быть освобождены путем вызова метода Release:

recorder.Release();

Управление звуковыми уведомлениями

Класс AudioManager

Класс AudioManager предоставляет доступ к звуковым уведомлениям, которые позволяют приложениям знать, когда происходят звуковые события. Эта служба также предоставляет доступ к другим функциям звука, таким как управление режимом громкости и звонка. Приложение AudioManager позволяет приложению обрабатывать звуковые уведомления для управления воспроизведением звука.

Управление фокусом звука

Звуковые ресурсы устройства (встроенный проигрыватель и записыватель) совместно используются всеми запущенными приложениями.

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

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

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

Дополнительные сведения об фокусе звука см. в разделе "Управление фокусом звука".

Регистрация обратного вызова для фокуса звука

Регистрация обратного FocusChangeListener вызова из приложения IOnAudioChangeListener является важной частью получения и выпуска фокуса звука. Это связано с тем, что предоставление фокуса звука может быть отложено до последующего времени. Например, приложение может запросить воспроизведение музыки во время выполнения телефонного звонка. Аудиофокус не будет предоставлен до тех пор, пока телефонный звонок не будет завершен.

По этой причине объект обратного вызова передается как параметр GetAudioFocus в метод метода AudioManager, и это вызов, который регистрирует обратный вызов. Если звуковой фокус изначально запрещен, но позже предоставлен, приложение сообщается путем вызова OnAudioFocusChange обратного вызова. Тот же метод используется для того, чтобы сообщить приложению, что фокус звука убирается.

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

Запрос фокуса звука

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

  1. Получите дескриптор в системную AudioManager службу.

  2. Создайте экземпляр класса обратного вызова.

  3. Запросите звуковые ресурсы устройства, вызвав RequestAudioFocus метод в AudioManager . Параметры — это объект обратного вызова, тип потока (музыка, голосовой звонок, звонок и т. д.) и тип запрашиваемого права доступа (звуковые ресурсы можно запрашивать на данный момент или на неопределенный период, например).

  4. Если запрос предоставлен, playMusic метод вызывается немедленно, а звук начинает воспроизводиться.

  5. Если запрос отклонен, дальнейшие действия не принимаются. В этом случае звук будет воспроизводиться только в том случае, если запрос предоставлен позже.

В приведенном ниже примере кода показаны следующие действия.

Boolean RequestAudioResources(INotificationReceiver parent)
{
  AudioManager audioMan = (AudioManager) GetSystemService(Context.AudioService);
  AudioManager.IOnAudioFocusChangeListener listener  = new MyAudioListener(this);
  var ret = audioMan.RequestAudioFocus (listener, Stream.Music, AudioFocus.Gain );
  if (ret == AudioFocusRequest.Granted) {
    playMusic();
    return (true);
  } else if (ret == AudioFocusRequest.Failed) {
    return (false);
  }
  return (false);
}

Выпуск фокуса звука

После завершения AbandonFocus воспроизведения дорожки вызывается метод AudioManager . Это позволяет другому приложению получать звуковые ресурсы устройства. Другие приложения получат уведомление об изменении фокуса звука, если они зарегистрировали собственные прослушиватели.

API звука низкого уровня

Низкоуровневые API аудио обеспечивают больший контроль над воспроизведением звука и записью, так как они взаимодействуют напрямую с буферами памяти вместо использования URI файлов. Существует несколько сценариев, в которых этот подход предпочтителен. Ниже приведены соответствующие сценарии.

  1. При воспроизведении из зашифрованных звуковых файлов.

  2. При воспроизведении последовательности коротких клипов.

  3. Потоковая передача звука.

Класс AudioTrack

Класс AudioTrack использует низкоуровневые API аудио для записи и является низким эквивалентом MediaPlayer класса.

Инициализация и воспроизведение

Для воспроизведения звука необходимо создать экземпляр нового экземпляра AudioTrack . Список аргументов, переданный в конструктор , указывает, как воспроизводить образец звука, содержащийся в буфере. Аргументы:

  1. Тип потока — голос, мелодия, музыка, система или сигнализация.

  2. Частота — частота выборки, выраженная в Гц.

  3. Конфигурация канала — Mono или стерео.

  4. Формат звука — 8-разрядная или 16-разрядная кодировка.

  5. Размер буфера — в байтах.

  6. Режим буфера — потоковая передача или статический.

После построения вызывается метод AudioTrack Play, чтобы настроить его для начала воспроизведения. Запись звукового буфера в AudioTrack начало воспроизведения:

void PlayAudioTrack(byte[] audioBuffer)
{
  AudioTrack audioTrack = new AudioTrack(
    // Stream type
    Stream.Music,
    // Frequency
    11025,
    // Mono or stereo
    ChannelOut.Mono,
    // Audio encoding
    Android.Media.Encoding.Pcm16bit,
    // Length of the audio clip.
    audioBuffer.Length,
    // Mode. Stream or static.
    AudioTrackMode.Stream);

    audioTrack.Play();
    audioTrack.Write(audioBuffer, 0, audioBuffer.Length);
}

Приостановка и остановка воспроизведения

Вызовите метод Pause, чтобы приостановить воспроизведение:

audioTrack.Pause();

Вызов метода Stop завершает воспроизведение безвозвратно:

audioTrack.Stop();

Очистка

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

audioTrack.Release();

Класс AudioRecord

Класс AudioRecord является эквивалентом AudioTrack на стороне записи. Например AudioTrack, он использует буферы памяти непосредственно вместо файлов и URI. Для этого требуется, чтобы RECORD_AUDIO разрешение было задано в манифесте.

Инициализация и запись

Первым шагом является создание нового объекта AudioRecord . Список аргументов, переданный в конструктор , предоставляет все сведения, необходимые для записи. AudioTrackВ отличие от того, где аргументы являются в основном перечислениями, эквивалентные аргументы в AudioRecord целых числах. Например:

  1. Аппаратный источник входного звука, например микрофон.

  2. Тип потока — голос, мелодия, музыка, система или сигнализация.

  3. Частота — частота выборки, выраженная в Гц.

  4. Конфигурация канала — Mono или стерео.

  5. Формат звука — 8-разрядная или 16-разрядная кодировка.

  6. Размер буфера в байтах

AudioRecord После создания вызывается его метод StartRecording. Теперь он готов начать запись. Непрерывно AudioRecord считывает звуковой буфер для входных данных и записывает его в звуковой файл.

void RecordAudio()
{
  byte[] audioBuffer = new byte[100000];
  var audRecorder = new AudioRecord(
    // Hardware source of recording.
    AudioSource.Mic,
    // Frequency
    11025,
    // Mono or stereo
    ChannelIn.Mono,
    // Audio encoding
    Android.Media.Encoding.Pcm16bit,
    // Length of the audio clip.
    audioBuffer.Length
  );
  audRecorder.StartRecording();
  while (true) {
    try
    {
      // Keep reading the buffer while there is audio input.
      audRecorder.Read(audioBuffer, 0, audioBuffer.Length);
      // Write out the audio file.
    } catch (Exception ex) {
      Console.Out.WriteLine(ex.Message);
      break;
    }
  }
}

Остановка записи

Вызов метода Stop завершает запись:

audRecorder.Stop();

Очистка

AudioRecord Если объект больше не нужен, вызов метода Release освобождает все ресурсы, связанные с ним:

audRecorder.Release();

Итоги

Ос Android предоставляет мощную платформу для воспроизведения, записи и управления звуком. В этой статье описано, как воспроизводить и записывать звук с помощью высокоуровневых MediaPlayer и MediaRecorder классов. Далее он изучил, как использовать звуковые уведомления для совместного использования звуковых ресурсов устройства между различными приложениями. Наконец, речь идет о том, как воспроизводить и записывать звук с помощью интерфейсов API низкого уровня, которые напрямую интерфейсируются с буферами памяти.