-
Notifications
You must be signed in to change notification settings - Fork 6
/
character.py
157 lines (141 loc) · 6.04 KB
/
character.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
"""キャラクター情報機能を提供する API Router"""
from typing import Annotated
from fastapi import APIRouter, Depends, HTTPException, Query, Request
from fastapi.responses import FileResponse
from pydantic.json_schema import SkipJsonSchema
from voicevox_engine.aivm_manager import AivmManager
from voicevox_engine.metas.Metas import Speaker, SpeakerInfo
from voicevox_engine.metas.MetasStore import Character, ResourceFormat
from voicevox_engine.resource_manager import ResourceManager, ResourceManagerError
RESOURCE_ENDPOINT = "_resources"
async def _get_resource_baseurl(request: Request) -> str:
return f"{request.url.scheme}://{request.url.netloc}/{RESOURCE_ENDPOINT}"
def _characters_to_speakers(characters: list[Character]) -> list[Speaker]:
"""キャラクターのリストを `Speaker` のリストへキャストする。"""
return list(
map(
lambda character: Speaker(
name=character.name,
speaker_uuid=character.uuid,
styles=character.talk_styles + character.sing_styles,
version=character.version,
supported_features=character.supported_features,
),
characters,
)
)
def generate_character_router(
resource_manager: ResourceManager,
aivm_manager: AivmManager,
) -> APIRouter:
"""キャラクター情報 API Router を生成する"""
router = APIRouter(tags=["話者情報"])
@router.get(
"/speakers",
summary="話者情報の一覧を取得する",
)
def speakers(
core_version: Annotated[
str | SkipJsonSchema[None],
Query(description="AivisSpeech Engine ではサポートされていないパラメータです (常に無視されます) 。"),
] = None, # fmt: skip # noqa
) -> list[Speaker]:
"""話者情報の一覧を返します。"""
# AivisSpeech Engine では常に AivmManager から Speaker を取得する
return aivm_manager.get_speakers()
"""
characters = metas_store.talk_characters(core_version)
return _characters_to_speakers(characters)
"""
@router.get(
"/speaker_info",
summary="UUID で指定された話者の情報を取得する",
)
def speaker_info(
resource_baseurl: Annotated[str, Depends(_get_resource_baseurl)],
speaker_uuid: str,
resource_format: ResourceFormat = "base64",
core_version: Annotated[
str | SkipJsonSchema[None],
Query(description="AivisSpeech Engine ではサポートされていないパラメータです (常に無視されます) 。"),
] = None, # fmt: skip # noqa
) -> SpeakerInfo:
"""
UUID で指定された話者の情報を返します。
画像や音声は resource_format で指定した形式で返されます。
"""
# AivisSpeech Engine では常に AivmManager から SpeakerInfo を取得する
return aivm_manager.get_speaker_info(speaker_uuid)
"""
return metas_store.character_info(
character_uuid=speaker_uuid,
talk_or_sing="talk",
core_version=core_version,
resource_baseurl=resource_baseurl,
resource_format=resource_format,
)
"""
@router.get(
"/singers",
summary="AivisSpeech Engine ではサポートされていない API です (常に 501 Not Implemented を返します)",
)
def singers(
core_version: Annotated[
str | SkipJsonSchema[None],
Query(description="AivisSpeech Engine ではサポートされていないパラメータです (常に無視されます) 。"),
] = None, # fmt: skip # noqa
) -> list[Speaker]:
# """歌えるキャラクターの情報の一覧を返します。"""
raise HTTPException(
status_code=501,
detail="Singers is not supported in AivisSpeech Engine.",
)
"""
characters = metas_store.sing_characters(core_version)
return _characters_to_speakers(characters)
"""
@router.get(
"/singer_info",
summary="AivisSpeech Engine ではサポートされていない API です (常に 501 Not Implemented を返します)",
)
def singer_info(
resource_baseurl: Annotated[str, Depends(_get_resource_baseurl)],
speaker_uuid: str,
resource_format: ResourceFormat = "base64",
core_version: Annotated[
str | SkipJsonSchema[None],
Query(description="AivisSpeech Engine ではサポートされていないパラメータです (常に無視されます) 。"),
] = None, # fmt: skip # noqa
) -> SpeakerInfo:
# """
# UUID で指定された歌えるキャラクターの情報を返します。
# 画像や音声はresource_formatで指定した形式で返されます。
# """
raise HTTPException(
status_code=501,
detail="Singer info is not supported in AivisSpeech Engine.",
)
"""
return metas_store.character_info(
character_uuid=speaker_uuid,
talk_or_sing="sing",
core_version=core_version,
resource_baseurl=resource_baseurl,
resource_format=resource_format,
)
"""
# リソースはAPIとしてアクセスするものではないことを表明するためOpenAPIスキーマーから除外する
@router.get(f"/{RESOURCE_ENDPOINT}/{{resource_hash}}", include_in_schema=False)
async def resources(resource_hash: str) -> FileResponse:
"""
ResourceManagerから発行されたハッシュ値に対応するリソースファイルを返す
"""
try:
resource_path = resource_manager.resource_path(resource_hash)
except ResourceManagerError:
raise HTTPException(status_code=404)
return FileResponse(
resource_path,
headers={"Cache-Control": "max-age=2592000"}, # 30日
)
return router