AirUI 可視化方案仍在優化中,其輕量化、低成本、高可靠的特性在工業場景具備一定應用價值。針對用戶對通話錄音功能的需求,本文提供一套可直接落地的實現方案,支持自動接聽與自動錄音,適用于暫無需可視化 UI 的場景參考。
一、方案功能
基于LuatOS開發,適配多種型號核心板,可實現低成本通話留痕,適用于客服系統、會議記錄、遠程問診、話務工單追溯等場景。
主要功能特色如下:
自動接聽: 來電響鈴2聲后自動接聽,無需手動操作。
自動錄音: 通話接通后自動開始錄音,對方掛斷后自動停止。
SD卡存儲: 錄音文件以PCM格式保存到SD卡,支持自動掛載和空間檢測。
數據優化: 只保存上行數據,避免下行數據造成的回聲問題。
跨模組兼容: Air780EHM、Air780EGH、Air780EHV、Air8000系列核心板,均可通過外掛音頻配件板和SD卡存儲配件板實現。
簡而言之:一套方案搞定多個硬件型號,極大提升開發效率。
二、主要硬件準備
方案一:Air8000/Air780EHV開發板
開發板提供了豐富的音頻接口資源,可通過開發板上的音頻接口進行連接和測試。
如Air8000/Air780EHV開發板:

方案二:核心板+配件板
如果沒有Air780EHV和Air8000系列Turnkey開發板,那么可使用Air780EHM、Air780EGH、Air780EHV、Air8000系列核心板,通過外掛音頻配件板和存儲配件板來實現通話錄音功能。
AirAUDIO_1010音頻配件板: 負責音頻輸入輸出;
AirMICROSD_1010存儲配件板: 提供SD卡存儲功能。
連接小貼士: 如果搭配AirAUDIO_1010擴展板測試,需將擴展板中PA開關撥到OFF,讓軟件控制PA,避免pop音。
本文以Air780EGH為例:
接線方式參照下方圖表對應連接(注意不同型號核心板具體引腳號差異):


三、開源示例與教程
基于LuatOS開發的通話錄音示例已上傳Gitee開源倉庫,即便是新接觸LuatOS開發的朋友,也可以根據合宙資料中心提供配套實操教程快速上手。
核心功能模塊包括SD卡掛載、通話狀態機、錄音數據回調等,完整示例代碼詳見源碼倉庫最新文件。
--[[ 錄音功能特性: - 錄音文件保存為PCM格式:/sd/record_call.pcm - 只保存上行數據(包含本地聲音和網絡回聲) - 下行數據自動跳過,避免重復存儲 - 支持SD卡自動掛載和空間檢測 -- ====================== 錄音功能 ====================== -- 創建音頻數據緩沖區 local up1 = zbuff.create(BUFFER_SIZE,0) -- 上行數據保存區1 local up2 = zbuff.create(BUFFER_SIZE,0) -- 上行數據保存區2 local down1 = zbuff.create(BUFFER_SIZE,0) -- 下行數據保存區1 local down2 = zbuff.create(BUFFER_SIZE,0) -- 下行數據保存區2 -- 打開錄音文件 local function open_record_file() -- 先掛載SD卡 if not mount_sd_card() then log.error("錄音文件", "SD卡掛載失敗,無法進行錄音") return false end log.info("錄音文件", "SD卡掛載成功,錄音文件將保存到SD卡") -- 關閉已打開的文件 if record_file then record_file:close() record_file = nil end -- 刪除舊錄音文件 if io.exists(RECORD_FILE_PATH) then os.remove(RECORD_FILE_PATH) log.info("錄音文件", "刪除舊錄音文件:", RECORD_FILE_PATH) end -- 創建錄音文件 record_file = io.open(RECORD_FILE_PATH, "wb") if record_file then log.info("錄音文件", "創建錄音文件成功:", RECORD_FILE_PATH) record_start_time = mcu.ticks() is_recording_to_file = true return true else log.error("錄音文件", "創建錄音文件失敗:", RECORD_FILE_PATH) return false end end -- 關閉錄音文件 local function close_record_file() if record_file then record_file:close() record_file = nil local file_size = io.fileSize(RECORD_FILE_PATH) record_duration = (mcu.ticks() - record_start_time) / 1000 -- 轉換為秒 log.info("錄音文件", "錄音完成", "文件大小:", file_size, "字節", "錄音時長:", string.format("%.1f", record_duration), "秒", "路徑:", RECORD_FILE_PATH) is_recording_to_file = false record_start_time = 0 record_duration = 0 end end -- 寫入錄音數據到文件 local function write_record_data(buff, is_downlink) if not record_file or not is_recording_to_file then return false end -- 保存數據 if not is_downlink then local data_size = buff:used() if data_size > 0 then local start_time = mcu.ticks() -- 寫入數據到文件 record_file:write(buff:query()) local end_time = mcu.ticks() local write_time = end_time - start_time local write_speed = data_size / (write_time / 1000) -- 字節/秒 log.info("錄音寫入", "數據大小:", data_size, "字節,", "寫入耗時:", string.format("%.2f", write_time), "ms,", "寫入速度:", string.format("%.2f", write_speed / 1024), "KB/s") return true end else -- 下行數據不保存,只記錄日志 -- 寫入下行數據會導致文件內有回聲 local data_size = buff:used() if data_size > 0 then log.info("錄音寫入", "下行數據跳過", "數據大小:", data_size, "字節") end end return false end -- 音頻數據回調函數 local function recordCallback(is_dl, point) if is_dl then log.info("錄音", "下行數據,位于緩存", point+1, "緩存1數據量", down1:used(), "緩存2數據量", down2:used()) -- 處理下行數據 if point == 0 then write_record_data(down1, true) down1:del() -- 清空緩沖區 else write_record_data(down2, true) down2:del() -- 清空緩沖區 end else log.info("錄音", "上行數據,位于緩存", point+1, "緩存1數據量", up1:used(), "緩存2數據量", up2:used()) -- 處理上行數據 if point == 0 then write_record_data(up1, false) up1:del() -- 清空緩沖區 else write_record_data(up2, false) up2:del() -- 清空緩沖區 end end log.info("通話質量", cc.quality()) end -- 啟用通話錄音 local function enableRecording() cc.record(true, up1, up2, down1, down2) cc.on("record", recordCallback) log.info("cc_app", "通話錄音已啟用") end -- 開始通話錄音到文件 local function start_call_recording() if open_record_file() then log.info("通話錄音", "開始錄音到文件:", RECORD_FILE_PATH) return true else log.error("通話錄音", "無法開始錄音到文件,請檢查SD卡") return false end end -- 停止通話錄音到文件 local function stop_call_recording() close_record_file() log.info("通話錄音", "停止錄音到文件") end -- 獲取所有緩沖區 local function getRecordingBuffers() return { up1 = up1, up2 = up2, down1 = down1, down2 = down2 } end -- 獲取錄音文件信息 local function get_record_file_info() if io.exists(RECORD_FILE_PATH) then local file_size = io.fileSize(RECORD_FILE_PATH) return { path = RECORD_FILE_PATH, size = file_size, duration = record_duration, exists = true } else return { path = RECORD_FILE_PATH, size = 0, duration = 0, exists = false } end end -- 呼入自動接聽,等待對方掛斷 local function handle_scenario(status) if status == "INCOMINGCALL" then -- 獲取來電號碼 caller_number = cc.lastNum() or "未知號碼" call_counter = call_counter + 1 log.info("收到來電,號碼:", caller_number, "響鈴次數:", call_counter) -- 響鈴2聲后自動接聽 if call_counter >= 2 then log.info("自動接聽來電") cc.accept(0) call_counter = 0 -- 重置計數器 end elseif status == "SPEECH_START" then -- 語音通話真正開始 log.info("電話已接通,電話號碼:", caller_number) -- 開始通話錄音到文件 start_call_recording() elseif status == "DISCONNECTED" then -- 對方掛斷通話 log.info("通話結束對方掛斷") -- 停止通話錄音到文件 stop_call_recording() call_counter = 0 -- 重置計數器 end end -- ====================== 主事件處理器 ====================== sys.subscribe("CC_IND", function(status) log.info("CC狀態", status) handle_scenario(status) -- 需要處理的通用狀態 if status == "READY" then sys.publish("CC_READY") -- 發布系統就緒事件 elseif status == "HANGUP_CALL_DONE" or status == "MAKE_CALL_FAILED" or status == "DISCONNECTED" then exaudio.pm(audio.SHUTDOWN) --主動進入低功耗模式 end end) -- ====================== 電話系統初始化 ====================== local function init_cc() -- 先嘗試掛載SD卡 mount_sd_card() -- 初始化音頻設備 audio_drv.initAudioDevice() -- 等待電話系統就緒 sys.waitUntil("CC_READY") -- 初始化電話功能 cc.init(audio_drv.getMultimediaId()) -- 啟用通話錄音(錄音功能在cc_app中) enableRecording() log.info("cc_app", "電話系統初始化完成") end -- 啟動初始化任務 sys.taskInit(init_cc) 四、使用注意事項 必須插入SD卡才能使用錄音功能,因為錄音文件較大無法存入內存;緩沖區大小必須是640的倍數,否則可能導致錄音異常。
四、使用注意事項
必須插入SD卡才能使用錄音功能,因為錄音文件較大無法存入內存;緩沖區大小必須是640的倍數,否則可能導致錄音異常。
錄音文件保存在SD卡的/sd/record_call.pcm路徑下,可以通過讀卡器在電腦上查看;錄音文件為原始PCM格式,需要使用專用播放器(如Audacity)播放。

-
Lua
+關注
關注
0文章
88瀏覽量
11505 -
通話錄音
+關注
關注
0文章
3瀏覽量
1125 -
物聯網開發
+關注
關注
0文章
12瀏覽量
1934 -
LuatOS
+關注
關注
0文章
168瀏覽量
2738
發布評論請先 登錄
解決蘋果手機通話不能錄音的問題
iPhone6手機通話時怎么錄音?,完美攻略get起來吧~
電話錄音,電話錄音系統,電話錄音卡,電話錄音盒
做好通話錄音設備,要考量這幾個方面
電腦版本的通話錄音軟件有哪些
谷歌Android Pie系統正式推出,除了添加一些新特性外通話錄音功能遭遇封殺
ios15支持通話錄音功能嗎 蘋果如何設置通話錄音
ios15出通話錄音,ios15有通話錄音嗎
電銷自動外呼系統的主要功能都有哪些
蘋果13有通話錄音功能嗎
【蘋果神器來襲】錄音寶,讓你的通話錄音so easy!
工業場景通話錄音:LuatOS 開源方案
通話錄音功能實現:自動接聽 + 自動錄音開源方案
評論