首页 > 代码库 > PJSUA2开发文档--第六章 媒体 Media类

PJSUA2开发文档--第六章 媒体 Media类

6. 媒体(Media)

媒体对象是能够产生媒体或接受媒体的对象。

Media的重要子类是AudioMedia,它代表音频媒体。PJSUA2支持多种类型的音频媒体对象:

  • 捕获设备的AudioMedia,用于从声音设备捕获音频。
  • 播放设备的AudioMedia,可以播放音频到声音设备。
  • 呼叫音频媒体,用于向远程人员发送和接收音频。
  • AudioMediaPlayer,播放WAV文件。
  • AudioMediaRecorder将音频录制到WAV文件。

将来可能会添加更多的媒体对象。

6.1 音频会议桥

会议桥提供了一种简单而又强大的概念来管理音频媒体之间的音频流。原理很简单,就是将音频源连接到音频目的地,桥接器会把音频流从源地址送到目的地,就这样。如果多个来源正在发送到同一个目的地,则来自源的音频被混合。如果一个信号源发送到多个目的地,则桥接器负责把来自源的音频复制到多个目的地。桥接器甚至会照顾不同时钟频率和时间的媒体。

在PJSUA2中,所有音频媒体对象都插入中央会议桥,方便操作。首先,插入式音频媒体将不会连接到任何东西,因此媒体不会流出/入任何对象。音频媒体源可以使用API?? AudioMedia.startTransmit()/ AudioMedia.stopTransmit())启动/停止到目的地的传输。

插入式的会议桥的音频媒体对象将被赋予识别桥对象的端口ID号。 应用程序可以使用API AudioMedia.getPortId()来检索端口ID。 通常,应用程序不需要担心会议桥及其端口ID(所有这些都将由Media类负责),除非应用程序要创建自己的定制音频媒体。

6.1.1 播放WAV文件?

要将WAV文件播放到声音设备,只需将WAV播放对象传输到声音设备的播放媒体:

AudioMediaPlayer player;
AudioMedia& play_med = Endpoint::instance().audDevManager().getPlaybackDevMedia();
try 
{ player.createPlayer(
"file.wav"); player.startTransmit(play_med); }
catch(Error& err)
{ }

默认情况下,WAV文件将以循环模式播放。要禁用循环,创建播放器时,需指定 PJMEDIA_FILE_NO_LOOP

player.createPlayer("file.wav", PJMEDIA_FILE_NO_LOOP);

没有循环,一旦回放到达WAV文件的末尾,就会播放静音。

完成播放后,只需停止播放即可停止播放:

try
{
    player.stopTransmit(play_med);
}
catch(Error& err) 
{
}

在停止播放时,将从上次播放位置恢复播放,恢复传输。使用player.setPos()到播放位置,设定到所需的位置。

6.1.2 录制为WAV文件

如果要将音频设备录制到WAV文件,只需执行以下操作:

AudioMediaRecorder recorder;
AudioMedia& cap_med = Endpoint::instance().audDevManager().getCaptureDevMedia();
try {
    recorder.createRecorder("file.wav");
    cap_med.startTransmit(recorder);
} catch(Error& err) {
}

媒体将从声音设备流向WAV录像文件。像前面一样,要停止或暂停录制,只需停止传输:

try {
   cap_med.stopTransmit(recorder);
} catch(Error& err) {
}

请注意,如上所述停止向WAV录像机的传输并不会关闭WAV文件,可通过将源连接到WAV录像机来重新开始录制。关闭之前无法播放录制的WAV文件。要关闭WAV录音机,只需删除它:

delete recorder;

 

6.1.3 本地音频环回

通过将捕获设备中的音频直接发送到播放设备(即本地环回),检查本地声音设备(捕获和播放设备)是否正常工作的有用测试。可以这样做:

cap_med.startTransmit(play_med);

 

6.1.4 循环音频

如果需要,可以将音频媒体对象的音频循环到自身(即,从对象接收的音频将被传输到自身)。只要对象具有双向介质,就可以从任何对象中回放音频。这意味着可以循环呼叫音频媒体,以便远程人员收到的音频将被传回给他/他。但是不能循环WAV播放器或录音机,因为这些对象只能播放或录制,而不能同时播放和录制。

6.1.5 正常呼叫

单个呼叫可以有多个媒体(例如音频和视频)。应用程序可以使用API?? Call.getMedia()检索音频媒体。然后,对于正常的呼叫,我们想要与远程人员建立双向音频,可以通过连接声音设备和呼叫音频媒体轻松完成,反之亦然:

CallInfo ci = call.getInfo();
AudioMedia *aud_med = NULL;

// Find out which media index is the audio
for (unsigned i=0; i<ci.media.size(); ++i) {
    if (ci.media[i].type == PJMEDIA_TYPE_AUDIO) {
        aud_med = (AudioMedia *)call.getMedia(i);
        break;
    }
}

if (aud_med) {
    // This will connect the sound device/mic to the call audio media
    cap_med.startTransmit(*aud_med);

    // And this will connect the call audio media to the sound device/speaker
    aud_med->startTransmit(play_med);
}

 

6.1.6 第二通电话

假设我们想同时与两个伙伴谈话。由于我们已经与一方进行双向媒体连接,我们只需要使用以下代码向对方添加双向连接:

AudioMedia *aud_med2 = (AudioMedia *)call2.getMedia(aud_idx);
if (aud_med2) {
    cap_med->startTransmit(*aud_med2);
    aud_med2->startTransmit(play_med);
}

现在我们可以同时与双方交谈,我们会听到任何一方的声音。但是在这个阶段,远程方不能说话或者听不到对方(即我们还没有在全会议模式下)。

6.1.7 电话会议

为了让双方互相交流,只需建立双向媒体:

aud_med->startTransmit(*aud_med2);
aud_med2->startTransmit(*aud_med);

现在三方(我们和这两个伙伴)都能够相互交流。

6.1.8 录制会议

在进行会议时,想要将会议记录到WAV文件是非常有意义的,我们需要做的就是将麦克风和两个通话连接到WAV录音机:

cap_med.startTransmit(recorder);
aud_med->startTransmit(recorder);
aud_med2->startTransmit(recorder);

6.2 音频设备管理

请参阅接下来的音频设备框架。

 

6.3 类参考

6.3.1 媒体框架

类?

class pj::Media

 

PJSUA2开发文档--第六章 媒体 Media类