Freeswitch-Python3开发

一、Freeswitch如何使用mod_python3

官网地址:https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Modules/mod_python_1048940/#eol

1.1 Freeswitch和python

请注意,mod_python 基于 python2,并将于 2020 年 1 月 1 日停止使用。请使用 mod_python3。

所以我这里就是使用的python3给大家介绍

1.2 Freeswitch版本选择

Freeswitch从1.10.7才开始对python3的支持,所以,你的Freeswitch必须不低于Freeswitch1.10.7。

1.3 Freeswitch编译mod_python3

1.3.1 debian安装python3

pip install -yq python3-dev python3-pip

在这里插入图片描述
说明你安装好了

1.3.2 Freeswitch编译mod_python3

方法一:直接从源开始编译
如果你要从头全部重新编译一下,你可以到源码的freeswitch1_10_7/build/modules.conf.in下面取消这个注释,然后编译
在这里插入图片描述
然后就是正常的编译Freeswitch。如果你还不会编译Freeswitch,请参考
Freeswitch编译安装指南:http://t.csdnimg.cn/tuSVJ

方法二:只编译mod_python3这个模块
首先需要再freeswitch1_10_7源码目录下执行

 ./configure --with-python3=/usr/bin/python3.9

接着在freeswitch1_10_7/src/mod/languages/mod_python3 目录下,执行:

make
make install

或者在源码目录下执行:

make mod_python3-install

可能是我的版本是freeswitch1_10_7还是其他的什么原因,在源码目录下直接执行make mod_python3-install没有成功,我也没有深究。有实验的大佬可以告诉我原因。我就在 freeswitch1_10_7/src/mod/languages/mod_python3 下执行了

编译后,会在/usr/lib/python3/dist-packages下产生freeswitch.py
在这里插入图片描述

有的时候,我们可以直接把freeswitch.py放在对应安装的python3库下面,给你们拷贝了一份freeswitch.py

链接: https://pan.baidu.com/s/127ok_jI2UnIvFqSBGad6xA?pwd=5n45 提取码: 5n45 复制这段内容后打开百度网盘手机App,操作更方便哦

也会在编译后的 /usr/local/freeswitch/mod/产生对应的so和la
在这里插入图片描述

1.3.3 加载

方法一:
在fs_cli的控制台执行:load mod_python3
方法二:
在/usr/local/freeswitch/conf/autoload_configs下,每次启动FS自动加载mod_python3
在这里插入图片描述

在这里插入图片描述
重启FS就可以了

二、如何编写脚本

2.1 函数的基本框架

  • handler 启动函数
  • hangup_hook 处理挂机或转移事件的钩子函数,需通过session.setHangupHook事先设定。
  • input_callback 处理输入事件(如DTMF按键)的回调函数,需通过session.setInputCallback事先设定。
  • fsapi 处理来自fs_cli、拨号计划HTTP请求等的API调用
  • runtime 在独立线程中运行指定函数,通常由fs_cli的pyrun命令触发。
  • xml_fetch 绑定到FreeSWITCH的XML查找功能,用于动态生成或修改XML配置。
# 导入FreeSWITCH的Python模块以实现与FreeSWITCH服务器的交互
import freeswitch

"""
FreeSWITCH的mod_python使用示例。此模块使用mod_python默认查找的名称,
但大多数这些名称可以通过在从FreeSWITCH调用模块时使用<modname>::<function>来覆盖。
"""

def handler(session, args):
    """
    'handler'是应用程序的默认函数名。它可以被<modname>::<function>覆盖。
    `session`是会话对象,用于控制通话过程。
    `args`是一个字符串,包含了模块名之后的所有传入参数。
    
    功能:接听电话呼叫,记录日志,设置挂机钩子,设置输入回调,并播放音乐。
    """
    freeswitch.consoleLog('info', 'Answering call from Python.\n')  # 记录接听电话的日志信息
    freeswitch.consoleLog('info', 'Arguments: %s\n' % args)         # 打印传入的参数
    
    session.answer()                                                  # 接听电话
    session.setHangupHook(hangup_hook)                                # 设置挂机时的回调函数
    session.setInputCallback(input_callback)                           # 设置输入(如DTMF)的回调函数
    session.execute("playback", session.getVariable("hold_music"))     # 播放背景音乐,音乐来源为变量hold_music的值


def hangup_hook(session, what, args=''):
    """
    处理挂机或转移事件的钩子函数,需通过session.setHangupHook事先设定。
    `session`: 会话对象。
    `what`: 字符串,表示触发事件的类型,如"hangup"(挂断)或"transfer"(转移)。
    `args`: 可选参数,若在设置回调时提供了额外参数,则此处会有值。
    """
    freeswitch.consoleLog("info", "hangup hook for '%s'\n" % what)  # 记录挂机或转移的钩子被触发的日志信息


def input_callback(session, what, obj, args=''):
    """
    处理输入事件(如DTMF按键)的回调函数,需通过session.setInputCallback事先设定。
    `session`: 会话对象。
    `what`: 字符串,表示事件类型,如"dtmf"(双音多频按键)或"event"(其他事件)。
    `obj`: 对象,根据what的不同,可能是DTMF对象或事件对象。
    `args`: 可选参数,同hangup_hook。
    
    功能:根据输入类型记录日志,并根据情况暂停输入处理。
    """
    if what == "dtmf":                          # 判断是否为DTMF输入
        freeswitch.consoleLog("info", what + " " + obj.digit + "\n")  # 记录按下的DTMF键
    else:
        freeswitch.consoleLog("info", what + " " + obj.serialize() + "\n")  # 记录其他类型的事件
    return "pause"  # 返回"pause"以暂停输入处理,等待进一步指令


def fsapi(session, stream, env, args):
    """
    处理来自fs_cli、拨号计划HTTP请求等的API调用。
    `session`: 当从拨号计划调用时为会话对象,否则为"na"。
    `stream`: 输出流对象,用于向API调用方返回数据。
    `env`: 环境事件对象,包含调用时的相关环境信息。
    `args`: 调用该模块时传入的所有参数组成的字符串。
    
    功能:根据是否有参数,记录不同日志,并返回环境事件的序列化数据。
    """
    if args:
        stream.write("fsapi called with no arguments.\n")  # 若有参数,提示无参数调用(这里可能是注释错误,应为有参数)
    else:
        stream.write("fsapi called with these arguments: %s\n" % args)  # 记录传入的参数
    stream.write(env.serialize())  # 将环境事件对象序列化后返回给调用者


def runtime(args):
    """
    在独立线程中运行指定函数,通常由fs_cli的`pyrun`命令触发。
    `args`: 从命令行传递给此函数的参数字符串。
    
    功能:简单打印传入的参数。
    """
    print(args + "\n")  # 打印参数并换行


def xml_fetch(params):
    """
    绑定到FreeSWITCH的XML查找功能,用于动态生成或修改XML配置。
    `params`: 包含查找请求详情的事件对象。
    
    功能:返回一个示例XML配置,定义了一个简单的拨号计划上下文,用于接听电话并播放音乐。
    """
    xml = '''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <document type="freeswitch/xml">
        <section name="dialplan" description="RE Dial Plan For FreeSWITCH">
            <context name="default">
                <extension name="generated">
                    <condition>
                        <action application="answer"/>
                        <action application="playback" data="${hold_music}"/>
                    </condition>
                </extension>
            </context>
        </section>
    </document>'''
    return xml  # 返回生成的XML配置

2.2 基本使用

2.2.1 触发条件

在这里插入图片描述

2.2.2 默认脚本位置

默认的脚本位置一般在/usr/local/freeswitch/scripts

  1.   如果你有很多脚本,建议在这个文件夹下面在建文件夹;比如说你建立了一个脚本路径为/usr/local/freeswitch/scripts/tests/t1.py
    你的调用方式是tests.t1
  2. 如果tests.t1里面引用了自己定义的包,这个包也在同目录下,是会报找不到这个包的
    解决方式:找到你安装python的位置,然后找dist-packages或者site-packages下面,比如我通过pip install -yq python3-dev python3-pip安装的python3.9,所以我的操作如下

方法一:添加软连接

cd /usr/lib/python3/dist-packages
ln -s /usr/local/freeswitch/scripts/tests .

然后就会找到这个方法了,
方法二:硬核操作,直接添加复制
把/usr/local/freeswitch/scripts/tests/下面引用的包放在/usr/lib/python3/dist-packages下面,不过这样会显得特别臃肿,不建议

方法三:以下内容添加到系统环境启动中

export PYTHONPATH=$PYTHONPATH:/usr/local/freeswitch/scripts/tests

不要忘记,tests 包目录将需要一个 init.py。

在启动 freeswitch 的 shell 中,需要定义这个环境变量。

export 设置的环境变量只在当前 Shell 会话中有效。一旦你退出当前 Shell(例如关闭终端窗口),这些环境变量的设置就会丢失。因此,相对于写入诸如 /.bashrc、/.profile 或 /etc/profile 等配置文件从而实现持久化环境变量设置的方式,直接使用 export 命令所做的设置确实是临时的

2.2.3 回调参数如何使用参数

2.2.3.1 handler回调函数参数怎么用

前面已经介绍了如何handler是拨号计划的回调函数,那么回调函数 handler(session, args)里面有个args参数,这个其实就是额外参数,这里args就是一个字符串。

在这里插入图片描述
只要在里面用空格拼接就可以了,然后使用则会功能则表达式处理下就可以用了

def handler(session, args):
    """
    'handler'是应用程序的默认函数名。它可以被<modname>::<function>覆盖。
    `session`是会话对象,用于控制通话过程。
    `args`是一个字符串,包含了模块名之后的所有传入参数。
    """
    freeswitch.consoleLog('info', 'Answering call from Python.\n')  # 记录接听电话的日志信息
    freeswitch.consoleLog('info', 'Arguments: %s\n' % args)  # 打印传入的参数
    pairs = re.findall(r'(\w+)=(\S+)', args)

    # 将匹配到的键值对转换为字典
    dialplan_args = dict(pairs)
    # 获取参数
    ws= dialplan_args.get('ws', None)
    model=dialplan_args.get('model', "qwen")
2.2.3.2 set事件回调函数参数怎么用

我们通常在handler里面设置一些事件

  • setHangupHook 挂断事件
  • setInputCallback 输入事件

在这里插入图片描述
在这里插入图片描述
这里的回调函数一定要有这些参数,但是args默认是字符串,我们可以把=''删掉。我们来穿一个对象或者多个对象,这里我们就可以用利用字典的方式进行传,然后获取

    # 创建主线程 QueueManager对象
    main_qm = QueueManager()
    # 客户说话类
    speaker = SpeakerStatus()
    input_callback_args = {'main_qm': main_qm, 'speaker': speaker}
    session.setInputCallback(input_callback, input_callback_args)
    hangup_hook_args = {'speaker': speaker}
    session.setHangupHook(hangup_hook, hangup_hook_args)  # 设置挂机时的回调函数

在这里插入图片描述

三、致谢

写到这里,大家应该就入了门,后面的修行就要看自己了。欢迎讨论微信手机同号18956043585

给大家看一下我实现的效果吧,我的声音可能有点小

Freeswitch对接AI大模型

  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码浪人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值