1

sip 通話中に、dtmf 番号を送信したい場合があります。
これを行うために、キーが押されたときにそのキーのサウンドを再生するカスタム ダイヤル パッドを作成しましたが、一口通話中にはそのサウンドを再生しません (通話がない場合、サウンドが再生されます)。
これらのサウンドは、AudioToolbox.hライブラリ ( AudioServicesPlaySystemSound(soundID)) の関数で再生されます。

sip 呼び出し中にサウンドを再生できるようにするために、pjsip (pjsua) または AudioToolbox ライブラリで設定する必要があるプロパティはありますか?
私はこれが可能であることを知っています(Briaにはこれがあり、Groundwireもあり、pjsipを使用してsipを実装しているかどうかはわかりません)。

4

1 に答える 1

8

この回答は、次の 2 つのリンクからのコード スニペットの組み合わせです: PJSUA-API Media ManipulationpjsipDll_PlayWav.cpp

pjsua が通話を発信するとき、通話先との間でメディアをデバイスのスピーカーに転送するために、ポート (会議ポート) を使用しています。同時に複数のポートを開くことができます

キーパッド ボタンのクリック音を再生するために、もう 1 つのポートを開いて音を再生します (この場合は wav ファイルであり、avi ファイルをストリーミングするための pjsua 関数もあります)。 .
これを行うには、次の関数を使用します。

 pj_status_t    pjsua_conf_connect (pjsua_conf_port_id source, pjsua_conf_port_id sink)

ここで、シンク ポートはデバイスのスピーカー ポートであり、この場合 (そしてほとんどの場合) は 0 です。

以下のすべての関数は pjsua_app.c ファイルに追加されます。Objective-C クラスで使用される場所の前に、次のような行を追加する必要があります。

pj_status_t play_sound_during_call(pj_str_t sound_file);

ここでサウンドを再生するには、次の関数を使用します。

pj_status_t play_sound_during_call(pj_str_t sound_file)
{
    pjsua_player_id player_id;
    pj_status_t status;
    status = pjsua_player_create(&sound_file, 0, &player_id);
    if (status != PJ_SUCCESS)
        return status;

    pjmedia_port *player_media_port;

    status = pjsua_player_get_port(player_id, &player_media_port);
    if (status != PJ_SUCCESS)
    {
        return status;
    }

    pj_pool_t *pool = pjsua_pool_create("my_eof_data", 512, 512);
    struct pjsua_player_eof_data *eof_data = PJ_POOL_ZALLOC_T(pool, struct pjsua_player_eof_data);
    eof_data->pool = pool;
    eof_data->player_id = player_id;

    pjmedia_wav_player_set_eof_cb(player_media_port, eof_data, &on_pjsua_wav_file_end_callback);

    status = pjsua_conf_connect(pjsua_player_get_conf_port(player_id), 0);

    if (status != PJ_SUCCESS)
    {
        return status;
    }        

    return status;
}

そして、wav ファイルの読み取り (再生) が終了したときにリッスンするコールバック関数を次に示します。

struct pjsua_player_eof_data
{
    pj_pool_t          *pool;
    pjsua_player_id player_id;
};

static PJ_DEF(pj_status_t) on_pjsua_wav_file_end_callback(pjmedia_port* media_port, void* args)
{
    pj_status_t status;

    struct pjsua_player_eof_data *eof_data = (struct pjsua_player_eof_data *)args;

    status = pjsua_player_destroy(eof_data->player_id);

    PJ_LOG(3,(THIS_FILE, "End of Wav File, media_port: %d", media_port));

    if (status == PJ_SUCCESS)
    {
        return -1;// Here it is important to return a value other than PJ_SUCCESS
                  //Check link below
    }

    return PJ_SUCCESS;
}

pjmedia_wav_player_set_eof_cb コールバック関数が PJ_SUCCESS 以外の値を返す必要がある理由は、pjmedia_wav_player_set_eof_cb のドキュメントにのように記載されているためです。

アプリケーションがコールバックでファイル ポートを破棄する場合は、ここで PJ_SUCCESS 以外を返す必要があることに注意してください。

于 2013-10-03T16:07:33.873 に答える