【Python】PC听书工具,微软tts朗读

简介:

使用edge-tts朗读txt文本。拥有“断点续读”的功能。会缓存一大堆的mp3文件,可以手动清理,也可以动手合成一个音频发b站之类的。: )

20231205更新:

现在把源码上传到gitee了,方便手机用termux时克隆代码到本地。txtReader: termux 上使用 或 windows 上使用的 txt阅读器 (gitee.com)

git clone https://gitee.com/harryxiaocn/txt-reader.git

20230921更新:

为了避免缓存不够,听起来断断续续的,现在三线程同时下载音频……

源码(已过期,以仓库内源码为准):

# coding=utf-8
import json
import os.path
import threading
import time

import edge_tts as et
from playsound import playsound
import asyncio
"""
准备工作:
1、pip3 install edge_tts
2、pip3 install playsound
"""


def RTxt(path):
  with open(path, encoding='utf8') as f:
    return f.read()


def WTxt(path, content):
  with open(path, 'w', encoding='utf8') as f:
    f.write(content)


class Reader:
  def __init__(self, txtPath):
    self.novel = RTxt(txtPath)
    self.novelName = os.path.basename(txtPath).split('.')[0]
    self.lines = self.novel.split('\n')
    self.setting = {'pos': 0, 'downloadPos': 0}
    self.sayProcess = None
    if os.path.exists('setting.json'):
      self.setting = json.loads(RTxt('setting.json'))
    self.end = False

  def Start(self):
    def Download():
      while self.setting['downloadPos'] < len(self.lines):
        line = self.lines[self.setting['downloadPos']]
        try:
          self.Download(line)
        except Exception as e:
          print('Download.e=', e, self.setting['downloadPos'])
        WTxt('setting.json', json.dumps(self.setting))
        while self.setting['downloadPos'] > self.setting['pos'] + 300:
          time.sleep(1)

    def Say():
      while self.setting['pos'] < len(self.lines):
        while self.setting['downloadPos'] < self.setting['pos'] + 10:
          print('等待缓存中……')
          time.sleep(1)
        # print('下载行=', self.setting['downloadPos'])
        # print('朗读行=', self.setting['pos'])
        print('朗读行=', self.lines[self.setting['pos']], self.setting['pos'], self.setting['downloadPos'])
        self.Say()
        self.setting['pos'] += 1

    downloadThread = threading.Thread(target=Download, daemon=True)
    downloadThread.start()

    downloadThread2 = threading.Thread(target=Download, daemon=True)
    downloadThread2.start()

    downloadThread3 = threading.Thread(target=Download, daemon=True)
    downloadThread3.start()

    sayThread = threading.Thread(target=Say, daemon=True)
    sayThread.start()
    sayThread.join()

  def Download(self, text, voice='zh-CN-YunxiNeural', rate='+25%', volume='+0%'):
    mp3Path = 'temp\\{}_{}.mp3'.format(self.novelName, self.setting['downloadPos'])
    try:
      self.setting['downloadPos'] += 1

      async def Do():
        await t.save(mp3Path)
      t = et.Communicate(text=text, voice=voice, rate=rate, volume=volume)
      asyncio.run(Do())
    except Exception as e:
      print('[error]Download.e=', e, mp3Path)

  def Say(self):
    """朗读"""
    mp3Path = 'temp\\{}_{}.mp3'.format(self.novelName, self.setting['pos'])
    if os.path.exists(mp3Path) and os.path.getsize(mp3Path) > 0:
      try:
        playsound('{}\\{}'.format(os.getcwd(), mp3Path))
      except Exception as e:
        print('[error]Say.e=', e)


if __name__ == '__main__':
  reader = Reader('小说.txt')
  reader.Start()
  print('程序终止!')

暂停之类的功能实现起来比较麻烦,就没弄了。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值