docker搭建freeswitch实现点对点视频,多人视频

欢迎来到我的博客,代码的世界里,每一行都是一个故事

🎏:你只管努力,剩下的交给时间

🏠 :小破站

docker搭建freeswitch实现点对点视频,多人视频

本来我信心满满,打算在 CentOS 7 上一步一步搭建 FreeSWITCH,实现点对点视频通话和多人房间视频。毕竟网上"教程"那么多嘛,看起来也不复杂。可是真动手才发现,不是缺依赖就是编译不过,不是模块装不上就是版本冲突,踩坑踩到心态爆炸。搜索出来的博客,十有八九都是"人云亦云"的复制粘贴,根本跑不通。最终我还是选择了 Docker:简单粗暴,至少能保证环境统一,不至于自己跟自己打架。内存多花点就多花点,反正 FreeSWITCH 本身也不算重。

我实现了什么?

  • 使用Docker部署FreeSWITCH服务

  • 配置SIP配置文件支持WebRTC

  • 配置SSL证书以支持WSS安全连接

  • 配置STUN/TURN服务器以支持NAT穿透

  • 实现SIP用户注册功能

  • 实现基本的SIP呼叫流程

  • 实现挂断通话功能

  • 实现加入会议功能

  • 支持多种会议URI格式(3000@default、3000-domain@profile等)

  • 实现会议保活机制(定期发送DTMF信号)

  • 实现视频网格布局

来个题外话

当以后大家出现本机搭建有问题的时候,并且很复杂的时候,可以无脑使用docker。(纯自己的看法,可能有问题,自己甄别),比如这次的freeswitch,各种博客+AI,但是在自己操作过程中真的各种报错,包括yum安装时候的版本问题,镜像源等等。遇到这种,就是万能公式,进入dockerhub查一下freeswitch。能看到下面的内容:

臣附议:当你什么都不懂的时候就随大流吧,铁子!找下载最多的。

再附议 :其实它里面已经封装好了你要的所有东西,你只需要一行命令,大不了10行就OK了,直接不需要管繁琐的版本等等。

**再再附议:**我一般不喜欢用最新版本,所以我选择了最新版的前一个版本(没什么问题)。

它是什么?

首先我想啰嗦几句,和大家说说这个玩意它是干home的?

FreeSWITCH 是一个开源的通信软件平台,设计用于创建语音、视频和文本通信应用。它是一个强大的软交换(softswitch)解决方案,可以处理各种通信协议,包括 SIP、WebRTC、H.323 等。FreeSWITCH 既可以作为一个独立的电话系统,也可以作为更大规模通信系统的组件。

docker部署

sh 复制代码
docker run --net=host --name freeswitch \
-e SOUND_RATES=8000:16000 \
-e SOUND_TYPES=music:en-us-callie \
-v /home/acowbo/freeswitch-sounds:/usr/share/freeswitch/sounds \
-v /etc/freeswitch/:/etc/freeswitch \
safarov/freeswitch:1.10.12

注意📢:这里可能会卡到,如果卡到的内容是这样的,你可以直接ctrl+c,然后重启容器即可,因为这个模块我们用不到,当然你也可以去除这个模块:

我来说明一下这个模块:

mod_signalwire 是 FreeSWITCH 中的一个用于接入 SignalWire 云通信平台的模块。

我们应该是用不到的,禁用方法有两种,一种直接配置文件查找后删除即可,另外一种容器已经启动,直接禁用。

第一种方式

  1. 执行vim /etc/freeswitch/autoload_configs/modules.conf.xml可以看到如下图所示:

**第二种方式:**执行docker exec -it freeswitch fs_cli后输入unload mod_signalwire

wss加密配置实现

这一步如果你使用的是certbot就可以直接按照我的来,反正原理就是把证书挂载即可!https://mp.weixin.qq.com/s/e3vd0ritP8Dkp7SgsNqt8Q

就下面的两个文件,至于/etc/freeswitch/certs,这个目录是不存在的需要先创建mkdir -p /etc/freeswitch/certs

sh 复制代码
cp /etc/letsencrypt/live/status.acowbo.fun/fullchain.pem /etc/freeswitch/certs/wss.pem
cp /etc/letsencrypt/live/status.acowbo.fun/privkey.pem /etc/freeswitch/certs/wss.key
chmod 644 /etc/freeswitch/certs/wss.pem
chmod 640 /etc/freeswitch/certs/wss.key
chown -R root:root /etc/freeswitch/certs

上面的都弄好之后就是修改配置文件了:

执行vim /etc/freeswitch/sip_profiles/internal.xml

然后找到wss模块,如下图。建议端口不要用它之前的,安全一点

会议配置(房间)

需要修改的文件为/etc/freeswitch/autoload_configs/conference.conf.xml,使用AI问问即可,当然我改的内容会贴出来:是在默认的profile下哈

xml 复制代码
<param name="domain" value="你的公网ip"/>
<param name="conference-flags" value="audio-always|video-bridge|rfc-4579|livearray-sync|minimize-video-encoding"/>
<param name="conference-flags" value="livearray-sync"/>
<!-- 添加基本视频支持 -->
<param name="video-mode" value="mux"/>
<param name="video-layout-name" value="group:grid"/>
<param name="video-canvas-size" value="1280x720"/>
<param name="video-canvas-bgcolor" value="#333333"/>
<param name="video-layout-bgcolor" value="#000000"/>
<param name="video-codec-bandwidth" value="2mb"/>
<param name="video-fps" value="30"/>
<param name="video-auto-floor-msec" value="1000"/>

<!-- 添加视频布局控制 -->
<param name="video-layout-width" value="1280"/>
<param name="video-layout-height" value="720"/>
<param name="video-mute-exit-canvas" value="false"/>
<param name="video-required-for-canvas" value="false"/>
<param name="max-members" value="16"/>

<!-- 配置DTMF布局控制 -->
<param name="video-layout-group" value="grid"/>
<param name="video-layout-name" value="3x3"/>
<param name="video-layout-conf-flags" value="auto-3d-position|video-floor-only"/>
<param name="enable-video-layout-overlay" value="true"/>
<param name="video-layout-callout-timeout" value="10"/>
<param name="video-canvas-count" value="1"/>

效果展示

常见问题解决

注册出错解决

这里有很多种情况,目前我遇到的是两种,具体如下:

domain识别到的是容器ip

直接说问题:/etc/freeswitch/vars.xml文件种的配置你没有进行修改,导致它默认读取的是容器的ip,可以使用vim,输入/来定位找到此内容:<X-PRE-PROCESS cmd="set" data="domain=$${local_ip_v4}"/>然后将$${local_ip_v4}改为你的公网ip即可。

验证方法:执行docker exec -it freeswitch fs_cli -x 'global_getvar domain_name',freeswitch是我的容器名称,换为你的即可!最后输出的结果需要是你的公网ip才行。

用户密码不正确

这个目录下的这些个文件,我统称为用户,他这里有一个默认密码,如果你没有修改,就直接去/etc/freeswitch/vars.xml里面找。

WSS访问问题

这里存在两个问题,一个是访问不到,一个是视频连接出错,也就是不能打视频

第一个问题排查如下:

  1. 你要确定你的wss的端口是可达的,这里你可以使用telnet来尝试
  2. 你要确定端口对应,别服务中的端口是10014,实际去绑定的时候是10012
  3. 千万别用nginx去做中转,如果做也是对应的wss,而非直接/处理
  4. 如果你排查下来发现还是不可访问,我说的不可访问是这个端口是通的,执行`lsof -i tcp:你的端口,也是可以看到有输出的,并且是执行freeswitch的。这个时候我建议你用他本来的端口,wss的是7443,ws的是5066。我的有一台服务器就是这样的,我用了10011,10014。服务也存在,也能连接上,就是不通,很奇怪。关键是用的freeswitch版本都一样。

第二个问题其实没什么排查的必要:因为是需要穿透的,也就是需要穿透nat。这个穿透的第三者作为一个桥梁,告诉他们两个对方的真实信息。具体搭建和使用可以看我的另一个文章:https://mp.weixin.qq.com/s/XxnaUMwP0dy8aVA6kHbGmA

SIP 设备(Tcp/Udp)不能视频

这里大致的情况就是打通了,管道中也存在,但是30s后就自动断开了。使用了抓流工具也看不出什么门道(在下比较菜),总结就是不通。哈哈哈~~,言归正传,大致是两种情况。如果想要自己抓包看一下,可以使用tcpdump -i any -nn -s 0 -w /tmp/fs_video_full.pcap "udp port 5060 or udp portrange 16384-32768 or tcp port 5060 or port 10014 or port 10011"

  1. 视频流和音频流不通,比如服务端发出响应,客户端没有回,或者说不知道怎么回。反之一样。

  2. udp端口没开,默认是16384-32768,记住了是udp,udp,udp。(大部分就是这个原因了)

    测试udp端口是否开用这个命令即可 *nc -vzu 你的服务器ip 16384*

常用命令

sh 复制代码
# 查看所有SIP profile的状态
docker exec -it freeswitch fs_cli -x "sofia status"

# 查看某个profile的详细信息(如internal或external)
docker exec -it freeswitch fs_cli -x "sofia status profile internal"

# 查看 internal profile 下的所有注册用户信息(已注册的终端列表)
docker exec -it freeswitch fs_cli -x "sofia status profile internal reg"

# 重新加载XML配置(包括用户、拨号计划等)
docker exec -it freeswitch fs_cli -x "reloadxml"

# 列出当前所有正在运行的会议室及相关信息
docker exec -it freeswitch fs_cli -x "conference list"

# 挂断指定UUID的通话
docker exec -it freeswitch fs_cli -x "uuid_kill <uuid>"

# 显示当前所有活动的通道(channels),包括呼叫详情
docker exec -it freeswitch fs_cli -x "show channels"

# 查看指定 UUID 的通道详细信息,UUID 是通话的唯一标识符
docker exec -it freeswitch fs_cli -x "uuid_dump 44e97f0b-bc3c-41d8-9929-936a890c3cb4"

# 使用 Lua 脚本 dissolve_conference.lua 解散会议室,参数是会议室ID和发起者IP(这里示例是会议室12345,IP 154.11.80.119)
docker exec -it freeswitch fs_cli -x "luarun dissolve_conference.lua 12345-154.11.80.119"

加餐

lua脚本实现解散会议

有时候会议中的人可能退不出来,比如sip设备。这时候就需要别人辅助去解散会议了。目前有两种方式,第一种是通过后端api来实现调用(未使用),第二种就是使用会议发起人来实现(看似未使用,实则使用了)。

下面我针对第二种来说明实现思路:

解散会议和加会议其实是一样的,仅仅就是在解散会议的时候走一个lua脚本,然后脚本里调用了API,这一步和使用后端API神似。

需要确定几件事:

  1. 是否使用lua,这里提供了很多,比如py。

  2. 如果使用lua,确定模块是否已经加载?执行一下命令docker exec -it freeswitch fs_cli -x "module_exists mod_lua",如果返回true,就证明加载了。当然还有一种方法就是看配置文件

  3. /etc/freeswitch/autoload_configs/lua.conf.xml修改如下参数<param name="script-directory" value="/etc/freeswitch/scripts/?.lua"/>,这个好像没什么卵用,最后执行我还是带了全路径。

上面的都搞好了,就直接搞吧!!在/etc/freeswitch/dialplan/default.xml加入如下内容

xml 复制代码
<!-- acowbo 解散会议-->
    <extension name="dynamic_end_conference_lua">
      <condition field="destination_number" expression="^\*66(\d+)$">
        <action application="set" data="conf_num=${regex(${destination_number}|^\\*66(\\d+)$|$1)}"/>
        <action application="log" data="DEBUG: destination_number123=${destination_number}, conf_num123=${conf_num}"/>
        <action application="set" data="conf_full=${conf_num}-${domain_name}"/>
        <action application="log" data="INFO: domain_name=${domain_name}, conf_full=${conf_full}"/>
        <action application="lua" data="/etc/freeswitch/scripts/dissolve_conference.lua ${conf_full}"/>
        <action application="hangup"/>
      </condition>
    </extension>

此时,如果你的会议是3000,比如此时你加入会议了,你再执行一次加入会议,前面加*66,也就是*663000

。大哥们这里别怼,这里的按钮你可以是解散会议,但是执行的方法还是加入会议的方法。这样就实现了!

注意📢:这里必须是lua,而非luarun,而在控制台必须是luarun,比如docker exec -it freeswitch fs_cli -x "luarun dissolve_conference.lua 12345-154.11.80.119"

相关推荐
叶总没有会8 小时前
Docker入门
运维·docker·容器
发现你走远了8 小时前
极简后端环境搭建:一行 Docker 命令部署四大核心数据库(避坑 PG 18+)
数据库·docker·容器
山楂树の9 小时前
H.265 (HEVC) 视频解码转逐帧图像 完整实现方案
学习·音视频·h.265
身如柳絮随风扬9 小时前
使用 Docker 部署 GitLab 并分配用户账号 —— 保姆级教程
docker·容器·gitlab
brucelee1869 小时前
Docker 运行 Android 模拟器
android·docker·容器
大强同学9 小时前
用Claude Code把一篇文章自动做成视频,全程不用碰剪辑软件
音视频
郭源潮19 小时前
从8k嘈杂到16k清晰,我是如何使用RNNoise+libresample构建音频降噪管道的?
c++·音视频·实时音视频
YWamy9 小时前
音视频SDK赋能智能硬件:实时RTC技术的应用难点与落地实践
音视频·实时音视频·智能硬件
科研前沿9 小时前
深耕数字孪生与视频孪生,打造行业标杆
音视频
Konwledging10 小时前
docker
docker