カスタムオーディオドライバー(Android)

概要

OpenTok Android SDK を使用すると、パブリッシャーおよびサブスクライバー向けにカスタムオーディオドライバーを設定できます。カスタムオーディオドライバーを使用することで、パブリッシャーのストリームに送信されるオーディオをカスタマイズできます。また、サブスクライブしたストリームのオーディオの再生をカスタマイズすることも可能です。

プロジェクトの設定

このセクションのコードは、の「Basic-Audio-Driver-Java」プロジェクトで入手可能です。 opentok-android-sdk-samples レポジトリにクローンする必要があります。まだの場合は、レポをローカル・ディレクトリにクローンする必要がある。コマンドラインで

git clone git@github.com:Vonage/vonage-video-android-sdk-samples.git

を開く。 Basic-Audio-Java プロジェクトをAndroid Studioで実行する。

注: このチュートリアルでは、Android サンプルアプリの Java 版について解説します。ドキュメント付きの Kotlin 版については、 Androidサンプルアプリレポ.

手順 1:カスタムオーディオドライバの追加

このサンプルアプリケーションは、カスタムオーディオドライバを使用して、オーディオストリームにホワイトノイズ(ランダムなオーディオ信号)をパブリッシュします。また、カスタムオーディオドライバを使用して、サブスクライブされたストリームからオーディオをキャプチャし、ファイルに保存します。

オーディオデバイスとオーディオバスの設定

カスタムオーディオドライバを使用する場合、アプリが使用するカスタムオーディオドライバとオーディオバスを定義します。

について NoiseAudioDevice クラスは、アプリが使用する基本的なオーディオ・デバイス・インターフェースを定義します。このクラスは BaseAudioDevice OpenTok Android SDK で定義されているクラスです。カスタムオーディオドライバーを使用するには、 AudioDeviceManager.setAudioDevice() メソッドを使用します。このサンプルでは、オーディオ・デバイスを NoiseAudioDevice クラスである:

AudioDeviceManager.setAudioDevice(noiseAudioDevice);

を使用する。 AudioSettings OpenTok Android SDK で定義されているこのクラスを使用して、カスタムオーディオドライバーで使用されるオーディオ形式を定義します。この NoiseAudioDevice() コンストラクタは AudioSettings カスタムオーディオキャプチャラー用とカスタムオーディオレンダラー用のインスタンスです。それぞれのサンプルレートとチャンネル数を設定します:

public NoiseAudioDevice(Context context) {
    this.context = context;

    captureSettings = new AudioSettings(SAMPLING_RATE, NUM_CHANNELS_CAPTURING);
    rendererSettings = new AudioSettings(SAMPLING_RATE, NUM_CHANNELS_RENDERING);

    capturerStarted = false;
    rendererStarted = false;

    audioDriverPaused = false;

    capturerHandler = new Handler();
    rendererHandler = new Handler();
}

コンストラクタはまた、デバイスがキャプチャ中かレンダリング中かを報告するいくつかのローカルプロパティを設定する。を処理するHandlerインスタンスも設定します。 capturer 実行可能オブジェクト。

について NoiseAudioDevice.getAudioBus() メソッドは AudioBus インスタンスによって定義される。 NoiseAudioDevice.AudioBus クラスを使用する。を使用する。 AudioBus インスタンスにアクセスし、セッションとの間でオーディオサンプルを送受信します。パブリッシャーは AudioBus オブジェクトにオーディオサンプルを送信します。サブスクライバは、(サブスクライブしたストリームからの)オーディオサンプルを AudioBus オブジェクトに送信します。

出版社で使用する音声のキャプチャー

について BaseAudioDevice.startCapturer() メソッドは、オーディオデバイスがパブリッシュするオーディオのキャプチャを開始するときに呼び出されます。このメソッドは NoiseAudioDevice このメソッドの実装は capturer スレッドが1秒後にキューで実行される:

public boolean startCapturer() {
    capturerStarted = true;
    capturerHandler.postDelayed(capturer, capturerIntervalMillis);
    return true;
}

について capturer スレッドはランダムデータ(ホワイトノイズ)のサンプルを含むバッファを生成する。そして writeCaptureData() のメソッドを使用する。 AudioBus オブジェクトがサンプルをオーディオバスに送信します。アプリケーションのパブリッシャーは、オーディオバスに送られたサンプルを使って、パブリッシュされたストリームにオーディオとして送信します。そして、キャプチャがまだ進行中であれば(アプリがパブリッシュしていれば capturer スレッドはさらに1秒後に再び実行される:

private Runnable capturer = new Runnable() {
    @Override
    public void run() {
        capturerBuffer.rewind();

        Random rand = new Random();
        rand.nextBytes(capturerBuffer.array());

        getAudioBus().writeCaptureData(capturerBuffer, SAMPLING_RATE);

        if(capturerStarted && !audioDriverPaused) {
            capturerHandler.postDelayed(capturer, capturerIntervalMillis);
        }
    }
};

AudioDevice クラスには、NoiseAudioDevice クラスによって実装されている他のメソッドも含まれています。ただし、このサンプルではこれらのメソッドで特に興味深い処理は行われていないため、ここではこれらについては触れません。

ステップ 2: カスタムオーディオレンダラーの追加

購読ストリームのオーディオ用のシンプルなオーディオ・レンダラーを実装します。

について NoiseAudioDevice() コンストラクタメソッドは、入力オーディオをファイルに保存するための設定を行います。これは、カスタムオーディオドライバのオーディオレンダラーの使用例を示すためだけのものです。このアプリには、 AndroidManifest.xml ファイル:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

について BaseAudioDevice.initRenderer() メソッドは、アプリがオーディオレンダラーを初期化するときに呼び出されます。このメソッドは NoiseAudioDevice このメソッドを実装すると、新しいFileオブジェクトがインスタンス化され、そこにアプリがオーディオデータを書き込みます:

@Override
public boolean initRenderer() {
    rendererBuffer = ByteBuffer.allocateDirect(SAMPLING_RATE * 2); // Each sample has 2 bytes
    File documentsDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
    rendererFile = new File(documentsDirectory, "output.raw");

    if (!rendererFile.exists()) {
        try {
            rendererFile.getParentFile().mkdirs();
            rendererFile.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    return true;
}

について BaseAudioDevice.startRendering() メソッドは、オーディオデバイスがサブスクライブしたストリームからオーディオのレンダリング(再生)を開始するときに呼び出される。このメソッドは NoiseAudioDevice このメソッドの実装は capturer スレッドが1秒後にキューで実行される:

 @Override
 public boolean startRenderer() {
     rendererStarted = true;
     rendererHandler.postDelayed(renderer, rendererIntervalMillis);
     return true;
 }

について renderer スレッドは、オーディオバスから1秒分のオーディオを取得する。 readRenderData() のメソッドを使用する。 AudioBus オブジェクトを作成します。そして、オーディオデータをファイルに書き込みます(サンプル用)。また、オーディオデバイスがまだオーディオサンプルのレンダリングに使われている場合は、タイマーをセットして rendererHandler 0.1秒後に再びスレッドを実行する:

private Handler rendererHandler;

private Runnable renderer = new Runnable() {
    @Override
    public void run() {
        rendererBuffer.clear();
        getAudioBus().readRenderData(rendererBuffer, SAMPLING_RATE);

        try {
            FileOutputStream stream = new FileOutputStream(rendererFile);
            stream.write(rendererBuffer.array());
            stream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (rendererStarted && !audioDriverPaused) {
            rendererHandler.postDelayed(renderer, rendererIntervalMillis);
        }
    }
};

この例は、説明のために意図的に単純化されています。単にオーディオデータをファイルに書き込むだけのものです。カスタムオーディオドライバをより実用的な場面で活用する場合、このドライバを使用してBluetoothデバイスにオーディオを再生したり、再生前にオーディオを処理したりすることができます。

おめでとうございます!Android向けカスタムオーディオドライバーのチュートリアルを完了しました。
ここで作成したコードをさらに試したり調整したりすることもできますし、あるいは 次のステップ の下にある。

次のステップ

ここでの作業が終わったら、以下の役立つリソースを活用して、OpenTokアプリケーションの構築と機能強化を続けてください: