Spaces:
Sleeping
Sleeping
#!/usr/bin/python3 | |
# -*- coding: utf-8 -*- | |
import argparse | |
import asyncio | |
from functools import partial | |
import json | |
import logging | |
from pathlib import Path | |
import platform | |
from typing import List | |
import uuid | |
from project_settings import project_path, log_directory, temp_directory, edge_tts_temp_directory | |
import log | |
log.setup(log_directory=log_directory) | |
import aiofiles | |
import anyio | |
import edge_tts | |
import gradio as gr | |
import librosa | |
from scipy.io import wavfile | |
import spacy | |
from toolbox.os.command import Command | |
main_logger = logging.getLogger("main") | |
def get_args(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument( | |
"--example_wav_dir", | |
default=(project_path / "data/examples").as_posix(), | |
type=str | |
) | |
args = parser.parse_args() | |
return args | |
async def edge_tts_get_speakers() -> List[str]: | |
edge_tts_speakers_choices = list() | |
voices = await edge_tts.list_voices() | |
for voice in voices: | |
short_name = voice["ShortName"] | |
locale = voice["Locale"] | |
if locale != "zh-CN": | |
continue | |
edge_tts_speakers_choices.append(short_name) | |
return edge_tts_speakers_choices | |
async def edge_tts_text_to_speech(text: str, speaker: str, audio_dir: Path = edge_tts_temp_directory): | |
# tts | |
main_logger.info(f"edge tts; speaker: {speaker}; text: {text}") | |
communicate = edge_tts.Communicate(text, speaker) | |
# save audio | |
audio_dir.mkdir(parents=True, exist_ok=True) | |
audio_file = audio_dir / "{}.wav".format(uuid.uuid4()) | |
audio_file = audio_file.as_posix() | |
record_file = audio_dir / "edge_tts.jsonl" | |
try: | |
await communicate.save(audio_file) | |
except edge_tts.exceptions.NoAudioReceived: | |
audio_file = None | |
# save record | |
async with aiofiles.open(record_file.as_posix(), "a+", encoding="utf-8") as f: | |
row = json.dumps({ | |
"text": text, | |
"speaker": speaker, | |
"filename": audio_file, | |
}, | |
ensure_ascii=False) | |
await f.write("{}\n".format(row)) | |
return audio_file | |
spacy_model = spacy.load("zh_core_web_sm") | |
async def e_book_reading(txt_file: str, speaker: str): | |
txt_file = Path(txt_file) | |
audio_dir = temp_directory / "e_book_reading" / txt_file.stem / speaker | |
while True: | |
async with aiofiles.open(txt_file.as_posix(), "r", encoding="utf-8") as f: | |
data = await f.read() | |
doc = spacy_model(data) | |
for sentence in doc.sents: | |
text = sentence.text.strip() | |
if len(text) == 0: | |
continue | |
filename = await edge_tts_text_to_speech(text=text, speaker=speaker, audio_dir=audio_dir) | |
# sample_rate, signal = wavfile.read(filename) | |
signal, sample_rate = librosa.load(filename) | |
duration = len(signal) / sample_rate | |
yield filename | |
await asyncio.sleep(duration) | |
def shell(cmd: str): | |
return Command.popen(cmd) | |
def main(): | |
args = get_args() | |
title = "## 电子书阅读." | |
loop = asyncio.get_event_loop() | |
edge_tts_speakers_choices = loop.run_until_complete(edge_tts_get_speakers()) | |
# blocks | |
with gr.Blocks() as blocks: | |
gr.Markdown(value=title) | |
with gr.Tabs(): | |
with gr.TabItem("Edge TTS"): | |
edge_tts_text = gr.Textbox(value="学而时习之,不亦悦乎。", lines=4, max_lines=50, label="text") | |
edge_tts_speaker = gr.Dropdown(choices=edge_tts_speakers_choices, value="zh-CN-XiaoxiaoNeural", label="speakers") | |
edge_tts_audio = gr.Audio(type="filepath", label="audio", autoplay=True) | |
edge_tts_button = gr.Button(value="edge_tts", variant="primary") | |
edge_tts_button.click( | |
edge_tts_text_to_speech, | |
inputs=[ | |
edge_tts_text, | |
edge_tts_speaker, | |
], | |
outputs=[ | |
edge_tts_audio | |
], | |
) | |
with gr.TabItem("Ebook Reading"): | |
e_book_reading_file = gr.File( | |
value=(project_path / "data/e_book/confucianism/the_analects/the_analects.txt").as_posix(), | |
label="txt" | |
) | |
e_book_reading_speaker = gr.Dropdown(choices=edge_tts_speakers_choices, value="zh-CN-XiaoxiaoNeural", label="speakers") | |
e_book_reading_audio = gr.Audio(type="filepath", label="audio", streaming=True) | |
e_book_reading_button = gr.Button(value="e_book_reading", variant="primary") | |
e_book_reading_button.click( | |
e_book_reading, | |
inputs=[ | |
e_book_reading_file, | |
e_book_reading_speaker, | |
], | |
outputs=[ | |
e_book_reading_audio | |
], | |
) | |
with gr.TabItem("shell"): | |
shell_text = gr.Textbox(label="cmd") | |
shell_button = gr.Button("run") | |
shell_output = gr.Textbox(label="output") | |
shell_button.click( | |
shell, | |
inputs=[ | |
shell_text, | |
], | |
outputs=[ | |
shell_output | |
], | |
) | |
launch = partial( | |
blocks.queue().launch, | |
share=False if platform.system() == "Windows" else False, | |
server_name="127.0.0.1" if platform.system() == "Windows" else "0.0.0.0", | |
server_port=7860, | |
) | |
anyio.run( | |
launch, | |
backend="asyncio" | |
) | |
return | |
if __name__ == "__main__": | |
main() | |