freeswitch通過lua腳本實現多方會話功能,包括會議錄音自動外呼等

freeswitch 會議模塊

freeswitch 自帶有多方會議功能,在安裝目錄下的conf/autoload_configs/modules.conf.xml中,開啓會議功能,通常默認是啓用的,默認的 dialplan 配置下,註冊分機撥3000即可進入默認配置的會議功能。這裏的 3000 指的是會議號碼,多個分機都撥這個號碼即可進入同一個會議。

會議模塊相關配置

會議模塊同樣也有對應的全局配置,例如配置特定類型的會議的按鍵規則和其他規則等。這些都可以在配置文件conf/autoload_configs/conference.conf.xml中實現。

下面將對按鍵規則和定製會議功能做詳細介紹。
首先是按鍵規則,這裏配置的按鍵規則適用於 default 類型的所有會議。在conference.conf.xml中的<caller-controls>中。其中action表示按鍵後的功能,digits表示按鍵。action有多種,詳見官方文檔,例如mute爲靜音等。

  <caller-controls>
    <group name="default">
      <control action="mute" digits="0"/>
      <control action="deaf mute" digits="*"/>
      <control action="energy up" digits="9"/>
      <control action="energy equ" digits="8"/>
      <control action="energy dn" digits="7"/>
      <control action="vol talk up" digits="3"/>
      <control action="vol talk zero" digits="2"/>
      <control action="vol talk dn" digits="1"/>
      <control action="vol listen up" digits="6"/>
      <control action="vol listen zero" digits="5"/>
      <control action="vol listen dn" digits="4"/>
      <control action="hangup" digits="#"/>
    </group>
  </caller-controls>

其次是會議相關的其他配置,這裏依舊以 default 類型的會議爲例,同樣的你可以配置其他類型的會議的定製功能,只需要在使用會議時指定是什麼類型的會議即可。這些配置都在<profiles>標籤下。

以 default 類型的會議爲例,詳細參數介紹和配置內容參見官方文檔

<profile name="default">
    <param name="domain" value="$${domain}"/>
    <!-- Sample Rate-->
    <param name="rate" value="8000"/>
    <!-- Number of milliseconds per frame -->
    <param name="interval" value="20"/>
    <!-- Energy level required for audio to be sent to the other users -->
    <param name="energy-level" value="300"/>
    <!-- 會議中2人及以上時開始錄音 -->
    <param name="min-required-recording-participants" value="2"/>
    <!-- 錄音文件地址 -->
    <param name="auto-record" value="$${base_dir}/recordings/${strftime(%Y-%m-%d-%H-%M-%S)}_${conference_name}.wav"/>
    <!-- File to play to acknowledge muted -->
    <param name="muted-sound" value="conference/conf-muted.wav"/>
    <!-- File to play to acknowledge unmuted -->
    <param name="unmuted-sound" value="conference/conf-unmuted.wav"/>
    <!-- File to play if you are alone in the conference -->
    <param name="alone-sound" value="conference/conf-alone.wav"/>
    <!-- File to play endlessly (nobody will ever be able to talk) -->
    <!--<param name="perpetual-sound" value="perpetual.wav"/>-->
    <!-- File to play when you're alone (music on hold)-->
    <param name="moh-sound" value="$${hold_music}"/>
    <!-- File to play when you join the conference -->
    <param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>
    <!-- File to play when you leave the conference -->
    <param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>
    <!-- File to play when you are ejected from the conference -->
    <param name="kicked-sound" value="conference/conf-kicked.wav"/>
    <!-- File to play when the conference is locked -->
    <param name="locked-sound" value="conference/conf-locked.wav"/>
    <!-- File to play when the conference is locked during the call-->
    <param name="is-locked-sound" value="conference/conf-is-locked.wav"/>
</profile>

dialplan配置

dialplanfreeswitch作爲呼叫系統的一箇中樞,所有會話的方向都由它決定,它的配置文件是在 freeswitch 安裝目錄下的 conf/dialplan/default.xml 中,default.xml 是默認的 dialplan 配置,具體使用哪個 dialplan 可以在 conf/sip_profile 下的配置文件中配置。我們這裏以 default.xml 爲例。

每一通會話都有主叫和被叫號碼,在 dialplan 配置中,通過 xml 配置規則,會話通過正則表達式的匹配來決定使用那個配置規則,從而得到會話的下一步走向。

例如,我們前面配置了會議室,那麼可以在默認的 dialplan 配置中配置一個簡單的會議室,號碼爲3000 的會議室,freeswitch 內部分機註冊後可以撥打3000 進入會議室,具體限制和參數配置以前面會議室配置爲主。

dialplan 配置,extension 標籤外圍由 include 標籤和 context 標籤包裹,這裏不展示。具體參考 freeswitch 安裝後默認的 dialplan 配置。

<extension name="nb_conferences">
  <condition field="destination_number" expression="^(3000)$">
    <action application="answer"/>
    <action application="conference" data="$1-${domain_name}@default"/>
  </condition>
</extension>

配置說明:
首先我們是要在dialplan中配置一個撥號計劃,即 extension, 每個extension下可以有多個condition,即匹配規則。這裏只有一個匹配規則,多個的情況下可以進行按順序多次匹配。例子中我們是拿會話的被叫號碼來做匹配(被叫號碼就是輸入的號碼,自身的號碼是主叫),destination_number 表示被叫號碼。匹配成功後,進入內部執行 action,首先是給予應答,然後創建會議室。其中 $1 的值是 3000domain_name的值在 vars.xml 文件中,默認爲本機 ip

至此,我們可以使用分機撥打 3000進入會議室了,任何分機都可以通過撥打這個號碼進入 3000 這個會議室。

實現會議室自動外呼

通常在實際情況中更多的是由一個人創建會議室並且呼叫其他成員加入會議。因此我們需要會議室能夠自己去呼叫需要呼叫的號碼。

這同樣是可以在dialplan 中配置的,如下:

<extension name="MY_Extension">  
  <condition field="destination_number" expression="^95126_(\d{7,15})_(\d{7,15})$">      
    <action application="answer"/>  
    <!-- <action application="set" data="ringback=${us-ring}"/> -->  
    
    <action application="set" data="conference_auto_outcall_caller_id_name=${caller_id_name}"/>  
    <action application="set" data="conference_auto_outcall_caller_id_number=${caller_id_number}"/>  
    <action application="set" data="conference_auto_outcall_timeout=60"/>  
    <action application="set" data="conference_auto_outcall_flags=none"/>  
    <action application="set" data="conference_auto_outcall_profile=default"/>  
    
    <action application="conference_set_auto_outcall" data="user/$1"/>  
    <action application="conference_set_auto_outcall" data="user/$2"/>  
  
    <action application="conference" data="ehby-$1-$2@default+flags{endconf|moderator}"/>  
  </condition>  
</extension>

配置說明:

  1. conference_auto_outcall_caller_id_nameconference_auto_outcall_caller_id_number表示會議室在外呼時的外顯號碼。
  2. conference_set_auto_outcall是會議室中發起外呼的應用,通過配置 data 值可以自動發起外呼。這裏的號碼源自主叫所撥的好號碼中,例如主叫撥打95126_1234567_2345678這個號碼進入會議室,同時會議室會呼叫12345672345678這兩個號碼。
  3. 在配置會議室時,這裏也用到了 default 默認配置。並且通過 flag 配置了兩個新的參數,其中 endconf 表示主持人掛機則停止會議。moderator則標識了主持人,這裏表示將主叫作爲主持人。

這樣我們就可以通過輸入呼叫的號碼來形成會議室並且自動呼叫需要加入會議室的其他成員,但是這裏的缺點就是要手動輸入號碼,並且輸入的號碼會很長。

通過 lua 腳本實現從數據庫獲取被叫形成會議

要使用 lua 腳本,則需要在 module.conf.xml 中打開對於 lua 腳本的支持。其次數據庫使用MySQL,但是 lua 腳本要連接數據庫的話,需要安裝 ODBC 來連接。

通過下面的操作來安裝和配置 ODBC

yum install unixODBC-devel mysql-connector-odbc

/etc/odbc.ini

[freeswitch]
DRIVER   = MySQL
SERVER   = 127.0.0.1
PORT     = 3306
DATABASE = freeswitch
USER     = root
PASSWORD = 123456
OPTION   = 3

測試連接,執行:isql freeswitch -v

測試連接成功後,就可以來編寫 lua 腳本實現功能了,首先是腳本存放的位置,在 freeswitch 安裝目錄下的 script 文件夾下,而調用 lua 腳本的操作則配置在 dialplan 中。

假設我們要寫的腳本名稱叫做 meeting.lua,則在 dialplan 中配置如下:

<extension name="nb_conferences">
  <condition field="destination_number" expression="^(3000)$">
    <action application="lua" data="meeting.lua"/>
  </condition>
</extension>

這樣一來,凡是呼叫 3000 號碼的,都會執行該腳本。

其次是編寫 lua 腳本,腳本如下:

local caller_id_number = session:getVariable("caller_id_number");
destination_number = session:getVariable("destination_number");
--自動呼叫被叫時的外顯號碼
display_number = "";

freeswitch.consoleLog("NOTICE", "形成會議室caller_id_number = " .. caller_id_number .. ",destination_number = ".. destination_number .."\n");

local dbh = freeswitch.Dbh("freeswitch", "root", "123456");
freeswitch.consoleLog("NOTICE","start connect mysql...\r\n");

local sql = "select count(*) as count, phone1 as firstcallee,phone2 as secondcallee from tb_number where phone = "..caller_id_number;


if(dbh:connected())
then
        freeswitch.consoleLog("INFO","connect success!!!\r\n");
        dbh:query(sql, function(row)
                freeswitch.consoleLog("NOTICE","行數:" .. row.count .. ",會話被叫1:" .. row.firstcallee ..",會話被叫2:"..row.secondcallee.. "\r\n");
                if(row.count == “0”)
                then
                        session:hangup();
                else
                        session:execute("set","conference_auto_outcall_caller_id_name=${"..display_number.."}");
                        session:execute("set","conference_auto_outcall_caller_id_number=${"..display_number.."}");
                        session:execute("set","conference_auto_outcall_timeout=60");
                        session:execute("set","conference_auto_outcall_flags=none");
                        session:execute("set","conference_auto_outcall_profile=default");
                            
                        session:execute("conference_set_auto_outcall" data="user/"..row.firstcallee.."@127.0.0.1");
                        session:execute("conference_set_auto_outcall" data="user/"..row.secondcallee.."@127.0.0.1");
                        session:execute("conference", "ehby-${caller_id_name}-${destination_number}@default+flags{endconf|moderator}");
                end
        end);
        dbh:release();
else
        freeswitch.consoleLog("ERR","Unable to connect to mysql database\r\n");
        session:hangup();
end


dialplan 中調用 lua 腳本時,會自動傳入一個 session 表示當前這通會話,session 中包含了當前這通會話的所有信息,包括主被叫等,並且可以通過 session 來對這通會話做一些配置或者操作。

上面的例子中,表示的是通過主叫號碼從數據庫查詢得到兩個被叫號碼,並且形成會議自動呼叫被叫號碼的功能。

  1. 通過 session:getVariable() 方法,我們可以拿到這通會話的一些基礎信息,如主被叫等。具體有哪些值請參考官方文檔
  2. 在通過 freeswitch.Dbh(“freeswitch”, “root”, “123456”) 獲取數據庫連接的時候,參數分別爲數據庫名稱,賬號和密碼,需要注意的是,這裏的數據庫名稱並不是 MySQL 中的數據庫名稱,而是配置在 /etc/odbc.ini 中的數據庫名稱(方括號內的)
  3. 數據庫連接成功後,通過 query 方法執行 SQL 語句,並且通過回調函數對拿到的數據進行處理,其中 dbh:release(); 是釋放數據庫連接資源。
  4. 與 dialplan 中不同的是,這裏配置撥號計劃需要使用 session 的 execute 方法,參數第一個對應 application,第二個對應 data。
  5. 在發起外呼的時候,這裏所配置的是呼叫 freeswitch 內部分機的形式,即 user/+分機號+@IP 的形式,如果有對接外部網關,則應該這樣配:sofia/gateway/+網關名+/+號碼。
  6. lua 語法上,變量前加 local 爲本地變量,不加 local 爲全局變量。
發佈了74 篇原創文章 · 獲贊 31 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章