voice-changer/server/MMVCServerSIO.py

251 lines
9.3 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
from dataclasses import dataclass
import misc.log_control
import socket
import platform
import os
import argparse
import uvicorn
import webbrowser
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-03-08 03:48:50 +03:00
from const import NATIVE_CLIENT_FILE_MAC, NATIVE_CLIENT_FILE_WIN, SSL_KEY_DIR, setModelType
2023-01-28 09:07:54 +03:00
import subprocess
import multiprocessing as mp
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()
parser.add_argument("-t", type=str, default="MMVC",
help="Server type. MMVC|TRAIN")
2023-01-14 10:51:44 +03:00
parser.add_argument("-p", type=int, default=18888, help="port")
2022-12-31 10:02:53 +03:00
parser.add_argument("-c", type=str, help="path for the config.json")
parser.add_argument("-m", type=str, help="path for the model file")
2023-01-07 14:07:39 +03:00
parser.add_argument("-o", type=str, help="path for the onnx model file")
2022-12-31 10:02:53 +03:00
parser.add_argument("--https", type=strtobool,
default=False, help="use https")
2022-12-31 10:02:53 +03:00
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("--colab", type=strtobool,
default=False, help="run on colab")
2023-03-08 03:48:50 +03:00
parser.add_argument("--modelType", type=str,
2023-03-10 19:56:10 +03:00
default="MMVCv15", help="model type: MMVCv13, MMVCv15, so-vits-svc-40v2")
2023-01-17 02:29:57 +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()
if pf == 'Windows':
if level == 0:
print(f"{message}")
elif level == 1:
print(f" {message}")
elif level == 2:
print(f" {message}")
else:
print(f" {message}")
2022-12-31 10:02:53 +03:00
else:
2023-01-15 11:59:30 +03:00
if level == 0:
print(f"\033[17m{message}\033[0m")
elif level == 1:
print(f"\033[34m {message}\033[0m")
elif level == 2:
print(f"\033[32m {message}\033[0m")
else:
print(f"\033[47m {message}\033[0m")
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()
2022-12-31 10:02:53 +03:00
2023-01-14 03:40:08 +03:00
# printMessage(f"Phase name:{__name__}", level=2)
# thisFilename = os.path.basename(__file__)[:-3]
# if __name__ == thisFilename or args.colab == True:
2023-01-28 05:51:56 +03:00
# printMessage(f"PHASE3:{__name__}", level=2)
2023-03-08 03:48:50 +03:00
2023-01-14 03:40:08 +03:00
TYPE = args.t
PORT = args.p
CONFIG = args.c
MODEL = args.m if args.m != None else None
ONNX_MODEL = args.o if args.o != None else None
MODEL_TYPE = os.environ.get('MODEL_TYPE', None)
if MODEL_TYPE == None:
MODEL_TYPE = args.modelType
2023-03-08 03:48:50 +03:00
setModelType(MODEL_TYPE)
2023-01-14 03:40:08 +03:00
2023-01-28 05:51:56 +03:00
def localServer():
uvicorn.run(
f"{os.path.basename(__file__)[:-3]}:app_socketio",
host="0.0.0.0",
port=int(PORT),
reload=False if hasattr(sys, "_MEIPASS") else True,
log_level="warning"
)
2023-01-14 03:40:08 +03:00
if args.colab == True:
os.environ["colab"] = "True"
2023-01-28 05:51:56 +03:00
voiceChangerManager = VoiceChangerManager.get_instance()
2023-01-14 03:40:08 +03:00
if CONFIG and (MODEL or ONNX_MODEL):
voiceChangerManager.loadModel(CONFIG, MODEL, ONNX_MODEL)
app_fastapi = MMVC_Rest.get_instance(voiceChangerManager)
app_socketio = MMVC_SocketIOApp.get_instance(app_fastapi, voiceChangerManager)
2022-12-31 10:02:53 +03:00
if __name__ == '__mp_main__':
2023-01-14 12:31:20 +03:00
printMessage(f"サーバプロセスを起動しています。", level=2)
2022-12-31 10:02:53 +03:00
if __name__ == '__main__':
2023-01-28 08:01:23 +03:00
mp.freeze_support()
2023-01-28 05:51:56 +03:00
2023-01-14 12:31:20 +03:00
printMessage(f"Voice Changerを起動しています。", level=2)
2022-12-31 10:02:53 +03:00
TYPE = args.t
PORT = args.p
CONFIG = args.c
2023-01-07 18:25:21 +03:00
MODEL = args.m if args.m != None else None
2023-01-07 14:07:39 +03:00
ONNX_MODEL = args.o if args.o != None else None
2022-12-31 10:02:53 +03:00
if TYPE != "MMVC" and TYPE != "TRAIN":
print("Type(-t) should be MMVC or TRAIN")
exit(1)
2023-01-14 12:31:20 +03:00
# printMessage(f"Start MMVC SocketIO Server", level=0)
printMessage(f"-- 設定 -- ", level=1)
2023-01-07 14:07:39 +03:00
printMessage(f"CONFIG:{CONFIG}, MODEL:{MODEL} ONNX_MODEL:{ONNX_MODEL}", level=1)
2022-12-31 10:02:53 +03:00
if args.colab == False:
if os.getenv("EX_PORT"):
EX_PORT = os.environ["EX_PORT"]
printMessage(
f"External_Port:{EX_PORT} Internal_Port:{PORT}", level=1)
else:
printMessage(f"Internal_Port:{PORT}", level=1)
if os.getenv("EX_TB_PORT"):
EX_TB_PORT = os.environ["EX_TB_PORT"]
printMessage(f"External_TeonsorBord_Port:{EX_TB_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(おれおれ証明書生成)
2023-01-14 19:30:46 +03:00
os.makedirs(SSL_KEY_DIR, exist_ok=True)
2022-12-31 10:02:53 +03:00
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"
create_self_signed_cert(certname, keyname, certargs={"Country": "JP",
"State": "Tokyo",
"City": "Chuo-ku",
"Organization": "F",
2023-01-14 19:30:46 +03:00
"Org. Unit": "F"}, cert_dir=SSL_KEY_DIR)
key_path = os.path.join(SSL_KEY_DIR, keyname)
cert_path = os.path.join(SSL_KEY_DIR, certname)
2022-12-31 10:02:53 +03:00
printMessage(
f"protocol: HTTPS(self-signed), key:{key_path}, cert:{cert_path}", level=1)
elif args.https and args.httpsSelfSigned == 0:
# HTTPS
key_path = args.httpsKey
cert_path = args.httpsCert
printMessage(
f"protocol: HTTPS, key:{key_path}, cert:{cert_path}", level=1)
else:
# HTTP
printMessage(f"protocol: HTTP", level=1)
2023-01-14 12:31:20 +03:00
printMessage(f"-- ---- -- ", level=1)
2022-12-31 10:02:53 +03:00
# アドレス表示
2023-01-14 12:31:20 +03:00
printMessage(
2023-01-28 05:51:56 +03:00
f"ブラウザで次のURLを開いてください.", level=2)
2022-12-31 10:02:53 +03:00
if args.https == 1:
printMessage(
2023-01-14 12:31:20 +03:00
f"https://<IP>:<PORT>/", level=1)
2022-12-31 10:02:53 +03:00
else:
printMessage(
2023-01-14 12:31:20 +03:00
f"http://<IP>:<PORT>/", level=1)
2022-12-31 10:02:53 +03:00
if TYPE == "MMVC":
path = ""
else:
path = "trainer"
2023-01-14 12:31:20 +03:00
printMessage(f"多くの場合は次のいずれかのURLにアクセスすると起動します。", level=2)
if "EX_PORT" in locals() and "EX_IP" in locals(): # シェルスクリプト経由起動(docker)
if args.https == 1:
printMessage(f"https://localhost:{EX_PORT}/{path}", level=1)
for ip in EX_IP.strip().split(" "):
printMessage(f"https://{ip}:{EX_PORT}/{path}", level=1)
else:
printMessage(f"http://localhost:{EX_PORT}/{path}", level=1)
2023-01-28 05:51:56 +03:00
else: # 直接python起動
2023-01-14 12:31:20 +03:00
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
hostname = s.getsockname()[0]
if args.https == 1:
printMessage(f"https://localhost:{PORT}/{path}", level=1)
printMessage(f"https://{hostname}:{PORT}/{path}", level=1)
else:
printMessage(f"http://localhost:{PORT}/{path}", level=1)
2022-12-31 10:02:53 +03:00
# サーバ起動
if args.https:
# HTTPS サーバ起動
2022-12-31 19:43:46 +03:00
res = uvicorn.run(
2022-12-31 10:02:53 +03:00
f"{os.path.basename(__file__)[:-3]}:app_socketio",
host="0.0.0.0",
port=int(PORT),
2023-01-28 05:51:56 +03:00
reload=False if hasattr(sys, "_MEIPASS") else True,
2022-12-31 10:02:53 +03:00
ssl_keyfile=key_path,
ssl_certfile=cert_path,
2023-01-04 20:28:36 +03:00
# log_level="warning"
2022-12-31 10:02:53 +03:00
)
else:
# HTTP サーバ起動
if args.colab == True:
uvicorn.run(
f"{os.path.basename(__file__)[:-3]}:app_fastapi",
host="0.0.0.0",
port=int(PORT),
2022-12-31 19:58:38 +03:00
log_level="warning"
2022-12-31 10:02:53 +03:00
)
else:
2023-01-28 05:51:56 +03:00
# uvicorn.run(
# f"{os.path.basename(__file__)[:-3]}:app_socketio",
# host="0.0.0.0",
# port=int(PORT),
# reload = False if hasattr(sys, "_MEIPASS") else True,
# log_level="warning"
# )
os.environ['MODEL_TYPE'] = MODEL_TYPE
2023-01-28 05:51:56 +03:00
p = mp.Process(name="p", target=localServer)
p.start()
try:
if sys.platform.startswith('win'):
2023-01-28 08:09:00 +03:00
# process = subprocess.Popen(["voice-changer-native-client.exe", "-u", f"http://localhost:{PORT}/{path}"])
process = subprocess.Popen([NATIVE_CLIENT_FILE_WIN, "-u", f"http://localhost:{PORT}/{path}"])
2023-01-28 05:51:56 +03:00
return_code = process.wait()
2023-01-28 08:01:23 +03:00
print("client closed.")
2023-01-28 05:51:56 +03:00
p.terminate()
2023-01-28 08:01:23 +03:00
elif sys.platform.startswith('darwin'):
2023-01-28 08:09:00 +03:00
process = subprocess.Popen([NATIVE_CLIENT_FILE_MAC, "-u", f"http://localhost:{PORT}/{path}"])
2023-01-28 08:01:23 +03:00
return_code = process.wait()
print("client closed.")
p.terminate()
2023-01-28 05:51:56 +03:00
except Exception as e:
print(e)