文章目錄
- 一、Freeswitch如何使用mod_python3
- 1.1 Freeswitch和python
- 1.2 Freeswitch版本選擇
- 1.3 Freeswitch編譯mod_python3
- 1.3.1 debian安裝python3
- 1.3.2 Freeswitch編譯mod_python3
- 1.3.3 加載
- 二、如何編寫腳本
- 2.1 函數的基本框架
- 2.2 基本使用
- 2.2.1 觸發條件
- 2.2.2 默認腳本位置
- 2.2.3 回調參數如何使用參數
- 2.2.3.1 handler回調函數參數怎么用
- 2.2.3.2 set事件回調函數參數怎么用
- 三、致謝
一、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
- ??如果你有很多腳本,建議在這個文件夾下面在建文件夾;比如說你建立了一個腳本路徑為
/usr/local/freeswitch/scripts/tests/t1.py
你的調用方式是tests.t1
- 如果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