voice-changer/server/MMVCServerSIO.py

389 lines
12 KiB
Python
Raw Normal View History

2023-01-28 05:51:56 +03:00
import sys
2022-12-31 10:02:53 +03:00
from distutils.util import strtobool
2023-01-28 09:07:54 +03:00
from datetime import datetime
import socket
import platform
import os
import argparse
2023-06-16 10:49:55 +03:00
from Exceptions import WeightDownladException
2023-06-17 09:35:43 +03:00
from downloader.SampleDownloader import downloadInitialSamples
from downloader.WeightDownloader import downloadWeight
2023-08-06 01:09:32 +03:00
from voice_changer.VoiceChangerParamsManager import VoiceChangerParamsManager
2023-05-03 16:36:59 +03:00
2023-04-27 17:38:25 +03:00
from voice_changer.utils.VoiceChangerParams import VoiceChangerParams
2023-01-28 09:07:54 +03:00
import uvicorn
from mods.ssl import create_self_signed_cert
from voice_changer.VoiceChangerManager import VoiceChangerManager
from sio.MMVC_SocketIOApp import MMVC_SocketIOApp
from restapi.MMVC_Rest import MMVC_Rest
2023-05-16 04:38:23 +03:00
from const import (
NATIVE_CLIENT_FILE_MAC,
NATIVE_CLIENT_FILE_WIN,
SSL_KEY_DIR,
)
2023-01-28 09:07:54 +03:00
import subprocess
import multiprocessing as mp
2023-08-14 05:08:31 +03:00
from mods.log_control import VoiceChangaerLogger
2023-04-28 07:49:40 +03:00
2023-08-14 05:08:31 +03:00
if __name__ == "__main__":
VoiceChangaerLogger.get_instance().initialize(initialize=True)
else:
VoiceChangaerLogger.get_instance().initialize(initialize=False)
logger = VoiceChangaerLogger.get_instance().getLogger()
logger.debug(f"---------------- Booting PHASE :{__name__} -----------------")
2022-12-31 10:02:53 +03:00
2022-12-31 12:06:57 +03:00
2022-12-31 10:02:53 +03:00
def setupArgParser():
parser = argparse.ArgumentParser()
2024-07-01 18:49:12 +03:00
parser.add_argument(
"--logLevel",
type=str,
default="error",
help="Log level info|critical|error. (default: error)",
)
2023-01-14 10:51:44 +03:00
parser.add_argument("-p", type=int, default=18888, help="port")
2023-04-27 17:38:25 +03:00
parser.add_argument("--https", type=strtobool, default=False, help="use https")
2024-07-01 18:49:12 +03:00
parser.add_argument(
"--test_connect",
type=str,
default="8.8.8.8",
help="test connect to detect ip in https mode. default 8.8.8.8",
)
parser.add_argument(
"--httpsKey", type=str, default="ssl.key", help="path for the key of https"
)
parser.add_argument(
"--httpsCert", type=str, default="ssl.cert", help="path for the cert of https"
)
parser.add_argument(
"--httpsSelfSigned",
type=strtobool,
default=True,
help="generate self-signed certificate",
)
parser.add_argument(
"--model_dir", type=str, default="model_dir", help="path to model files"
)
parser.add_argument(
"--sample_mode", type=str, default="production", help="rvc_sample_mode"
)
parser.add_argument(
"--content_vec_500",
type=str,
default="pretrain/checkpoint_best_legacy_500.pt",
help="path to content_vec_500 model(pytorch)",
)
parser.add_argument(
"--content_vec_500_onnx",
type=str,
default="pretrain/content_vec_500.onnx",
help="path to content_vec_500 model(onnx)",
)
parser.add_argument(
"--content_vec_500_onnx_on",
type=strtobool,
default=True,
help="use or not onnx for content_vec_500",
)
parser.add_argument(
"--hubert_base",
type=str,
default="pretrain/hubert_base.pt",
help="path to hubert_base model(pytorch)",
)
parser.add_argument(
"--hubert_base_jp",
type=str,
default="pretrain/rinna_hubert_base_jp.pt",
help="path to hubert_base_jp model(pytorch)",
)
parser.add_argument(
"--hubert_soft",
type=str,
default="pretrain/hubert/hubert-soft-0d54a1f4.pt",
help="path to hubert_soft model(pytorch)",
)
parser.add_argument(
"--whisper_tiny",
type=str,
default="pretrain/whisper_tiny.pt",
help="path to hubert_soft model(pytorch)",
)
parser.add_argument(
"--nsf_hifigan",
type=str,
default="pretrain/nsf_hifigan/model",
help="path to nsf_hifigan model(pytorch)",
)
parser.add_argument(
"--crepe_onnx_full",
type=str,
default="pretrain/crepe_onnx_full.onnx",
help="path to crepe_onnx_full",
)
parser.add_argument(
"--crepe_onnx_tiny",
type=str,
default="pretrain/crepe_onnx_tiny.onnx",
help="path to crepe_onnx_tiny",
)
parser.add_argument(
"--rmvpe", type=str, default="pretrain/rmvpe.pt", help="path to rmvpe"
)
parser.add_argument(
"--rmvpe_onnx",
type=str,
default="pretrain/rmvpe.onnx",
help="path to rmvpe onnx",
)
parser.add_argument(
"--host",
type=str,
default="127.0.0.1",
help="IP address of the network interface to listen for HTTP connections. Specify 0.0.0.0 to listen on all interfaces.",
)
parser.add_argument(
"--allowed-origins",
action="append",
default=[],
help="List of URLs to allow connection from, i.e. https://example.com. Allows http(s)://127.0.0.1:{port} and http(s)://localhost:{port} by default.",
)
2024-03-17 01:11:16 +03:00
2022-12-31 10:02:53 +03:00
return parser
def printMessage(message, level=0):
2023-01-15 11:59:30 +03:00
pf = platform.system()
2023-04-27 17:38:25 +03:00
if pf == "Windows":
2023-01-15 11:59:30 +03:00
if level == 0:
message = f"{message}"
2023-01-15 11:59:30 +03:00
elif level == 1:
message = f" {message}"
2023-01-15 11:59:30 +03:00
elif level == 2:
message = f" {message}"
2023-01-15 11:59:30 +03:00
else:
message = f" {message}"
2022-12-31 10:02:53 +03:00
else:
2023-01-15 11:59:30 +03:00
if level == 0:
message = f"\033[17m{message}\033[0m"
2023-01-15 11:59:30 +03:00
elif level == 1:
message = f"\033[34m {message}\033[0m"
2023-01-15 11:59:30 +03:00
elif level == 2:
message = f"\033[32m {message}\033[0m"
2023-01-15 11:59:30 +03:00
else:
message = f"\033[47m {message}\033[0m"
logger.info(message)
2022-12-31 10:02:53 +03:00
2023-01-28 05:51:56 +03:00
2022-12-31 10:02:53 +03:00
parser = setupArgParser()
2023-01-28 05:51:56 +03:00
args, unknown = parser.parse_known_args()
2023-06-16 10:49:55 +03:00
voiceChangerParams = VoiceChangerParams(
model_dir=args.model_dir,
content_vec_500=args.content_vec_500,
content_vec_500_onnx=args.content_vec_500_onnx,
content_vec_500_onnx_on=args.content_vec_500_onnx_on,
hubert_base=args.hubert_base,
hubert_base_jp=args.hubert_base_jp,
hubert_soft=args.hubert_soft,
nsf_hifigan=args.nsf_hifigan,
crepe_onnx_full=args.crepe_onnx_full,
crepe_onnx_tiny=args.crepe_onnx_tiny,
2023-07-15 03:17:19 +03:00
rmvpe=args.rmvpe,
2023-08-26 07:48:03 +03:00
rmvpe_onnx=args.rmvpe_onnx,
2023-06-16 10:49:55 +03:00
sample_mode=args.sample_mode,
2024-02-28 17:08:49 +03:00
whisper_tiny=args.whisper_tiny,
2023-06-16 10:49:55 +03:00
)
2023-08-06 01:09:32 +03:00
vcparams = VoiceChangerParamsManager.get_instance()
vcparams.setParams(voiceChangerParams)
2022-12-31 10:02:53 +03:00
2023-03-14 04:53:34 +03:00
printMessage(f"Booting PHASE :{__name__}", level=2)
2024-03-17 01:11:16 +03:00
HOST = args.host
2023-01-14 03:40:08 +03:00
PORT = args.p
2024-07-01 18:49:12 +03:00
def localServer(
logLevel: str = "critical",
key_path: str | None = None,
cert_path: str | None = None,
):
try:
uvicorn.run(
f"{os.path.basename(__file__)[:-3]}:app_socketio",
2024-03-17 01:11:16 +03:00
host=HOST,
port=int(PORT),
reload=False if hasattr(sys, "_MEIPASS") else True,
2024-03-17 01:11:16 +03:00
ssl_keyfile=key_path,
ssl_certfile=cert_path,
log_level=logLevel,
)
except Exception as e:
logger.error(f"[Voice Changer] Web Server Launch Exception, {e}")
2023-01-28 05:51:56 +03:00
2023-04-27 17:38:25 +03:00
if __name__ == "MMVCServerSIO":
mp.freeze_support()
2023-05-03 16:36:59 +03:00
voiceChangerManager = VoiceChangerManager.get_instance(voiceChangerParams)
2024-07-01 18:49:12 +03:00
app_fastapi = MMVC_Rest.get_instance(
voiceChangerManager, voiceChangerParams, args.allowed_origins, PORT
)
app_socketio = MMVC_SocketIOApp.get_instance(
app_fastapi, voiceChangerManager, args.allowed_origins, PORT
)
2022-12-31 10:02:53 +03:00
2023-04-27 17:38:25 +03:00
if __name__ == "__mp_main__":
2023-08-04 21:02:43 +03:00
# printMessage("サーバプロセスを起動しています。", level=2)
2023-08-03 22:39:17 +03:00
printMessage("The server process is starting up.", level=2)
2022-12-31 10:02:53 +03:00
2024-07-01 18:49:12 +03:00
2023-04-27 17:38:25 +03:00
if __name__ == "__main__":
2023-01-28 08:01:23 +03:00
mp.freeze_support()
2023-01-28 05:51:56 +03:00
logger.debug(args)
2023-07-26 11:04:55 +03:00
printMessage(f"PYTHON:{sys.version}", level=2)
2023-08-03 22:39:17 +03:00
# printMessage("Voice Changerを起動しています。", level=2)
printMessage("Activating the Voice Changer.", level=2)
2023-06-16 10:49:55 +03:00
# ダウンロード(Weight)
try:
downloadWeight(voiceChangerParams)
except WeightDownladException:
2023-08-03 22:39:17 +03:00
# printMessage("RVC用のモデルファイルのダウンロードに失敗しました。", level=2)
2023-06-16 10:49:55 +03:00
printMessage("failed to download weight for rvc", level=2)
2023-05-09 16:40:21 +03:00
2023-06-16 10:49:55 +03:00
# ダウンロード(Sample)
2023-05-17 20:51:40 +03:00
try:
2023-06-16 10:49:55 +03:00
downloadInitialSamples(args.sample_mode, args.model_dir)
2023-05-17 20:51:40 +03:00
except Exception as e:
printMessage(f"[Voice Changer] loading sample failed {e}", level=2)
2023-05-17 20:51:40 +03:00
2023-06-16 10:49:55 +03:00
# PORT = args.p
2022-12-31 10:02:53 +03:00
2023-04-18 21:35:04 +03:00
if os.getenv("EX_PORT"):
EX_PORT = os.environ["EX_PORT"]
2023-04-27 17:38:25 +03:00
printMessage(f"External_Port:{EX_PORT} Internal_Port:{PORT}", level=1)
2023-04-18 21:35:04 +03:00
else:
printMessage(f"Internal_Port:{PORT}", level=1)
if os.getenv("EX_IP"):
EX_IP = os.environ["EX_IP"]
printMessage(f"External_IP:{EX_IP}", level=1)
# HTTPS key/cert作成
if args.https and args.httpsSelfSigned == 1:
# HTTPS(おれおれ証明書生成)
os.makedirs(SSL_KEY_DIR, exist_ok=True)
key_base_name = f"{datetime.now().strftime('%Y%m%d_%H%M%S')}"
keyname = f"{key_base_name}.key"
certname = f"{key_base_name}.cert"
2023-04-27 17:38:25 +03:00
create_self_signed_cert(
certname,
keyname,
certargs={
"Country": "JP",
"State": "Tokyo",
"City": "Chuo-ku",
"Organization": "F",
"Org. Unit": "F",
},
cert_dir=SSL_KEY_DIR,
)
2023-04-18 21:35:04 +03:00
key_path = os.path.join(SSL_KEY_DIR, keyname)
cert_path = os.path.join(SSL_KEY_DIR, certname)
2024-07-01 18:49:12 +03:00
printMessage(
f"protocol: HTTPS(self-signed), key:{key_path}, cert:{cert_path}", level=1
)
2023-01-14 12:31:20 +03:00
2023-04-18 21:35:04 +03:00
elif args.https and args.httpsSelfSigned == 0:
# HTTPS
key_path = args.httpsKey
cert_path = args.httpsCert
2023-04-27 17:38:25 +03:00
printMessage(f"protocol: HTTPS, key:{key_path}, cert:{cert_path}", level=1)
2023-04-18 21:35:04 +03:00
else:
# HTTP
2023-04-27 17:38:25 +03:00
printMessage("protocol: HTTP", level=1)
printMessage("-- ---- -- ", level=1)
2023-04-18 21:35:04 +03:00
# アドレス表示
2023-08-03 22:39:17 +03:00
printMessage("Please open the following URL in your browser.", level=2)
# printMessage("ブラウザで次のURLを開いてください.", level=2)
2023-04-18 21:35:04 +03:00
if args.https == 1:
2023-04-27 17:38:25 +03:00
printMessage("https://<IP>:<PORT>/", level=1)
2023-04-18 21:35:04 +03:00
else:
2023-04-27 17:38:25 +03:00
printMessage("http://<IP>:<PORT>/", level=1)
2023-04-18 21:35:04 +03:00
2023-08-03 22:39:17 +03:00
# printMessage("多くの場合は次のいずれかのURLにアクセスすると起動します。", level=2)
2024-07-01 18:49:12 +03:00
printMessage(
"In many cases, it will launch when you access any of the following URLs.",
level=2,
)
if (
"EX_PORT" in locals() and "EX_IP" in locals()
): # シェルスクリプト経由起動(docker)
2022-12-31 10:02:53 +03:00
if args.https == 1:
2024-03-17 01:11:16 +03:00
printMessage(f"https://localhost:{EX_PORT}/", level=1)
2023-04-18 21:35:04 +03:00
for ip in EX_IP.strip().split(" "):
printMessage(f"https://{ip}:{EX_PORT}/", level=1)
2022-12-31 10:02:53 +03:00
else:
2024-03-17 01:11:16 +03:00
printMessage(f"http://localhost:{EX_PORT}/", level=1)
2023-04-18 21:35:04 +03:00
else: # 直接python起動
if args.https == 1:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((args.test_connect, 80))
hostname = s.getsockname()[0]
2024-03-17 01:11:16 +03:00
printMessage(f"https://localhost:{PORT}/", level=1)
2023-04-18 21:35:04 +03:00
printMessage(f"https://{hostname}:{PORT}/", level=1)
2022-12-31 10:02:53 +03:00
else:
2024-03-17 01:11:16 +03:00
printMessage(f"http://localhost:{PORT}/", level=1)
2022-12-31 10:02:53 +03:00
# サーバ起動
if args.https:
# HTTPS サーバ起動
try:
2024-03-17 01:11:16 +03:00
localServer(args.logLevel, key_path, cert_path)
except Exception as e:
logger.error(f"[Voice Changer] Web Server(https) Launch Exception, {e}")
2022-12-31 10:02:53 +03:00
else:
2023-05-31 08:30:35 +03:00
p = mp.Process(name="p", target=localServer, args=(args.logLevel,))
2023-04-19 02:22:08 +03:00
p.start()
try:
2023-04-27 17:38:25 +03:00
if sys.platform.startswith("win"):
2024-07-01 18:49:12 +03:00
process = subprocess.Popen(
[
NATIVE_CLIENT_FILE_WIN,
"--disable-gpu",
"-u",
f"http://localhost:{PORT}/",
]
)
2023-04-19 02:22:08 +03:00
return_code = process.wait()
logger.info("client closed.")
2023-04-19 02:22:08 +03:00
p.terminate()
2023-04-27 17:38:25 +03:00
elif sys.platform.startswith("darwin"):
2024-07-01 18:49:12 +03:00
process = subprocess.Popen(
[
NATIVE_CLIENT_FILE_MAC,
"--disable-gpu",
"-u",
f"http://localhost:{PORT}/",
]
)
2023-04-19 02:22:08 +03:00
return_code = process.wait()
logger.info("client closed.")
2023-04-19 02:22:08 +03:00
p.terminate()
except Exception as e:
2023-08-03 04:46:25 +03:00
logger.error(f"[Voice Changer] Client Launch Exception, {e}")