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
2023-07-26 22:06:25 +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 )
2023-07-26 22:06:25 +03:00
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 ( )
2023-07-01 08:57:57 +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 " )
2023-07-06 20:17:29 +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 " )
2023-06-16 10:49:55 +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 " )
2023-05-16 04:38:23 +03:00
2023-08-03 04:46:25 +03:00
parser . add_argument ( " --model_dir " , type = str , default = " model_dir " , help = " path to model files " )
2023-06-16 10:49:55 +03:00
parser . add_argument ( " --sample_mode " , type = str , default = " production " , help = " rvc_sample_mode " )
2023-04-27 17:38:25 +03:00
2023-08-03 04:46:25 +03:00
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) " )
2024-02-28 17:08:49 +03:00
parser . add_argument ( " --whisper_tiny " , type = str , default = " pretrain/whisper_tiny.pt " , help = " path to hubert_soft model(pytorch) " )
2023-08-03 04:46:25 +03:00
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 " )
2023-08-26 07:48:03 +03:00
parser . add_argument ( " --rmvpe_onnx " , type = str , default = " pretrain/rmvpe.onnx " , help = " path to rmvpe onnx " )
2023-01-17 02:29:57 +03:00
2024-03-17 01:11:16 +03:00
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. " )
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 :
2023-07-26 22:06:25 +03:00
message = f " { message } "
2023-01-15 11:59:30 +03:00
elif level == 1 :
2023-07-26 22:06:25 +03:00
message = f " { message } "
2023-01-15 11:59:30 +03:00
elif level == 2 :
2023-07-26 22:06:25 +03:00
message = f " { message } "
2023-01-15 11:59:30 +03:00
else :
2023-07-26 22:06:25 +03:00
message = f " { message } "
2022-12-31 10:02:53 +03:00
else :
2023-01-15 11:59:30 +03:00
if level == 0 :
2023-07-26 22:06:25 +03:00
message = f " \033 [17m { message } \033 [0m "
2023-01-15 11:59:30 +03:00
elif level == 1 :
2023-07-26 22:06:25 +03:00
message = f " \033 [34m { message } \033 [0m "
2023-01-15 11:59:30 +03:00
elif level == 2 :
2023-07-26 22:06:25 +03:00
message = f " \033 [32m { message } \033 [0m "
2023-01-15 11:59:30 +03:00
else :
2023-07-26 22:06:25 +03:00
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 ,
2023-07-06 20:17:29 +03:00
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-03-17 01:11:16 +03:00
def localServer ( logLevel : str = " critical " , key_path : str | None = None , cert_path : str | None = None ) :
2023-07-01 08:57:57 +03:00
try :
uvicorn . run (
f " { os . path . basename ( __file__ ) [ : - 3 ] } :app_socketio " ,
2024-03-17 01:11:16 +03:00
host = HOST ,
2023-07-01 08:57:57 +03:00
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 ,
2023-07-01 08:57:57 +03:00
log_level = logLevel ,
)
except Exception as e :
2023-07-26 22:06:25 +03:00
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 " :
2023-05-12 01:47:57 +03:00
mp . freeze_support ( )
2023-05-03 16:36:59 +03:00
voiceChangerManager = VoiceChangerManager . get_instance ( voiceChangerParams )
2024-03-17 01:11:16 +03:00
app_fastapi = MMVC_Rest . get_instance ( voiceChangerManager , voiceChangerParams , PORT , args . allowed_origins )
2023-03-14 04:53:34 +03:00
app_socketio = MMVC_SocketIOApp . get_instance ( app_fastapi , voiceChangerManager )
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
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
2023-07-26 22:06:25 +03:00
logger . debug ( args )
2023-07-26 11:04:55 +03:00
2023-07-06 20:17:29 +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 :
2023-07-26 22:06:25 +03:00
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 )
2023-06-16 10:49:55 +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)
printMessage ( " In many cases, it will launch when you access any of the following URLs. " , level = 2 )
2023-04-18 21:35:04 +03:00
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 :
2023-07-06 20:17:29 +03:00
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 サーバ起動
2023-07-01 08:57:57 +03:00
try :
2024-03-17 01:11:16 +03:00
localServer ( args . logLevel , key_path , cert_path )
2023-07-01 08:57:57 +03:00
except Exception as e :
2023-07-26 22:06:25 +03:00
logger . error ( f " [Voice Changer] Web Server(https) Launch Exception, { e } " )
2023-07-01 08:57:57 +03:00
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-03-17 01:11:16 +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 ( )
2023-07-27 09:45:54 +03:00
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-03-17 01:11:16 +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 ( )
2023-07-27 09:45:54 +03:00
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 } " )