news 2026/5/11 6:44:09

react native(学习笔记第四课) 英语打卡微应用(3)-ocr的文字转化成语音文件(tts)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
react native(学习笔记第四课) 英语打卡微应用(3)-ocr的文字转化成语音文件(tts)

文章目录

  • react native(学习笔记第四课) 英语打卡微应用(3)-图片转化成语音文件
      • 1. 文字到语音的转换`AI` (`Text To Speech TTS` )
      • 1.1 `AI`的采用选择
      • 1.2 全体代码
      • 1.2.1 主要`TTS`的类
      • 1.2.2 `pytest`进行提前测试
      • 1.2.3 最后进行结合到`backend`的真正代码中
      • 1.2.4 修改的代码汇总
    • 2. 构建基础`TTS`类
    • 3. 创建`pytest`代码并执行
      • 3.1 创建`pytest`代码
      • 3.2 执行`pytest`代码
    • 4. 在`backend`中调用`TTS`类进行语音生成
      • 4.1 修改`backend`中的代码
      • 4.2 执行手机应用进行测试
    • 5. 接下来的工作

react native(学习笔记第四课) 英语打卡微应用(3)-图片转化成语音文件

  • 文字到语音的转换AI(Text To Speech TTS)
  • 构建基础TTS
  • 创建pytest代码
  • backend中调用TTS类进行语音生成
  • 接下来的工作

1. 文字到语音的转换AI(Text To Speech TTS)

TTS是Text To Speech的缩写,即“从文本到语音”,是人机对话的一部分,让机器能够说话。TTS技术对文本文件进行实时转换,转换时间之短可以秒计算,速度非常快。

1.1AI的采用选择

因为上一个阶段使用了智谱AI,进行了图片到文字的OCR抽取,为了保持LLM的单一选择,是程序更加简单。继续选择使用智谱AI。
看到智谱AI的平台上,提供了TTSAI服务,正好可以使用。这里可以充值10元,可以使用好长时间,在测试阶段还是没有问题的。

在下面这里可以查看API的使用方法。

文本转语音API

1.2 全体代码

全体代码
介绍一下在这个阶段的主要改修和做成的代码。

1.2.1 主要TTS的类

TTS类
主要功能:

  • 接受HumanMessage或者纯文本的文本输入。
  • 调用智谱AIglm-tts,进行文本到语音的输出。
  • 将结果保存到wav文件中。

1.2.2pytest进行提前测试

pytest代码
主要功能:

  • sample文本文件中,提取文本。
  • pytest代码中,调用TTS类。

1.2.3 最后进行结合到backend的真正代码中

结合代码

1.2.4 修改的代码汇总

红色的地方是做成的代码部分,蓝色部分是backend的代码进行调用TTS类的地方。

2. 构建基础TTS

这里很简单,就是使用通常的request类进行https的请求,进行TTS转换。

importosimportuuidimportrequestsimportwaveimportiofromdotenvimportload_dotenvfromlangchain_core.runnablesimportRunnableLambda load_dotenv()classGLMTTS:def__init__(self):self.api_key=os.getenv("ZHIPU_AI_API_KEY")self.base_url=os.getenv("GLM_TTS_BASE_URL","https://open.bigmodel.cn/api/paas/v4/audio/speech")self.output_dir=os.getenv("TTS_OUTPUT_DIR","./tts_output")# speech max lengthself.speech_max_length=int(os.getenv("SPEECH_MAX_LENGTH",999))os.makedirs(self.output_dir,exist_ok=True)def_extract_text(self,messages)->str:"""从 LangChain message 结构中提取纯文本"""fromlangchain_core.messagesimportHumanMessageifnotisinstance(messages,list):returnstr(messages)texts=[]forminmessages:ifisinstance(m,HumanMessage):texts.append(m.content)elifisinstance(m,tuple)andm[0]=="human":texts.append(m[1])else:texts.append(str(m))# if length is over max length, the cut into max lengthtexts=texts[:self.speech_max_length]return"\n".join(texts).strip()defgenerate_speech(self,messages)->str:""" 输入: LangChain message / 文本 输出: 保存后的 WAV 文件路径 """text=self._extract_text(messages)print(f"text:{text}")headers={"Authorization":f"Bearer{self.api_key}","Content-Type":"application/json"}payload={"model":"glm-tts","input":text,"voice":"male","stream":False,"response_format":"wav"}resp=requests.post(self.base_url,headers=headers,json=payload)resp.raise_for_status()wav_bytes=resp.content filename=f"{uuid.uuid4().hex}.wav"file_path=os.path.join(self.output_dir,filename)withopen(file_path,"wb")asf:f.write(wav_bytes)returnfile_path# ✅ LangChain Runnable 兼容接口defas_runnable(self):returnRunnableLambda(self.generate_speech)

注意,这里通过dotenv定义了SPEECH_MAX_LENGTH999,之后暂时将超过999文字的截取到999文字内。因为通过测试看出智谱AIglm-tts这里,如果超过1000文字,就会出错,所以暂时先这样对应了一下。以后,将考虑将文章进行每1000的分割调用。

3. 创建pytest代码并执行

3.1 创建pytest代码

这里如果直接和backend的代码,那么调式起来还需要手机react native应用的启动,进行图片的扫描与AIocr解析,在这之前,使用pytest进行类似于单体测试。
注意,这里规范pytest的路径:

  • 和正式代码的根目录\app的同级,建立目录\tests
  • \tests的子路径也是测试的目标代码同样建立,\tests\ai\tts
  • 创建pytest的文件test_glm_test.py
# tests/test_glm_tts.pyimportsysfrompathlibimportPathfromapp.ai.tts.glm_ttsimportGLMTTSdeftest_glm_tts_001():withopen("tests\\resources\\speech.txt","r",encoding="utf-8")asf:lines=f.readlines()content="".join(lines)content=content[:999]print(f"len:{len(content)}")tts=GLMTTS()wav_path=tts.generate_speech(content)assert(len(wav_path)>0)

这里,需要注意两点:

  • 需要设定pytest.ini文件,让root path设定到apptests的父目录,以便pytest的测试代码能够找到app下的backend测试类(制品代码)。
  • 另外在这里准备好测试的文本文件,tests/resources/speech.txt,在pytest中使用这个文本文件。

3.2 执行pytest代码

这里,因为需要执行pytest,实现安装pytest

pipinstallpytest

之后,可以将venv里面上安装的python包提出到requirements.txt中,那么执行下面命令。

pip freeze>requirements.txt

接下来执行pytest的代码。

pytest .\tests\ai\tts\test_glm_tts.py


之后,进行结果的检查。注意,这里将dotenv里面定义了wav文件的输出路径。

检查输出路径,可以看到已经生成了文件(文件名字是UUID)。

可以听听转换成的语音文件。

4. 在backend中调用TTS类进行语音生成

4.1 修改backend中的代码

fromlangchain_core.messagesimportHumanMessagefromapp.ai.ttsimportGLMTTSclassOCRService:asyncdefextract_text(self,base64_url)->str:""" 从图片字节数据中提取文字 """try:# 在线程池中运行CPU密集型的OCR任务# 这样可以避免阻塞FastAPI的异步事件循环loop=asyncio.get_event_loop()# 执行OCRanalyzer=create_image_analyzer()result=analyzer(base64_url)# 将执行结果送给AI,转换成wav文件messages=[HumanMessage(content=result),]tts=GLMTTS()wav_path=tts.generate_speech(messages)print("生成音频路径:",wav_path)returnresultexceptExceptionase:logger.error(f"文字提取失败:{str(e)}",exc_info=True)# exc_info=True 会记录完整的堆栈跟踪raiseException(f"OCR处理失败:{str(e)}")

4.2 执行手机应用进行测试


这时候,点击识别文字的按钮,就会看到,经过了一会的处理,backend的本地路径(dotenv定义TTS_OUTPUT_DIR=C:\\Users\\Dell\\workspace上会出现生成的语音文件。
到此,实现了下面功能:

  • 手机的react native的应用进行拍照
  • 传递到backend
  • backend调用大模型实现
    • 图片到文本文件的ocr抽取
    • 文本到语音的转换

5. 接下来的工作

  • 将文本以及生成的wavbytes进行数据库的保存
  • 之后实现react native手机应用上,对数据库里面的数据进行list表示。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/11 6:44:08

Qt界面嵌入Halcon窗口实战:告别独立弹窗,实现一体化图像处理界面

Qt与Halcon深度整合:打造一体化机器视觉界面的实战指南 在工业自动化领域,机器视觉系统正变得越来越普及,而用户界面的友好程度直接影响着操作人员的工作效率。传统Halcon开发中,图像处理结果往往通过独立弹窗显示,这种…

作者头像 李华
网站建设 2026/5/11 6:40:29

UCC25600 LLC谐振变换器:从补偿网络设计到软启动与过流保护的实战调试

1. UCC25600 LLC谐振变换器入门指南 第一次接触LLC谐振变换器时,我被它的高效和低EMI特性吸引,但真正用UCC25600做项目时才发现理论和实操差距不小。这款德州仪器的控制器确实强大,但要把它的性能完全发挥出来,得先理解几个关键点…

作者头像 李华
网站建设 2026/5/11 6:32:05

好用的本地部署机构

在本地部署领域,诸多核心技术挑战影响着行业的发展。数据表明,中小企业缺乏AI研发团队,传统定制化开发周期长达数月,成本动辄百万级,这使得许多企业望而却步。同时,公有云部署存在数据泄露风险,…

作者头像 李华
网站建设 2026/5/11 6:25:23

Vagrant封装工具:快速搭建Claude API本地开发环境

1. 项目概述与核心价值最近在折腾本地大模型开发环境时,发现了一个挺有意思的工具——awfulwoman/vagrant-claude-wrapper。这名字乍一看有点“劝退”,但实际用下来发现,它解决了一个我在多项目、多环境开发中经常遇到的痛点:如何…

作者头像 李华
网站建设 2026/5/11 6:23:37

LeetCode 只出现一次的数字题解

LeetCode 只出现一次的数字题解 题目描述 给定一个整数数组,除了某个元素只出现一次外,其余每个元素均出现两次。找出那个只出现一次的元素。 示例: 输入:nums [2,2,1]输出:1 输入:nums [4,1,2,1,2]输出&…

作者头像 李华