diff --git a/README.md b/README.md index b5c131ce..73be45b8 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ AIを使ったリアルタイムボイスチェンジャー[MMVC](https://github - CPU/GPU切り替え - リアルタイム/ニアリアルタイム声質変換 +## 使用方法 + 使用方法等は[wiki](https://github.com/w-okada/voice-changer/wiki)をご参照ください。 ## MMVCのトレーニング用音声データと、実行時の音声入力の考え方 @@ -21,7 +23,7 @@ AIを使ったリアルタイムボイスチェンジャー[MMVC](https://github ## 関連技術 -本レポジトリでは、関連するボイスチェンジャとしてsoft-vcに注目しています。soft-vcにもリアルタイムでボイスチェンジできるようにしています。下記の「Docker不要な実行方法」のセクションからご利用ください。 +本レポジトリでは、関連するボイスチェンジャとして[soft-vc](https://github.com/bshall/soft-vc)に注目しています。soft-vcにもリアルタイムでボイスチェンジできるようにしています。下記の「Docker不要な実行方法」のセクションからご利用ください。 # Docker不要な実行方法 diff --git a/demo/SoftVcServerSIO.py b/demo/SoftVcServerSIO.py index 06f1e920..86c85def 100755 --- a/demo/SoftVcServerSIO.py +++ b/demo/SoftVcServerSIO.py @@ -1,8 +1,9 @@ import eventlet import socketio -import sys, math, base64 +import sys,os , math, struct, argparse +from distutils.util import strtobool from datetime import datetime -import struct +from OpenSSL import SSL, crypto import torch, torchaudio import numpy as np @@ -80,37 +81,95 @@ class MyCustomNamespace(socketio.Namespace): int_size = 2**(16 - 1) - 1 arr = (arr * int_size).astype(np.int16) - # write("logs/converted_data.wav", 24000, arr) - # changedVoiceBase64 = base64.b64encode(arr).decode('utf-8') - - # data = { - # "gpu":gpu, - # "srcId":srcId, - # "dstId":dstId, - # "timestamp":timestamp, - # "changedVoiceBase64":changedVoiceBase64 - # } - - # audio1 = audio1.astype(np.int16) bin = struct.pack('<%sh'%len(arr), *arr) - # print("return timestamp", timestamp) self.emit('response',[timestamp, bin]) def on_disconnect(self, sid): - # print('[{}] disconnect'.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) pass; +def setupArgParser(): + parser = argparse.ArgumentParser() + parser.add_argument("-p", type=int, required=True, help="port") + parser.add_argument("--https", type=strtobool, default=False, help="use https") + 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") + return parser + +def create_self_signed_cert(certfile, keyfile, certargs, cert_dir="."): + C_F = os.path.join(cert_dir, certfile) + K_F = os.path.join(cert_dir, keyfile) + if not os.path.exists(C_F) or not os.path.exists(K_F): + k = crypto.PKey() + k.generate_key(crypto.TYPE_RSA, 2048) + cert = crypto.X509() + cert.get_subject().C = certargs["Country"] + cert.get_subject().ST = certargs["State"] + cert.get_subject().L = certargs["City"] + cert.get_subject().O = certargs["Organization"] + cert.get_subject().OU = certargs["Org. Unit"] + cert.get_subject().CN = 'Example' + cert.set_serial_number(1000) + cert.gmtime_adj_notBefore(0) + cert.gmtime_adj_notAfter(315360000) + cert.set_issuer(cert.get_subject()) + cert.set_pubkey(k) + cert.sign(k, 'sha1') + open(C_F, "wb").write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert)) + open(K_F, "wb").write(crypto.dump_privatekey(crypto.FILETYPE_PEM, k)) + if __name__ == '__main__': - args = sys.argv - PORT = args[1] + parser = setupArgParser() + args = parser.parse_args() + PORT = args.p print(f"start... PORT:{PORT}") + + if args.https and args.httpsSelfSigned == 1: + # HTTPS(おれおれ証明書生成) + os.makedirs("./key", 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" + create_self_signed_cert(certname, keyname, certargs= + {"Country": "JP", + "State": "Tokyo", + "City": "Chuo-ku", + "Organization": "F", + "Org. Unit": "F"}, cert_dir="./key") + key_path = os.path.join("./key", keyname) + cert_path = os.path.join("./key", certname) + print(f"protocol: HTTPS(self-signed), key:{key_path}, cert:{cert_path}") + elif args.https and args.httpsSelfSigned == 0: + # HTTPS + key_path = args.httpsKey + cert_path = args.httpsCert + print(f"protocol: HTTPS, key:{key_path}, cert:{cert_path}") + else: + # HTTP + print("protocol: HTTP") + + # SocketIOセットアップ sio = socketio.Server(cors_allowed_origins='*') sio.register_namespace(MyCustomNamespace('/test')) app = socketio.WSGIApp(sio,static_files={ '': '../frontend/dist', '/': '../frontend/dist/index.html', }) - eventlet.wsgi.server(eventlet.listen(('0.0.0.0',int(PORT))), app) - \ No newline at end of file + + if args.https: + # HTTPS サーバ起動 + sslWrapper = eventlet.wrap_ssl( + eventlet.listen(('0.0.0.0',int(PORT))), + certfile=cert_path, + keyfile=key_path, + # server_side=True + ) + eventlet.wsgi.server(sslWrapper, app) + else: + # HTTP サーバ起動 + eventlet.wsgi.server(eventlet.listen(('0.0.0.0',int(PORT))), app) + + + diff --git a/demo/mod/monotonic_align/monotonic_align/core.cp39-win_amd64.pyd b/demo/mod/monotonic_align/monotonic_align/core.cp39-win_amd64.pyd new file mode 100755 index 00000000..9e9bacb7 Binary files /dev/null and b/demo/mod/monotonic_align/monotonic_align/core.cp39-win_amd64.pyd differ diff --git a/demo/serverSIO.py b/demo/serverSIO.py index 14a91d19..5209c93e 100755 --- a/demo/serverSIO.py +++ b/demo/serverSIO.py @@ -1,8 +1,9 @@ import eventlet import socketio -import sys +import sys, os, struct, argparse +from distutils.util import strtobool from datetime import datetime -import struct +from OpenSSL import SSL, crypto import torch import numpy as np @@ -77,19 +78,91 @@ class MyCustomNamespace(socketio.Namespace): # print('[{}] disconnect'.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) pass; +def setupArgParser(): + parser = argparse.ArgumentParser() + parser.add_argument("-p", type=int, required=True, help="port") + parser.add_argument("-c", type=str, required=True, help="path for the config.json") + parser.add_argument("-m", type=str, required=True, help="path for the model file") + parser.add_argument("--https", type=strtobool, default=False, help="use https") + 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") + return parser + +def create_self_signed_cert(certfile, keyfile, certargs, cert_dir="."): + C_F = os.path.join(cert_dir, certfile) + K_F = os.path.join(cert_dir, keyfile) + if not os.path.exists(C_F) or not os.path.exists(K_F): + k = crypto.PKey() + k.generate_key(crypto.TYPE_RSA, 2048) + cert = crypto.X509() + cert.get_subject().C = certargs["Country"] + cert.get_subject().ST = certargs["State"] + cert.get_subject().L = certargs["City"] + cert.get_subject().O = certargs["Organization"] + cert.get_subject().OU = certargs["Org. Unit"] + cert.get_subject().CN = 'Example' + cert.set_serial_number(1000) + cert.gmtime_adj_notBefore(0) + cert.gmtime_adj_notAfter(315360000) + cert.set_issuer(cert.get_subject()) + cert.set_pubkey(k) + cert.sign(k, 'sha1') + open(C_F, "wb").write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert)) + open(K_F, "wb").write(crypto.dump_privatekey(crypto.FILETYPE_PEM, k)) + if __name__ == '__main__': - args = sys.argv - PORT = args[1] - CONFIG = args[2] - MODEL = args[3] - print(f"start... PORT:{PORT}, CONFIG:{CONFIG}, MODEL:{MODEL}") - # sio = socketio.Server(cors_allowed_origins='http://localhost:8080') + parser = setupArgParser() + args = parser.parse_args() + PORT = args.p + CONFIG = args.c + MODEL = args.m + print(f"start... PORT:{PORT}, CONFIG:{CONFIG}, MODEL:{MODEL}") + + if args.https and args.httpsSelfSigned == 1: + # HTTPS(おれおれ証明書生成) + os.makedirs("./key", 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" + create_self_signed_cert(certname, keyname, certargs= + {"Country": "JP", + "State": "Tokyo", + "City": "Chuo-ku", + "Organization": "F", + "Org. Unit": "F"}, cert_dir="./key") + key_path = os.path.join("./key", keyname) + cert_path = os.path.join("./key", certname) + print(f"protocol: HTTPS(self-signed), key:{key_path}, cert:{cert_path}") + elif args.https and args.httpsSelfSigned == 0: + # HTTPS + key_path = args.httpsKey + cert_path = args.httpsCert + print(f"protocol: HTTPS, key:{key_path}, cert:{cert_path}") + else: + # HTTP + print("protocol: HTTP") + + + # SocketIOセットアップ sio = socketio.Server(cors_allowed_origins='*') sio.register_namespace(MyCustomNamespace('/test', CONFIG, MODEL)) app = socketio.WSGIApp(sio,static_files={ '': '../frontend/dist', '/': '../frontend/dist/index.html', }) - eventlet.wsgi.server(eventlet.listen(('0.0.0.0',int(PORT))), app) - \ No newline at end of file + + if args.https: + # HTTPS サーバ起動 + sslWrapper = eventlet.wrap_ssl( + eventlet.listen(('0.0.0.0',int(PORT))), + certfile=cert_path, + keyfile=key_path, + # server_side=True + ) + eventlet.wsgi.server(sslWrapper, app) + else: + # HTTP サーバ起動 + eventlet.wsgi.server(eventlet.listen(('0.0.0.0',int(PORT))), app) + diff --git a/demo/setup.sh b/demo/setup.sh index 8c1c730a..9e2a4983 100755 --- a/demo/setup.sh +++ b/demo/setup.sh @@ -29,13 +29,13 @@ fi # 起動 if [ "${TYPE}" = "SOFT_VC" ] ; then echo "SOFT_VCを起動します" - python3 SoftVcServerSIO.py 8080 + python3 SoftVcServerSIO.py -p 8080 --https True --httpsSelfSigned True elif [ "${TYPE}" = "SOFT_VC_FAST_API" ] ; then echo "SOFT_VC_FAST_APIを起動します" python3 SoftVcServerFastAPI.py 8080 docker else echo "MMVCを起動します" - python3 serverSIO.py 8080 $CONFIG $MODEL + python3 serverSIO.py -p 8080 -c $CONFIG -m $MODEL --https True --httpsSelfSigned True fi diff --git a/start2.sh b/start2.sh index d70cd012..76b4492a 100644 --- a/start2.sh +++ b/start2.sh @@ -2,7 +2,7 @@ # 参考:https://programwiz.org/2022/03/22/how-to-write-shell-script-for-option-parsing/ -DOCKER_IMAGE=dannadori/voice-changer:20220919_073405 +DOCKER_IMAGE=dannadori/voice-changer:20220923_143426 TENSORBOARD_PORT=6006 VOICE_CHANGER_PORT=8080 diff --git a/trainer/Dockerfile b/trainer/Dockerfile index 0a857d95..3c06beed 100644 --- a/trainer/Dockerfile +++ b/trainer/Dockerfile @@ -1,4 +1,4 @@ -FROM dannadori/voice-changer-internal:20220919_073236 as front +FROM dannadori/voice-changer-internal:20220923_142757 as front FROM debian:bullseye-slim as base ARG DEBIAN_FRONTEND=noninteractive