talk.lua 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. -- talk.lua
  2. local talk = {}
  3. dnsproxy = require("dnsproxy")
  4. dhcpsrv = require("dhcpsrv")
  5. httpplus = require("httpplus")
  6. local run_state = false
  7. local input_method = require "InputMethod"
  8. local input_key = false
  9. local g_dev_list = {}
  10. local airaudio = require "airaudio"
  11. extalk = require("extalk")
  12. local local_id
  13. -- 初始化fskv
  14. AIRTALK_TASK_NAME = "airtalk_task"
  15. USER_TASK_NAME = "user"
  16. SUCC = "success"
  17. local speech_topic = "867920075013921"
  18. local event = ""
  19. local talk_state = ""
  20. -- 新增通讯录相关变量
  21. local address_list_page = 1 -- 通讯录当前页码
  22. local address_list_max_page = 1 -- 通讯录最大页码
  23. local current_page = "main" -- 当前页面状态
  24. local contacts_per_page = 8 -- 每页显示的联系人数量
  25. local function contact_list(dev_list)
  26. g_dev_list = dev_list
  27. for i=1,#dev_list do
  28. log.info("联系人ID:",dev_list[i]["id"],"名称:",dev_list[i]["name"])
  29. end
  30. end
  31. local function state(event_table)
  32. if event_table.state == extalk.START then
  33. log.info("对讲开始,可以说话了")
  34. talk_state = "对讲开始,可以说话了"
  35. elseif event_table.state == extalk.STOP then
  36. log.info("对讲结束")
  37. talk_state = "对讲结束"
  38. elseif event_table.state == extalk.UNRESPONSIVE then
  39. log.info("对端未响应")
  40. talk_state = "对端未响应"
  41. elseif event_table.state == extalk.ONE_ON_ONE then
  42. for i=1,#g_dev_list do
  43. if g_dev_list[i]["id"] == event_table.id then
  44. log.info(g_dev_list[i]["name"],",来电话了")
  45. talk_state = g_dev_list[i]["name"]..",来电话了"
  46. break
  47. end
  48. end
  49. elseif event_table.state == extalk.BROADCAST then
  50. for i=1,#g_dev_list do
  51. if g_dev_list[i]["id"] == event_table.id then
  52. log.info(g_dev_list[i]["name"],"开始广播")
  53. talk_state = g_dev_list[i]["name"].."开始广播"
  54. break
  55. end
  56. end
  57. end
  58. end
  59. local extalk_configs = {
  60. key = PRODUCT_KEY, -- 项目key,一般来说需要和main 的PRODUCT_KEY保持一致
  61. heart_break_time = 120, -- 心跳间隔(单位秒)
  62. contact_list_cbfnc = contact_list, -- 联系人回调函数,回调信息含设备号和昵称
  63. state_cbfnc = state, --状态回调,分为对讲开始,对讲结束,未响应
  64. }
  65. local function init_talk()
  66. log.info("init_call")
  67. airaudio.init() -- 初始化音频
  68. extalk.setup(extalk_configs) -- airtalk 初始化
  69. end
  70. -- 绘制通讯录页面
  71. local function draw_address_list()
  72. lcd.clear(_G.bkcolor)
  73. -- 绘制返回按钮 (左上角)
  74. lcd.showImage(10, 10, "/luadb/back.jpg")
  75. -- 绘制标题 (居中)
  76. lcd.drawStr(120, 30, "通讯录")
  77. -- 计算当前页的联系人起始和结束索引
  78. local start_index = (address_list_page - 1) * contacts_per_page + 1
  79. local end_index = math.min(start_index + contacts_per_page - 1, #g_dev_list)
  80. -- 绘制联系人列表
  81. local y_pos = 78
  82. for i = start_index, end_index do
  83. local contact = g_dev_list[i]
  84. -- 绘制ID
  85. lcd.drawStr(10, y_pos, "ID: " .. (contact["id"] or ""))
  86. -- 绘制名称
  87. lcd.drawStr(10, y_pos + 15, "名称: " .. (contact["name"] or "未知"))
  88. -- 绘制分隔线
  89. lcd.drawLine(5, y_pos + 35-12, 315, y_pos + 35-12)
  90. y_pos = y_pos + 40 -- 每个联系人占40像素高度
  91. end
  92. -- 绘制翻页按钮 (底部居中)
  93. local page_btn_y = 412
  94. if address_list_page > 1 then
  95. lcd.drawStr(50, page_btn_y, "上一页")
  96. end
  97. if address_list_page < address_list_max_page then
  98. lcd.drawStr(220, page_btn_y, "下一页")
  99. end
  100. -- 绘制页码信息 (底部居中)
  101. lcd.drawStr(140, page_btn_y, address_list_page .. "/" .. address_list_max_page)
  102. -- 如果正在通话,绘制停止按钮 (底部居中)
  103. if g_state == SP_T_CONNECTED then
  104. lcd.fill(120, 435, 200, 465,0xF061) -- 绘制停止按钮边框
  105. lcd.drawStr(130, 462, "停止通话")
  106. end
  107. lcd.flush()
  108. end
  109. function talk.run()
  110. log.info("talk.run",airtalk.PROTOCOL_DEMO_MQTT_16K,mobile.imei())
  111. lcd.setFont(lcd.font_opposansm12_chinese)
  112. run_state = true
  113. local_id = mobile.imei()
  114. sys.taskInitEx(init_talk, USER_TASK_NAME)
  115. speech_topic = "867920075013921"
  116. log.info("get speech_topic",speech_topic)
  117. while run_state do
  118. sys.wait(100)
  119. if input_method.is_active() then
  120. input_method.periodic_refresh()
  121. else
  122. if current_page == "main" then
  123. lcd.clear(_G.bkcolor)
  124. if speech_topic then
  125. lcd.showImage(175, 300, "/luadb/datacall.jpg")
  126. end
  127. lcd.drawStr(0, 100, "方案介绍:airtalk.luatos.com")
  128. lcd.drawStr(0, 120, "平台端网址:airtalk.openluat.com/talk/")
  129. lcd.drawStr(0, 140, "所有要对讲的设备,要保持在线")
  130. lcd.drawStr(0, 160, talk_state)
  131. lcd.drawStr(0, 180, "事件:" .. event)
  132. lcd.drawStr(0, 200, "本机ID:" .. local_id)
  133. lcd.drawQrcode(185, 148, "https://airtalk.openluat.com/talk/", 82)
  134. lcd.drawStr(185, 242, "扫码进入网页端",0x0000)
  135. -- 显示输入法入口按钮
  136. lcd.showImage(32, 300, "/luadb/broadcast.jpg")
  137. lcd.showImage(104, 400, "/luadb/stop.jpg")
  138. lcd.showImage(0, 448, "/luadb/Lbottom.jpg")
  139. -- 显示通讯录按钮 (位置x10,y250)
  140. lcd.showImage(175, 250, "/luadb/addresslist.jpg")
  141. lcd.showImage(0,0,"/luadb/back.jpg")
  142. lcd.flush()
  143. elseif current_page == "address_list" then
  144. draw_address_list()
  145. end
  146. end
  147. if not run_state then
  148. return true
  149. end
  150. end
  151. end
  152. local function stop_talk()
  153. talk_state = "停止对讲"
  154. extalk.stop() -- 停止对讲
  155. end
  156. local function start_talk()
  157. if extalk.start(speech_topic) then
  158. talk_state = "发起一对一通话中...."
  159. end
  160. end
  161. local function start_broadcast()
  162. talk_state = "语音采集上传中,正在广播"
  163. extalk.start() -- 开始广播
  164. end
  165. -- 打开通讯录
  166. local function open_address_list()
  167. if g_dev_list == nil or #g_dev_list == 0 then
  168. talk_state = "联系人列表获取失败,检测key和群组是否建立"
  169. log.info("联系人列表获取失败,检测key和群组是否建立")
  170. return false
  171. else
  172. current_page = "address_list"
  173. address_list_page = 1
  174. end
  175. end
  176. -- 返回主页面
  177. local function back_to_main()
  178. current_page = "main"
  179. end
  180. -- 选择联系人
  181. local function select_contact(index)
  182. local contact_index = (address_list_page - 1) * contacts_per_page + index
  183. if contact_index <= #g_dev_list then
  184. local contact = g_dev_list[contact_index]
  185. if contact and contact["id"] then
  186. speech_topic = contact["id"]
  187. fskv.set("talk_number", speech_topic)
  188. start_talk()
  189. -- 对讲开始后返回到主页面
  190. back_to_main()
  191. end
  192. end
  193. end
  194. -- 处理通讯录页面的触摸事件
  195. local function handle_address_list_touch(x, y)
  196. -- 返回按钮区域 (左上角)
  197. if x > 10 and x < 50 and y > 10 and y < 50 then
  198. back_to_main()
  199. return
  200. end
  201. -- 上一页按钮区域 (底部左侧)
  202. if address_list_page > 1 and x > 40 and x < 90 and y > 390 and y < 420 then
  203. address_list_page = address_list_page - 1
  204. return
  205. end
  206. -- 下一页按钮区域 (底部右侧)
  207. if address_list_page < address_list_max_page and x > 210 and x < 260 and y > 390 and y < 420 then
  208. address_list_page = address_list_page + 1
  209. return
  210. end
  211. -- 停止通话按钮区域 (底部居中)
  212. if g_state == SP_T_CONNECTED and x > 120 and x < 200 and y > 435 and y < 465 then
  213. stop_talk()
  214. return
  215. end
  216. -- 联系人选择区域 (60-380像素高度)
  217. if y >= 60 and y <= 380 then
  218. local contact_index = math.floor((y - 60) / 40) + 1
  219. if contact_index >= 1 and contact_index <= contacts_per_page then
  220. select_contact(contact_index)
  221. end
  222. end
  223. end
  224. function talk.tp_handal(x, y, event)
  225. if input_key then
  226. input_method.process_touch(x, y)
  227. else
  228. if current_page == "main" then
  229. if x > 0 and x < 80 and y > 0 and y < 80 then
  230. run_state = false
  231. elseif x > 173 and x < 284 and y > 300 and y < 345 then
  232. sysplus.taskInitEx(start_talk, "start_talk")
  233. elseif x > 32 and x < 133 and y > 300 and y < 345 then
  234. sysplus.taskInitEx(start_broadcast, "start_broadcast")
  235. elseif x > 104 and x < 215 and y > 397 and y < 444 then
  236. sysplus.taskInitEx(stop_talk, "stop_talk")
  237. elseif x > 175 and x < 286 and y > 250 and y < 295 then -- 通讯录按钮
  238. sysplus.taskInitEx(open_address_list, "open_address_list")
  239. end
  240. elseif current_page == "address_list" then
  241. handle_address_list_touch(x, y)
  242. end
  243. end
  244. end
  245. return talk