voicevox / voicevox_engine /downloadable_library.py
2ndelement's picture
init
f1f433f
raw
history blame
3.54 kB
import base64
import json
import zipfile
from io import BytesIO
from pathlib import Path
from typing import List
from fastapi import HTTPException
from voicevox_engine.model import DownloadableLibrary
__all__ = ["LibraryManager"]
INFO_FILE = "metas.json"
class LibraryManager:
def __init__(self, library_root_dir: Path):
self.library_root_dir = library_root_dir
self.library_root_dir.mkdir(exist_ok=True)
def downloadable_libraries(self):
# == ダウンロード情報をネットワーク上から取得する場合
# url = "https://example.com/downloadable_libraries.json"
# response = requests.get(url)
# return list(map(DownloadableLibrary.parse_obj, response.json()))
# == ダウンロード情報をjsonファイルから取得する場合
# with open(
# self.root_dir / "engine_manifest_assets" / "downloadable_libraries.json",
# encoding="utf-8",
# ) as f:
# return list(map(DownloadableLibrary.parse_obj, json.load(f)))
# ダミーとして、speaker_infoのアセットを読み込む
with open(
"./engine_manifest_assets/downloadable_libraries.json",
encoding="utf-8",
) as f:
libraries = json.load(f)
speaker_info = libraries[0]["speakers"][0]["speaker_info"]
mock_root_dir = Path("./speaker_info/7ffcb7ce-00ec-4bdc-82cd-45a8889e43ff")
speaker_info["policy"] = (mock_root_dir / "policy.md").read_text()
speaker_info["portrait"] = base64.b64encode(
(mock_root_dir / "portrait.png").read_bytes()
)
for style_info in speaker_info["style_infos"]:
style_id = style_info["id"]
style_info["icon"] = base64.b64encode(
(mock_root_dir / "icons" / f"{style_id}.png").read_bytes()
)
style_info["voice_samples"] = [
base64.b64encode(
(
mock_root_dir / "voice_samples" / f"{style_id}_{i:0>3}.wav"
).read_bytes()
)
for i in range(1, 4)
]
return list(map(DownloadableLibrary.parse_obj, libraries))
def installed_libraries(self) -> List[DownloadableLibrary]:
library = []
for library_dir in self.library_root_dir.iterdir():
if library_dir.is_dir():
with open(library_dir / INFO_FILE, encoding="utf-8") as f:
library.append(json.load(f))
return library
def install_library(self, library_id: str, file: BytesIO):
for downloadable_library in self.downloadable_libraries():
if downloadable_library.uuid == library_id:
library_info = downloadable_library.dict()
break
else:
raise HTTPException(status_code=404, detail="指定された音声ライブラリが見つかりません。")
library_dir = self.library_root_dir / library_id
library_dir.mkdir(exist_ok=True)
with open(library_dir / INFO_FILE, "w", encoding="utf-8") as f:
json.dump(library_info, f, indent=4, ensure_ascii=False)
with zipfile.ZipFile(file) as zf:
if zf.testzip() is not None:
raise HTTPException(status_code=422, detail="不正なZIPファイルです。")
zf.extractall(library_dir)
return library_dir