Android オーディオ

Android OS では、オーディオとビデオの両方を網羅するマルチメディアの広範なサポートが提供されます。 このガイドでは、Android のオーディオに焦点を当て、組み込みのオーディオ プレーヤーとレコーダー クラス、および低レベルのオーディオ API を使用したオーディオの再生と録音について説明します。 また、開発者が適切に動作するアプリケーションを構築できるように、他のアプリケーションによってブロードキャストされるオーディオ イベントの操作についても説明します。

概要

最新のモバイル デバイスでは、以前は専用の機器 (カメラ、音楽プレーヤー、ビデオ レコーダー) を必要としていた機能が採用されています。 このため、マルチメディア フレームワークが Mobile API の最上位の機能になっています。

Android では、マルチメディアの広範なサポートが提供されます。 この記事では、Android におけるオーディオの操作について説明し、以下のトピックを取り上げます

  1. MediaPlayer を使用したオーディオの再生 – 組み込みの MediaPlayer クラスを使用してオーディオを再生します。これには、ローカル オーディオ ファイルや、AudioTrack クラスでストリーミングされたオーディオ ファイルが含まれます。

  2. オーディオの録音 – 組み込みの MediaRecorder クラスを使用してオーディオを録音します。

  3. オーディオ通知の操作 – オーディオ通知を使用して、オーディオ出力を一時停止または取り消すことでイベント (着信通話など) に正しく応答する適切な動作のアプリケーションを作成します。

  4. 低レベル オーディオの操作 – メモリ バッファーに直接書き込むことで、AudioTrack クラスを使用してオーディオを再生します。 AudioRecord クラスを使用してオーディオを録音し、メモリ バッファーから直接読み取ります。

要件

このガイドでは、Android 2.0 (API レベル 5) 以降が必要です。 Android でのオーディオのデバッグは、デバイスで行う必要があることに注意してください。

AndroidManifest.XMLRECORD_AUDIO アクセス許可を要求する必要があります。

Required permissions section of Android Manifest with RECORD_AUDIO enabled

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 クラスを使用したオーディオの録音

Android でオーディオを録音するための MediaPlayer の結果は、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);
  }
}

録音の停止

録音を停止するには、MediaRecorderStop メソッドを呼び出します。

recorder.Stop();

クリーンアップ

MediaRecorder が停止したら、Reset メソッドを呼び出してアイドル状態に戻します。

recorder.Reset();

MediaRecorder が不要になったら、Release メソッドを呼び出してリソースを解放する必要があります。

recorder.Release();

オーディオ通知の管理

AudioManager クラス

AudioManager クラスは、オーディオ イベントが発生した時点をアプリケーションに知らせるオーディオ通知にアクセスできるようにします。 また、このサービスでは、音量や着信音モードの制御など、他のオーディオ機能にもアクセスできます。 AudioManager を使用すると、アプリケーションはオーディオ通知を処理してオーディオの再生を制御できます。

オーディオ フォーカスの管理

デバイスのオーディオ リソース (組み込みのプレーヤーとレコーダー) は、実行中のすべてのアプリケーションで共有されます。

概念的には、これは、1 つのアプリケーションのみがキーボード フォーカスを持つデスクトップ コンピューター上のアプリケーションに似ています。実行中のいずれかのアプリケーションをマウスクリックで選択した後、キーボード入力はそのアプリケーションのみに適用されます。

オーディオ フォーカスは同様の考え方であり、複数のアプリケーションが同時にオーディオを再生または録音するのを防ぎます。 これはキーボード フォーカスよりも複雑です。オーディオ フォーカスは自発的であり、アプリケーションは現在オーディオ フォーカスがないという事実を無視して、再生できます。また、要求できるオーディオ フォーカスには、複数の異なる種類があるためです。 たとえば、要求元が非常に短い時間だけオーディオを再生することを必要とする場合、一時的なフォーカスを要求できます。

オーディオ フォーカスはすぐに許可されるか、最初は拒否され、後で許可される場合があります。 たとえば、アプリケーションが通話中にオーディオ フォーカスを要求した場合は拒否されますが、通話が完了すればフォーカスが許可されるでしょう。 この場合、オーディオ フォーカスが取り除かれると、それに応じて応答するためにリスナーが登録されます。 オーディオ フォーカスの要求は、オーディオの再生または録音に問題があるかどうかを判断するために使用されます。

オーディオ フォーカスの詳細については、オーディオ フォーカスの管理に関するページを参照してください。

オーディオ フォーカスのコールバックの登録

IOnAudioChangeListener から FocusChangeListener コールバックを登録することは、オーディオ フォーカスの取得と解放の重要な部分です。 これは、オーディオ フォーカスの許可が後日まで延期される可能性があるためです。 たとえば、通話が進行中にアプリケーションが音楽の再生を要求する場合があります。 オーディオ フォーカスが許可されるのは、通話が終了した後です。

このため、コールバック オブジェクトはパラメーターとして AudioManagerGetAudioFocus メソッドに渡され、コールバックを登録するのはこの呼び出しです。 オーディオ フォーカスが最初に拒否されたものの、後で許可された場合、コールバックで OnAudioFocusChange を呼び出すことでアプリケーションに通知されます。 同じ方法を使用して、オーディオ フォーカスが取り除かれることをアプリケーションに通知します。

アプリケーションがオーディオ リソースを使用し終わると、AudioManagerAbandonFocus メソッドを呼び出し、コールバックを再び渡します。 これにより、コールバックの登録が解除され、オーディオ リソースが解放されて、他のアプリケーションがオーディオ フォーカスを取得できるようになります。

オーディオ フォーカスの要求

デバイスのオーディオ リソースを要求するために必要な手順は次のとおりです。

  1. AudioManager システム サービスへのハンドルを取得します。

  2. コールバック クラスのインスタンスを作成します。

  3. AudioManagerRequestAudioFocus メソッドを呼び出して、デバイスのオーディオ リソースを要求します。 パラメーターは、コールバック オブジェクト、ストリームの種類 (音楽、音声通話、リングなど)、および要求されるアクセス権の種類です (たとえば、オーディオ リソースは一時的に要求することも、無期限に要求することもできます)。

  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);
}

オーディオ フォーカスの解放

トラックの再生が完了すると、AudioManagerAbandonFocus メソッドが呼び出されます。 これにより、別のアプリケーションがデバイスのオーディオ リソースを取得できるようになります。 他のアプリケーションは、独自のリスナーを登録している場合、このオーディオ フォーカスの変更の通知を受け取ります。

低レベルのオーディオ API

低レベルのオーディオ API は、ファイル URI を使用する代わりにメモリ バッファーと直接やり取りするため、オーディオの再生と録音をより細かく制御できます。 この方法が望ましいシナリオがいくつかあります。 これらのシナリオは、次のとおりです。

  1. 暗号化されたオーディオ ファイルから再生する場合。

  2. 一連のショート クリップを再生する場合。

  3. オーディオ ストリーミング。

AudioTrack クラス

AudioTrack クラスは、録音に低レベルのオーディオ API を使用し、MediaPlayer クラスと同等の低いレベルです。

初期化と再生

オーディオを再生するには、AudioTrack の新しいインスタンスをインスタンス化する必要があります。 コンストラクターに渡される引数リストは、バッファーに含まれるオーディオ サンプルの再生方法を指定します。 引数は次のとおり。

  1. ストリームの種類 – 音声、着信音、音楽、システムまたはアラーム。

  2. 周波数 – Hz で表されるサンプリング レート。

  3. チャネル構成 – モノラルまたはステレオ。

  4. オーディオ形式 – 8 ビットまたは 16 ビットのエンコード。

  5. バッファー サイズ – バイト単位。

  6. バッファー モード – ストリーミングまたは静的。

作成後、AudioTrackPlay メソッドが呼び出され、再生を開始するようにセットアップされます。 オーディオ バッファーを 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 が不要になったら、Release を呼び出してリソースを解放する必要があります。

audioTrack.Release();

AudioRecord クラス

AudioRecord クラスは、録音側の AudioTrack と同等です。 AudioTrack と同様に、ファイルと URI の代わりにメモリ バッファーを直接使用します。 マニフェストで RECORD_AUDIO アクセス許可が設定されている必要があります。

初期化と録音

最初の手順では、新しい AudioRecord オブジェクトを構築します。 コンストラクターに渡される引数リストは、録音に必要なすべての情報を提供します。 引数が主に列挙型である AudioTrack とは異なり、AudioRecord で等価の引数は整数です。 これには以下が含まれます。

  1. マイクなどのハードウェア オーディオ入力ソース。

  2. ストリームの種類 – 音声、着信音、音楽、システムまたはアラーム。

  3. 周波数 – Hz で表されるサンプリング レート。

  4. チャネル構成 – モノラルまたはステレオ。

  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 OS は、オーディオの再生、録音、管理のための強力なフレームワークを備えています。 この記事では、高レベルの MediaPlayerMediaRecorder クラスを使用してオーディオを再生および録音する方法を取り上げました。 次に、オーディオ通知を使用して、さまざまなアプリケーション間でデバイスのオーディオ リソースを共有する方法について説明しました。 最後に、メモリ バッファーと直接インターフェイスする低レベル API を使用してオーディオを再生および録音する方法について説明しました。