AI 應用 圖文 解說 (二) -- 百度智能云 ASR LIM TTS 語音AI助手源碼

?文章的目的為了記錄AI應用學習的經歷,降低AI的入門難度。同時記錄開發流程和要點有些記憶模糊,防止忘記。也希望可以給看到文章的朋友帶來一些收獲。


相關鏈接:
AI 應用 圖文 解說 (一) -- 百度智能云 實現 語音 聊天-CSDN博客
AI 應用 圖文 解說 (二) -- 百度智能云 ASR LIM TTS 語音AI助手程序 -CSDN博客

推薦鏈接:

開源 python 應用 開發(一)python、pip、pyAutogui、python opencv安裝-CSDN博客

開源 python 應用 開發(二)基于pyautogui、open cv 視覺識別的工具自動化-CSDN博客

開源 python 應用 開發(三)python語法介紹-CSDN博客

開源 python 應用 開發(四)python文件和系統綜合應用-CSDN博客

開源 python 應用 開發(五)python opencv之目標檢測-CSDN博客

開源 python 應用 開發(六)網絡爬蟲-CSDN博客

開源 python 應用 開發(七)數據可視化-CSDN博客

開源 python 應用 開發(八)圖片比對-CSDN博客

開源 python 應用 開發(九)目標跟蹤-CSDN博客

開源 python 應用 開發(十)音頻壓縮-CSDN博客

開源 python 應用 開發(十一)AI應用--百度智能云ASR短語音轉文本-CSDN博客

開源 python 應用 開發(十二)AI應用--百度智能云Agent聊天-CSDN博客

開源 python 應用 開發(十三)AI應用--百度智能云TTS語音合成-CSDN博客

開源 python 應用 開發(十四)python快速建設網站-CSDN博客

?推薦鏈接:

開源 Arkts 鴻蒙應用 開發(一)工程文件分析-CSDN博客

開源 Arkts 鴻蒙應用 開發(二)封裝庫.har制作和應用-CSDN博客

開源 Arkts 鴻蒙應用 開發(三)Arkts的介紹-CSDN博客

開源 Arkts 鴻蒙應用 開發(四)布局和常用控件-CSDN博客

開源 Arkts 鴻蒙應用 開發(五)控件組成和復雜控件-CSDN博客

?推薦鏈接:

開源 java android app 開發(一)開發環境的搭建-CSDN博客

開源 java android app 開發(二)工程文件結構-CSDN博客

開源 java android app 開發(三)GUI界面布局和常用組件-CSDN博客

開源 java android app 開發(四)GUI界面重要組件-CSDN博客

開源 java android app 開發(五)文件和數據庫存儲-CSDN博客

開源 java android app 開發(六)多媒體使用-CSDN博客

開源 java android app 開發(七)通訊之Tcp和Http-CSDN博客

開源 java android app 開發(八)通訊之Mqtt和Ble-CSDN博客

開源 java android app 開發(九)后臺之線程和服務-CSDN博客

開源 java android app 開發(十)廣播機制-CSDN博客

開源 java android app 開發(十一)調試、發布-CSDN博客

開源 java android app 開發(十二)封庫.aar-CSDN博客

推薦鏈接:

開源C# .net mvc 開發(一)WEB搭建_c#部署web程序-CSDN博客

開源 C# .net mvc 開發(二)網站快速搭建_c#網站開發-CSDN博客

開源 C# .net mvc 開發(三)WEB內外網訪問(VS發布、IIS配置網站、花生殼外網穿刺訪問)_c# mvc 域名下不可訪問內網,內網下可以訪問域名-CSDN博客

開源 C# .net mvc 開發(四)工程結構、頁面提交以及顯示_c#工程結構-CSDN博客

??????開源 C# .net mvc 開發(五)常用代碼快速開發_c# mvc開發-CSDN博客

主要內容:一個完整的語音AI助手程序,使用Python實現錄音、語音識別、AI對話和語音合成的功能。

目錄:

1.主要功能

2.源碼分析

3.所有源碼

4.顯示效果

一、主要功能

音頻錄制:使用sounddevice庫錄制16kHz單聲道音頻

語音識別:通過百度語音識別API將音頻轉換為文本

AI對話:使用AppBuilder AI模型進行智能對話

語音合成:通過百度語音合成API將文本轉換為語音

音頻播放:使用多種方式播放生成的語音回復

二、源碼分析

2.1??類定義和初始化 (VoiceAIAssistant)
初始化錄音配置參數(采樣率、聲道數等)

設置API密鑰和認證信息

初始化各個組件(pygame音頻、AppBuilder客戶端)

2.2? 音頻處理功能
start_recording(): 開始錄制音頻

stop_recording(): 停止錄制并保存

audio_callback(): 音頻流回調函數,收集音頻數據

save_to_wav(): 使用wave模塊保存WAV文件

2.3? API調用功能
get_access_token(): 獲取百度API訪問令牌

speech_to_text(): 調用百度語音識別API

text_to_speech(): 調用百度語音合成API

call_ai_model(): 調用AppBuilder AI模型

2.4? 輔助功能
play_audio(): 使用多種方式播放音頻文件

process_audio(): 完整的音頻處理流程

keyboard_listener(): 鍵盤監聽主循環

5. 工具函數
check_dependencies(): 檢查所需Python庫是否已安裝

main(): 程序主函數

三、所有源碼

import sounddevice as sd
import numpy as np
import wave
import keyboard
import time
import os
import base64
import urllib
import requests
import json
import pygame
import tempfile
import threading
import subprocess
from pydub import AudioSegment
import appbuilderclass VoiceAIAssistant:def __init__(self):# 錄音配置self.is_recording = Falseself.frames = []self.sample_rate = 16000self.channels = 1self.audio_filename = "test.wav"self.response_filename = "response.wav"# API配置 - 請替換為您的實際密鑰self.api_key = ""self.secret_key = ""self.app_token = ""self.app_id = ""# 設置環境變量os.environ["APPBUILDER_TOKEN"] = self.app_token# 初始化組件self.init_components()def init_components(self):"""初始化各個組件"""try:# 初始化pygame音頻pygame.mixer.init()print("? Pygame音頻初始化成功")except Exception as e:print(f"? Pygame初始化失敗: {e}")try:# 初始化AppBuilder客戶端self.app_builder_client = appbuilder.AppBuilderClient(self.app_id)self.conversation_id = self.app_builder_client.create_conversation()print("? AppBuilder客戶端初始化成功")except Exception as e:print(f"? AppBuilder初始化失敗: {e}")self.app_builder_client = Nonedef start_recording(self):"""開始錄制音頻"""if self.is_recording:print("已經在錄制中...")returnself.is_recording = Trueself.frames = []print("開始錄制16K音頻... (按空格鍵停止并保存)")try:# 直接使用16K采樣率錄制self.stream = sd.InputStream(samplerate=self.sample_rate,channels=self.channels,callback=self.audio_callback,dtype='int16')self.stream.start()return Trueexcept Exception as e:print(f"開始錄制失敗: {e}")self.is_recording = Falsereturn Falsedef stop_recording(self):"""停止錄制并保存"""if not self.is_recording:print("當前沒有在錄制")return Falseself.is_recording = Falseprint("停止錄制,正在保存16K WAV文件...")try:self.stream.stop()self.stream.close()return self.save_to_wav()except Exception as e:print(f"停止錄制失敗: {e}")return Falsedef audio_callback(self, indata, frames, time, status):"""音頻回調函數"""if status:print(f"音頻流狀態: {status}")if self.is_recording:self.frames.append(indata.copy())def save_to_wav(self):"""使用wave模塊保存WAV文件"""if not self.frames:print("沒有音頻數據可保存")return Falsetry:# 合并所有音頻幀audio_data = np.concatenate(self.frames, axis=0)audio_data = audio_data.flatten()# 確保數據在16位范圍內audio_data = np.clip(audio_data, -32768, 32767)audio_data = audio_data.astype(np.int16)# 使用wave模塊保存with wave.open(self.audio_filename, 'wb') as wav_file:wav_file.setnchannels(self.channels)wav_file.setsampwidth(2)  # 16位 = 2字節wav_file.setframerate(self.sample_rate)wav_file.writeframes(audio_data.tobytes())print(f"? 成功保存16K WAV文件: {self.audio_filename}")return Trueexcept Exception as e:print(f"保存文件時出錯: {e}")return Falsedef get_file_content_as_base64(self, path, urlencoded=False):"""獲取文件base64編碼"""try:with open(path, "rb") as f:content = base64.b64encode(f.read()).decode("utf8")if urlencoded:content = urllib.parse.quote_plus(content)return contentexcept Exception as e:print(f"讀取文件錯誤: {e}")return Nonedef get_access_token(self):"""獲取百度API訪問令牌"""try:url = "https://aip.baidubce.com/oauth/2.0/token"params = {"grant_type": "client_credentials", "client_id": self.api_key, "client_secret": self.secret_key}response = requests.post(url, params=params)response.raise_for_status()result = response.json()access_token = result.get("access_token")if access_token:print("? 成功獲取access_token")return access_tokenelse:print(f"獲取access_token失敗: {result}")return Noneexcept Exception as e:print(f"獲取access_token錯誤: {e}")return Nonedef speech_to_text(self):"""語音識別:將音頻轉換為文本"""try:if not os.path.exists(self.audio_filename):print(f"錯誤:文件不存在 - {self.audio_filename}")return Nonefile_size = os.path.getsize(self.audio_filename)url = "https://vop.baidu.com/server_api"access_token = self.get_access_token()if not access_token:return Nonepayload = json.dumps({"format": "wav","rate": 16000,"channel": 1,"cuid": "voice_assistant_cuid","token": access_token,"speech": self.get_file_content_as_base64(self.audio_filename, False),"len": file_size}, ensure_ascii=False)headers = {'Content-Type': 'application/json','Accept': 'application/json'}response = requests.post(url, headers=headers, data=payload.encode("utf-8"))if response.status_code == 200:result = response.json()if result.get("err_no") == 0:text = result.get("result", [""])[0]print(f"? 識別結果: {text}")return textelse:print(f"語音識別失敗: {result.get('err_msg')}")return Noneelse:print(f"請求失敗,狀態碼: {response.status_code}")return Noneexcept Exception as e:print(f"語音識別錯誤: {e}")return Nonedef text_to_speech(self, text):"""文本轉語音:將文本轉換為音頻"""try:url = "https://tsn.baidu.com/text2audio"access_token = self.get_access_token()if not access_token:return Noneencoded_text = urllib.parse.quote(text)params = {'tex': encoded_text,'tok': access_token,'cuid': 'voice_assistant_cuid','ctp': 1,'lan': 'zh','spd': 5,'pit': 5,'vol': 5,'per': 0,'aue': 6  # WAV格式}headers = {'Content-Type': 'application/x-www-form-urlencoded','Accept': 'audio/wav'}response = requests.post(url, data=params, headers=headers)if response.status_code == 200:# 保存音頻文件with open(self.response_filename, 'wb') as f:f.write(response.content)print(f"? 語音合成完成,保存為: {self.response_filename}")return self.response_filenameelse:print(f"語音合成失敗,狀態碼: {response.status_code}")return Noneexcept Exception as e:print(f"語音合成錯誤: {e}")return Nonedef call_ai_model(self, text):"""調用AI大模型處理文本"""if not self.app_builder_client:print("? AppBuilder客戶端未初始化")return "抱歉,AI服務暫時不可用。"try:print(f"🤖 向AI模型提問: {text}")resp = self.app_builder_client.run(self.conversation_id, text)answer = resp.content.answerprint(f"🤖 AI回復: {answer}")return answerexcept Exception as e:print(f"調用AI模型錯誤: {e}")return "抱歉,我暫時無法處理您的請求。"def play_audio(self, audio_file):"""播放音頻文件"""if not os.path.exists(audio_file):print(f"錯誤:音頻文件不存在 - {audio_file}")return Falsetry:# 方法1: 使用winsound播放(最簡單)import winsoundprint("🔊 正在播放音頻...")winsound.PlaySound(audio_file, winsound.SND_FILENAME)print("? 播放完成")return Trueexcept Exception as e:print(f"winsound播放失敗: {e}")try:# 方法2: 使用pygame播放pygame.mixer.music.load(audio_file)pygame.mixer.music.play()print("🔊 正在播放音頻...")# 等待播放完成while pygame.mixer.music.get_busy():pygame.time.wait(100)print("? 播放完成")return Trueexcept Exception as e:print(f"pygame播放失敗: {e}")try:# 方法3: 使用系統命令播放if os.name == 'nt':  # Windowsos.startfile(audio_file)else:  # Linux/Macsubprocess.run(['aplay', audio_file])print("? 使用系統播放器播放")return Trueexcept Exception as e:print(f"系統播放失敗: {e}")return Falsedef process_audio(self):"""完整處理流程:錄音->識別->AI->語音合成->播放"""print("=" * 60)print("開始處理音頻...")print("=" * 60)# 1. 語音識別print("🎤 正在識別語音...")recognized_text = self.speech_to_text()if not recognized_text:print("? 語音識別失敗")return False# 2. 調用AI模型print("🧠 正在調用AI模型...")ai_response = self.call_ai_model(recognized_text)# 3. 語音合成print("🔊 正在合成語音...")audio_file = self.text_to_speech(ai_response)if not audio_file:print("? 語音合成失敗")return False# 4. 播放音頻print("?? 正在播放回復...")return self.play_audio(audio_file)def keyboard_listener(self):"""鍵盤監聽主循環"""print("=" * 60)print("語音AI助手已啟動")print("按空格鍵開始/停止錄制")print("按ESC鍵退出程序")print("=" * 60)recording_started = Falsewhile True:# 檢測空格鍵if keyboard.is_pressed('space'):if not recording_started:if not self.is_recording:# 開始錄制if self.start_recording():print("?? 錄制中... (再次按空格停止)")else:# 停止錄制并處理if self.stop_recording():# 在新線程中處理音頻,避免阻塞鍵盤監聽processing_thread = threading.Thread(target=self.process_audio)processing_thread.daemon = Trueprocessing_thread.start()recording_started = Truetime.sleep(0.5)  # 防抖else:recording_started = False# 檢測ESC鍵退出if keyboard.is_pressed('esc'):if self.is_recording:self.stop_recording()print("👋 程序退出")breaktime.sleep(0.1)def check_dependencies():"""檢查所需依賴"""required_libs = ['sounddevice', 'numpy', 'keyboard', 'requests', 'pygame', 'pydub', 'appbuilder']missing_libs = []for lib in required_libs:try:if lib == 'appbuilder':import appbuilderelif lib == 'pydub':from pydub import AudioSegmentelse:__import__(lib)print(f"? {lib} 已安裝")except ImportError:print(f"? {lib} 未安裝")missing_libs.append(lib)if missing_libs:print(f"\n請安裝缺失的庫: pip install {' '.join(missing_libs)}")return Falsereturn Truedef main():"""主函數"""# 檢查依賴if not check_dependencies():return# 創建語音助手實例try:assistant = VoiceAIAssistant()# 啟動鍵盤監聽assistant.keyboard_listener()except KeyboardInterrupt:print("\n👋 程序被用戶中斷")except Exception as e:print(f"? 程序運行錯誤: {e}")if __name__ == "__main__":main()

四、使用效果

使用python IDE 運行或雙擊.py文件,代碼會檢查所需要的庫,如果沒有安裝,使用pip安裝就行。

如果報錯 Appbuilder問題,可以進行升級。

pip install --upgrade appbuilder-sdk -i https://mirrors.aliyun.com/pypi/simple/

程序不再報錯后,按下空格開始錄音,會音頻提交到智能云,與AI對話,最后返回合成的語音。音頻文件為.wav存放在桌面。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/97532.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/97532.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/97532.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

計算機Python畢業設計推薦:基于Django的博客網站設計與實現【python/大數據/深度學習/機器學習定制】

精彩專欄推薦訂閱:在下方主頁👇🏻👇🏻👇🏻👇🏻 💖🔥作者主頁:計算機畢設木哥🔥 💖 文章目錄 一、項目介紹二、…

當 AI 開始 “篩選” 信息:算法偏見會加劇認知鴻溝嗎?如何構建公平的 AI 生態?

AI 篩選信息的現狀與原理?在信息爆炸的時代,AI 篩選信息已成為各領域不可或缺的關鍵技術。在社交媒體平臺上,如抖音、小紅書等,AI 根據用戶的點贊、評論、瀏覽歷史等數據,精準推送用戶可能感興趣的內容,極大提升了用戶…

2023年IEEE IOTJ SCI1區TOP,動態環境下無人機目標覆蓋任務路徑規劃,深度解析+性能實測

目錄1.摘要2.問題模型3.算法設計4.結果展示5.參考文獻6.代碼獲取7.算法輔導應用定制讀者交流1.摘要 無人機(UAV)作為物聯網應用的重要工具,正廣泛應用于智能農業監測、智能交通監測等領域,并逐漸成為國內外研究熱點。然而&#x…

計算機視覺(四):二值化

二值化,就是將圖像從彩色或灰度模式轉換為只有兩種顏色(通常是黑色和白色)的模式。這個過程的本質是設定一個閾值 (Threshold),將圖像中所有像素的灰度值與這個閾值進行比較。 基本原理 二值化的核心原理非常簡單: 灰度…

(二)設計模式(Command)

文章目錄項目地址一、設計模式1.1 Command Design1. 創建命令接口2. 創建支付的Command類3. CommandScheduler4. 使用1.2 Chain of Responsibility1. 接口創建2. 審批人3. 發起審批1.3 State Pattern1. 創建簡單的狀態機定義動作和狀態狀態機使用狀態機1.x Iterator1.x Observe…

現代C++性能陷阱:std::function的成本、異常處理的真實開銷

1. std::function 的成本 std::function 是一個通用的、類型擦除的函數包裝器,它非常方便,可以存儲和調用任何可調用對象(函數、lambda、函數對象、bind表達式等)。然而,這種靈活性是有代價的。 主要成本來源&#xff…

基于Spark的白酒行業數據分析與可視化系統的設計與實現

文章目錄有需要本項目的代碼或文檔以及全部資源,或者部署調試可以私信博主項目介紹一、項目背景與研究意義二、系統整體架構三、系統功能設計四、應用場景與價值五、項目特色與創新點六、總結與展望每文一語有需要本項目的代碼或文檔以及全部資源,或者部…

織夢會員中心模板調用某個欄目名和欄目下文檔的辦法

大家在用到織夢dedecms時候,需要在會員中心模板調用欄目的名稱和鏈接,還有某個欄目下的文檔要怎么操作呢? 我們都知道,在會員中心模板,直接用dede:type或者dede:arclist標簽是不行的,在會員中心調用只能用p…

區塊鏈的法律定位:技術、工具還是資產?

高鵬律師首席數據官,數字經濟團隊創作AI輔助當我們談論區塊鏈時,我們在談論什么?是那串不可篡改的哈希值,是去中心化的信仰圖騰,還是藏在代碼背后的權利密碼?今天,我們不聊技術迭代的炫酷&#…

LeetCode每日一題,2025-8-31

dfs搜索解數獨,重點是如何判斷當前這位置的board[x][y]是否可以填數字num public class T37 {public static void main(String[] args) {char[][] board new char[][]{{5, 3, ., ., 7, ., ., ., .},{6, ., ., 1, 9, 5, ., ., .},{., 9, 8, ., ., ., ., 6, .},{8, …

Linux 進程信號學習筆記:從概念到實操

一、Linux 信號基本概念1.1 生活角度理解信號我們可以把進程比作等待快遞的人,信號就像快遞:識別信號:就像我們知道快遞來了該 怎么處理,進程對信號的識別是內核程序員預先編寫的內置特性,即使信號沒產生,進…

解決多種類潮濕敏感元器件的多溫度、多時長的排潮烘干

鎧德科技ESD烘箱針對復雜電路產品的排潮烘干需求,可通過以下技術路徑實現多品類元器件的高效兼容處理:多溫區獨立控制系統采用蜂窩式加熱模塊陣列,每個0.6m獨立溫區可設置1℃精度支持同時運行3種不同溫度曲線(典型值:8…

obdumper和obloader遷移OceanBase業務庫(一):實施手冊

obdumper和obloader遷移OceanBase業務庫(一):實施手冊導出前準備全庫(模式)數據導出全庫(模式)數據導入導入后檢查環境信息:OceanBase v4.3.5單機部署,MySQL租戶OBDUMPER…

SQLSugar 快速入門:從基礎到實戰查詢與使用指南

目錄 ?編輯 一、SQLSugar 簡介 二、SQLSugar 環境搭建 2.1 安裝 SQLSugar 2.1.1 通過 Visual Studio NuGet 圖形化界面安裝 2.1.2 通過 NuGet 命令行安裝 2.2 引用 SQLSugar 命名空間 三、SQLSugar 核心初始化配置 3.1 基礎初始化(非 IOC 模式&#xff09…

Python與Rust語法對比詳解:從入門到精通

Python與Rust語法對比詳解:從入門到精通 前言 Python和Rust作為當今最受關注的編程語言,分別代表了動態類型和靜態類型語言的典型特征。本文將從語法層面深入對比這兩種語言,幫助開發者理解它們的設計理念和使用場景。1. 基礎語法結構 1.1 He…

視頻加水印_帶gif 加動態水印 gif水印 視頻浮動水印

如果你有一個視頻,你想給它加一個水印,讓水印浮動,而且加的還是 GIF 動態圖片水印,那么你可以使用這個工具。首先把你的兩個文件拖進來,然后點擊第三個按鈕。加好了,打開看一下,我們看到這個水印…

C# 字符和字符串

原文:C# 字符和字符串_w3cschool 請勿將文章標記為付費!!!!! C#字符和字符串 C#的 char 類型別名 System.Char 類型表示 Unicode 字符。 在單引號中指定char字面值: …

IntelliJ IDEA 反編譯JAR包記錄

本文記錄了使用 IntelliJ IDEA 內置反編譯工具對 JAR 包進行反編譯的詳細步驟,方便日后快速參考和使用。 🛠? 工具準備 反編譯工具使用的是 IntelliJ IDEA 內置的 Java 反編譯器,無需額外安裝其他工具。 工具路徑: /Applications…

KingbaseES JDBC 驅動詳解:連接、配置與最佳實踐

目錄KingbaseES JDBC 驅動詳解:連接、配置與最佳實踐引言一、JDBC 基礎與 KingbaseES 實現1.1 JDBC 技術概述1.2 KingbaseES JDBC 驅動特點二、環境配置與驅動獲取2.1 驅動包選擇與依賴管理2.2 國密算法支持2.3 驅動版本信息獲取三、數據庫連接管理3.1 使用 DriverM…

破解 Aspose.Words 24.12,跳過 License 校驗,實現 HTML 向 Word/PDF 的轉換,附帶 Demo。

說明 在Java生態中處理Office文檔時,開發人員常面臨格式兼容性和功能完整性的挑戰。商業組件Aspose以其卓越的文檔處理能力成為企業級解決方案之一,支持Word、Excel、PDF等多種格式的精準轉換與操作。 請勿用于商業用途,若侵權請聯系我。 參考…