freeswitch集成tts和asr
LUA脚本实现语音的对话并记录在数据库
-- 引入 LuaSQL MySQL 模块 local luasql = require "luasql.mysql" -- 数据库连接设置 DBHOST = '127.0.0.1' -- MySQL 服务器地址 DBNAME = 'freeswitch' -- 这里使用你实际的数据库名称 DBUSER = 'root' -- MySQL 数据库用户名 DBPASS = '0.123456' -- MySQL 数据库密码 DBPORT = 3306 -- MySQL 的默认端口 -- 创建 LuaSQL MySQL 环境 local env = assert(luasql.mysql()) -- 连接到 MySQL 数据库 local dbcon = assert(env:connect(DBNAME, DBUSER, DBPASS, DBHOST, DBPORT)) -- 设置数据库连接的字符集为 utf8mb4 dbcon:execute("SET NAMES 'utf8mb4'") local questions = { "请问您的姓名是什么?", "请问您的年龄是?", "请问您的职业是什么?", "您最喜欢的城市是哪个?", "最后一个问题,您对我们的服务满意吗?" } local currentQuestion = 1 function again(s) if(currentQuestion > 2)then s:speak("问题回答完毕,感谢您的参与,再见!") s:hangup() else s:speak(questions[currentQuestion]) s:execute("detect_speech", "unimrcp:aliyun-mrcpserver alimrcp hello") s:streamFile("silence_stream://-1") end end --[[ session:setInputCallback的回调函数 @param s session @param type 由FreeSWITCH传递的input-type,可能是dtmf,event等 @param obj 发生input的消息包,包括消息头和消息体 @param arg 自定义的参数 ]] function onInput(s, type, obj, arg) -- 终端触发了dtmf(按了按键) if (type == "dtmf") then s:speak("你按到了" .. obj.digit .. ",请重新回答问题!\n") again(s) -- return "break" end -- 发生终端输入事件 if (type == "event") then local event = obj:getHeader("Speech-Type") -- 触发了begin-speaking事件,也就是发现终端开始说话了 if (event == "begin-speaking") then return "" end -- 触发了detected-speech事件,也就是发现终端说话结束了 if (event == "detected-speech") then s:execute("detect_speech", "pause") local speech_output = obj:getBody() -- 取到事件的消息体,也就是xml类型的语音识别结果 if (speech_output) then results = getResults(speech_output) if (results.result ~= nil) then s:speak("您的回答是:" .. results.result .. "\n") -- 把识别结果再说给终端 -- 插入操作(拼接字符串) local question = questions[currentQuestion] local answer = results.result local insert_sql = string.format("INSERT INTO record (question, answer) VALUES ('%s', '%s')", question, answer) -- 执行插入操作 local res, serr = dbcon:execute(insert_sql) else s:speak("对不起,我没听清你说什么了") end currentQuestion = currentQuestion + 1 again(s) -- 继续下一轮游戏 end return "break" else s:speak("对不起,我没听见你说什么") return "break" end return "break" end return "break" end --[[ 把mrcp传来的xml识别结果解析成lua的table类型 @param asrXml mrcp的语音识别结果 ]] function getResults(asrXml) local xml2lua = require('xml2lua') local handler = require('xmlhandler.tree') local xmlHandler = handler:new() local xmlParser = xml2lua.parser(xmlHandler) xmlParser:parse(asrXml) xml2lua.printable(xmlHandler.root) --[[ <?xml version="1.0" encoding="utf-8"?><result> <interpretation grammar="session:hello" confidence="1"> <instance> <result>乘风破浪。</result> <beginTime>160</beginTime> <endTime>1660</endTime> <taskId>0a07801cb19c48ad9ebe75e001b00e07</taskId> <waveformUri>dc834b5c7039441f-1.wav</waveformUri> </instance> <input mode="speech">乘风破浪。</input> </interpretation> </result> ]] if (xmlHandler.root ~= nil) then local rec_result = xmlHandler.root.result.interpretation.instance return rec_result else return nil end end -- 脚本实际上从这里开始 session:execute("ring_ready", "1000") -- 播放一个回铃音 session:execute("playback", "tone_stream://%(1850,4150,475,425);loops=1") -- 设置录音文件名 local record_time = os.time() local record_dir = os.date("%Y%m%d", record_time) local record_filename = os.date("%Y%m%d%H%M%S", record_time).."-"..session:getVariable("caller_id_number").."-"..session:getVariable("destination_number")..".wav" session:execute("record_session", "$${recordings_dir}/"..record_dir.."/"..record_filename) -- 接电话 session:answer() -- 设置input回调和tts参数 session:setInputCallback('onInput', '') -- zhibei_emo可以换成阿里云的其他发音人 session:set_tts_params("unimrcp:aliyun-mrcpserver", "zhibei_emo") -- 播放欢迎语 session:speak("您好,接下来我们将进行五个问题的调查!") -- 播放第一个问题 session:speak(questions[currentQuestion]) -- 等待对端说话 session:execute("detect_speech", "unimrcp:aliyun-mrcpserver alimrcp hello") -- 用无限长静音来使保持会话 session:streamFile("silence_stream://-1");
本文作者:IxXi
本文链接:https://www.cnblogs.com/IxXi1120/p/18617795
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步