logo头像

勤求古训,博采众方

使用Linphone做P2P语音通话

本文于 512 天之前发表,文中内容可能已经过时。

SIP客户端介绍

  • 关于VoIP中有很多的SIP客户端,其中Linphone、PJSIP、Telephone、BareSIP等。
  • LinPhone是跨平台的,包含了Windows、Linux、Mac、Android、iOS,支持视频,它是开源的。
  • PJSIP是个协议栈,也有个客户端,它是开源的,支持语音和视频。支持STUN、ICE、WebRTC AEC等,很多客户端都是用它作协议栈。它的实现是为了能在嵌入式设备上高效实现SIP/VoIP。
  • Telephone是一款开源免费的电话,界面非常简洁,仅支持Mac,在Apple Store里可以直接下载,底层用PJSIP。不支持视频。
  • Baresip是一个协议栈,不过,它带了一个完整的命令行SIP客户端,也很好用,它是开源的,跨平台的,支持语音和视频。

Linphone客户端配置

配置默认端口5060

  • 设置网络-端口关闭随机-默认5060

  • 保证呼叫的设备在同一个局域网同网段内,然后通过Linphone的呼叫键盘输入内容,一方通过sip:xxx@ip的形式呼叫一方设备,其中xxx的话自定义,比如:1002,ip的话是被呼叫设备的对应地址,比如:192.168.30.122。

  • 如果是自己的应用代码设置如下:

    1
    2
    3
    4
    5
    val transports = core.transports
    transports.udpPort = 5060
    transports.tcpPort = 5060
    transports.tlsPort = -1
    core.transports = transports

image-20231123101811616

Linphone常见问题

电话呼叫停止铃声

  • 配置core.ringDuringIncomingEarlyMedia = false
  • 然后呼入状态里调用core.stopRinging()

背景音降噪

  • 在assets的linphonerc_factory配置文件中增加,linphonerc_factory中的配置linphone每次启动都会应用,如果是linphonerc_default配置文件只会应用一次,下次启动不会重新应用
    1
    2
    3
    4
    [sound]
    noisegate=1 #这个表示开启降噪音,不开会又背景音
    ng_thres=0.12 #这个表示声音这个阈值以上都可以通过,用于判断哪些是噪音
    ng_floorgain=0.12 #这个表示低于阈值的声音进行增益,用于补偿声音太小被吃掉

硬件回声消除器不工作,强制使用软件回声消除器

  • 官方文档说明
    1
    2
    3
    4
    The hardware echo canceller on Android often only works if the AudioManager's mode is set to IN_COMMUNICATIONS.
    Any linphone-sdk newer than 5.0 will do that automatically, but make sure you don't modify it's value in your app.

    If the device declares having a hardware echo canceller but it doesn't work, you can use the following Kotlin code to tell our SDK to use the software one instead:
1
2
3
4
5
core.mediastreamerFactory.setDeviceInfo(android.os.Build.MANUFACTURER, android.os.Build.MODEL, android.os.Build.DEVICE, org.linphone.mediastream.Factory.DEVICE_HAS_BUILTIN_AEC_CRAPPY, <calibrated value>, 0)
core.reloadSoundDevices()

To get the correct <calibrated value>, use the echo canceller calibration option in linphone-android's audio settings.
Do it a few times and keep the lowest value.

回声消除优化

  • linphone会识别当前设备是否支持硬件回声消除器,如果不支持的话才会走软件回声消除器,软件回声消除器有三种算法可以选择,MSSpeexAEC,MSWebrtcAECM,MSWebrtcAEC,官方推荐使用第三种算法,音质更好,但会占用更多CPU另外算法的延迟值很重要是,是麦克风和扬声器的距离等因素有关,linphone提供了对应的api可以测试,另外算法的区间是有限的,默认是80的区间中搜索,比如延迟值为200ms,那么算法的工作区间是200ms-280ms之间。

通话无声音

  • 之前老的版本不需要,5.0 SDk开始需要增加依赖配置
    1
    2
    3
    dependencies {
    implementation 'androidx.media:media:1.2.0'
    }

单独拉流播放并通话,通话会暂停

  • 在assets的linphonerc_factory配置文件中增加,linphonerc_factory中的配置linphone每次启动都会应用,如果是linphonerc_default配置文件只会应用一次,下次启动不会重新应用
    1
    2
    [audio]
    android_pause_calls_when_audio_focus_lost=0

参考资料

Linphone的p2p设置官方说明
Linphone Android
Audio devices
Audio tuning
我用过的那些SIP客户端