linphone mediastream2 分析-双向录音机

本文详细介绍了基于linphone的轻量级voip客户端,如何利用mediastream2架构实现双向录音功能,包括初始化音频流、启动和结束录音的过程。
 

(转载请标明出处,请勿用于商业用途)

http://blog.youkuaiyun.com/linux_embedded/article/details/8957482

 

linphone是一个轻量级voip客户端,linphone的架构设计十分的清晰,其底层音视频引擎mediastream2是一个独立的模块,基于它可以很容易的实现各种音视频的应用没。本文中所说的linphone 双向录音功能就是基于mediastream2架构的。

linphone 整体架构

linphone拥有自己的用户接口和核心引擎(音频/视频引擎),允许在相同的函数基础上建立不同的用户接口。

  • 用户接口

GTK+用户接口

命令行接口(linphonec, linphonecsh)

iPhone用户接口(基于objective C)

基于Java实现的Andorid应用

  • liblinphone,核心引擎。提供了高度容易扩展的函数接口,它是一个功能强大的SIP VOIP SDK,我们可以基于该框架实现任意的语音/视频应用。liblinphone基于下列组件实现:

mediastream2,功能强大的音/视多媒体SDK,用于创建和处理音/视流

oRTP,简单的RTP处理库

eXosip,SIP UA 库,其基于libosip2实现

 

linphone和liblinphone都是使用C语言实现的,下面为linphone的整体结构。

 

 

mediastream2实现机制

mediastream2功能强大,体积小,特别适合嵌入式设备的音视频流的处理。mediastream2为一个独立的处理音视频流的库,它能够完成关于音视频流的捕获、接收、发送、编码、解码、翻译等功能,基于它可以实现各种音视频的应用。下面为mediastream2具体

特性:

  1. 可以捕获、重放多种基于各种音频架构(ALSA, AudioUnits, AudioQueue, WaveApi)的音频流。
  2. 接收、发送RTP数据包。
  3. 支持多种音视频编码方式:audio:speex, G711, GSM, iLBC, AMR, AMR-WB, G722, SILK, G729; video: H263, theora, MPEG4, H264 and VP8.
  4. 支持音频的wav格式文件的读取和保存。
  5. 捕获摄像头的YUV图片格式,并对其以优化。
  6. 立体声输出。
  7. 回声消除,基于speex回声消除机制(webrtc AEC机制)。
  8. 支持音频会议,支持音频参数均衡。
  9. 音量控制。
  10. 具有IEC NAT穿越动能。
  11. 自动比特率控制算法:基于RTCP反馈信息。

H264, ILBC, SILK, AMR, AMR-WB and G729是以插件的形式整合到mediastream2架构中去的。

 

设计:

mediastream2中每一个处理过程实体都被定义为一个MSFilter结构,每一个MSFiter有一个(若干个)输入和一个(若干个)输出,通过输入、输出将各个实体连接起来。下面为一个简单的例子:

MSRtpRecv --> MSSpeexDec --> MSFileRec
  1. MSRtpRecv:接收网络上的数据包、解包,并将它们输出到下一个Filter。
  2. MSSpeexDec:假设音频解码器为speex,它会decode音频数据包,并作为声卡播放filter或wav文件保存filter的输入。
  3. MSFileRec:将语音数据保存为wav格式的文件(输入确保为:Linear 16 pcm格式)

负责调度的对象为MSTicker,它一个独立的线程,其每10ms被唤醒一次,然后它会处理他所管理的媒体链的数据。可以有多个MSTicker同时运行吗,例如,处理音频的Ticker和处理视频的Ticker

,或者不同的处理器中会运行不同的Ticker。

利用mediastream2的Filter机制,我们可以很容易的实现我们需要的功能,我们也可以很容易的基于Filter机制扩展自己需要的功能。双向录音功能就是基于Tee和MSFileRec两个Filter实现的。

linphone双向录音功能实现方案

基于mediastream2的音频处理架构,利用Tee和MSFileRec嵌入到的音频处理流程中,实现linphone的双向录音功能。录音分为发送和接收两个处理流程。下面分别为两个处理流程:

  1. 发送过程录音:
     

   2. 接收过程录音:

代码实现

mediastream2录音功能处理流程如下:

按照上面的流程图,主要分为音频处理初始化、开始录音、结束录音几部分介绍一下具体的实现。

音频流初始化

mediasream2中音频流处理初始化都是在函数audio_stream_start_full完成的,我们需要把Tee、FileRec两个Filter加入到音频处理过程中,并对他们做一些必要的初始化工作,例如,设置wav保存时的sample rate等。下面是我们需要添加的处理:

修改数据结构struct _AudioStream,添加Recv_Tee、Snd_Tee、Recv_FileRec、Snd_FileRec

struct _AudioStream{
MSFilter *Recv_Tee;
	MSFilter *Snd_Tee;
	MSFilter *Recv_FileRec;
	MSFilter *Snd_FileRec;
};

创建、初始化Recv_Tee、Snd_Tee、Recv_FileRec、Snd_FileRec

//创建Filters
stream->Recv_Tee = ms_filter_new(MS_TEE_ID);
stream-Snd_Tee  = ms_fiter_new(MS_TEE_ID);
stream->Recv_FileRec = ms_filter_new(MS_FIlE_REC_ID);
stream->Snd_FileRec = ms_filter_new(MS_FILE_REC_ID);
//Set Filters 
ms_filter_call_method(stream->Recv_FileRec, MS_FILTER_SAMPLE_RATE, &sample_rate);//设置wav文件采样率
ms_filter_call_method(stream->Snd_FileRec, MS_FILETER_SAMPLE_RATE, &sample_rate);
 
//add Revc_Tee、FileRec to receive graph
ms_connection_help_link(&h, encoder , 0 ,0);
ms_connection_help_link(&h , stream->Recv_Tee , 0 , 1);
	ms_filter_link(stream->Recv_Tee , 0 , stream->Rec_FileRec , 0);
 
//add Snd_Tee、FileRec to send graph
ms_connection_help_link(&h , decoder , 0 , 0);
ms_connection_help_link(&h, stream->Snd_Tee , 0 , 1);
	ms_filter_link(stream->Snd_Tee , 0 , stream->FileRec , 0);
ms_conncetion)_help_link(&h , stream->sound_write ,0 ,-1);


 启动录音

一般在 linphone中,当一个会话建立成功,就会创建处理音频流Filter链,这时就会调用形如audio_stream_record()的函数录音,此函数有一个参数为wav文件的保存路径和文件名。

 

ms_filter_call_method_noarg(st->soundwrite,MS_FILE_REC_CLOSE); 
ms_filter_call_method(st->soundwrite,MS_FILE_REC_OPEN,(void*)filename);
ms_filter_call_method_noarg(st->soundwrite,MS_FILE_REC_START); 


本文创建了两个函数:audio_stream_recv_rcord()、audio_stream_snd_record()分别用来处理两个方向的录音。

结束录音

当通话结束时,linphone会自动结束录音,并释放Filters占用的资源。此项工作在audio_stream_stop中完成。

ms_filter_call_method_noarg(stream->Recv_FileRec , MS_FILE_REC_SOTP);
ms_filter_call_method_noarg(stream->Snd_FileRec , MS_FILE_REC_STOP);
ms_connection_help_unlink(&h , stream->Recv_Tee , 0 , 1);
ms_conncetion_help_unlink(&h , stream->Recv_FileRec , 0 ,0);
ms_connection_help_unlink(&h , stream->Snd_Tee , 0 ,1);
ms_filter_unlink(stream->Snd_Tee , 0 , stream_FileRec , 0);

 

如上就是linphone的双向录音功能实现的整个过程,该方法具有一定的通用性,在其他的一些VoIP或音频处理应用中我们同样可以利用该方案实现录音功能。

 


<think>好的,用户的问题是关于如何在Linphone Desktop 4.5.0-alpha版本中导入RTP地址。我需要先理解用户的具体需求。RTP通常用于实时音视频传输,用户可能希望将某个RTP流地址导入到Linphone中,以便接收或发送媒体流。 首先,我需要回忆一下Linphone的功能。Linphone支持SIP协议,但直接导入RTP地址可能需要使用命令行或者高级配置。因为RTP通常是SIP通话建立后自动处理的,直接操作RTP可能不在常规的GUI功能中。查看用户提供的引用内容,特别是引用[3]提到了CoreImpl.java中的inviteAddress方法,这属于Android SDK的部分,但用户询问的是Desktop版本,可能需要不同的方法。 接下来,考虑Linphone Desktop是否有命令行参数或API可以直接处理RTP流。通常,这类操作可能需要使用Linphone的终端命令或者配置文件。例如,使用linphonec命令行的版本,或者通过配置文件设置媒体流地址。 另外,用户提到的版本是4.5.0-alpha,属于较旧的版本,可能需要查阅该版本的文档或源代码。引用[1]提到了LinPhone-SDK的代码仓库,可能需要检查该版本的源代码是否存在相关功能。但用户的问题是关于Desktop应用,而不是SDK集成,可能需要不同的步骤。 可能的解决方案步骤包括:通过命令行启动Linphone并指定RTP地址,或者使用配置文件设置。例如,使用linphonec命令,启动后输入命令建立通话时指定RTP地址。例如,使用`call rtp://@IP:port`这样的命令,但需要确认Linphone是否支持这种URI格式。 另外,可能需要通过自定义SIP INVITE消息,在消息头中指定RTP地址。这需要了解SIP协议的结构,以及如何在Linphone中发送自定义的INVITE请求。引用[3]中的inviteAddress方法可能用于发起呼叫,但参数是Address对象,可能需要构造包含RTP地址的地址字符串。 此外,用户可能需要配置Linphone音频和视频设置,手动指定RTP端口或地址。在设置中找到网络或媒体配置部分,手动输入RTP流的IP和端口。但通常这些设置是用于接收流,而非主动导入外部RTP流。 还需要考虑是否需要使用第三方工具将RTP流导入到Linphone,比如通过GStreamer等多媒体框架中转。但这种方法可能超出Linphone本身的配置,需要更复杂的环境搭建。 总结可能的步骤:1. 使用命令行参数或终端命令直接呼叫RTP地址;2. 在配置文件中设置RTP参数;3. 通过自定义SIP消息包含RTP信息;4. 使用高级API或脚本控制Linphone的行为。需要进一步验证这些方法的可行性,并参考Linphone的文档或社区讨论。 最后,由于用户使用的是较旧的alpha版本,可能存在功能限制或不同的配置方式,建议用户升级到稳定版或查阅对应版本的文档。</think>在Linphone Desktop 4.5.0-alpha版本中导入RTP地址主要通过**命令行参数或API调用**实现,因为该功能未直接集成在图形界面中。以下是具体步骤: --- ### 方法一:通过命令行启动时指定RTP流 1. **启动Linphone时添加媒体参数** 使用`linphonec`命令行工具启动程序,并通过`--media`参数指定RTP地址格式: ```bash linphonec -C --media="rtp://目标IP:端口" ``` 例如,接收RTP流到本地端口6000: ```bash linphonec -C --media="rtp://0.0.0.0:6000" ``` 2. **建立呼叫后自动关联RTP** 在命令行界面中,输入以下命令发起呼叫(假设目标SIP地址为`sip:user@example.org`): ```bash call sip:user@example.org ``` Linphone会自动使用配置的RTP参数进行媒体传输[^3]。 --- ### 方法二:通过API动态设置(需开发适配) 若需在代码层面实现,可参考LinPhone-SDK的`Core`接口: 1. **配置媒体参数** 在初始化`Core`时设置RTP地址: ```cpp LinphoneCore *lc = linphone_core_new(NULL, NULL, NULL, NULL); linphone_core_set_media_rtp_port(lc, 6000); // 设置本地RTP端口 ``` 2. **发起呼叫时绑定地址** 使用`linphone_core_invite_address()`发起呼叫,并通过SDP协议协商RTP参数。 --- ### 注意事项 - **版本兼容性**:4.5.0-alpha版本可能存在稳定性问题,建议升级至稳定版(如5.x)[^1][^2]。 - **防火墙配置**:确保目标端口在防火墙中开放。 - **协议支持**:RTP需配合SIP或SDP协议使用,纯RTP流需额外工具解析。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值