2023-12-19 09:41:52 +08:00
# server.py
2024-04-14 19:08:25 +08:00
from flask import Flask , render_template , send_from_directory , request , jsonify
2023-12-19 09:41:52 +08:00
from flask_sockets import Sockets
import base64
import time
import json
import gevent
from gevent import pywsgi
from geventwebsocket . handler import WebSocketHandler
import os
import re
import numpy as np
2024-04-14 19:08:25 +08:00
from threading import Thread , Event
2023-12-28 13:11:18 +08:00
import multiprocessing
2023-12-19 09:41:52 +08:00
2024-04-14 19:08:25 +08:00
from aiohttp import web
2024-04-27 18:08:57 +08:00
import aiohttp
2024-05-12 10:30:47 +08:00
import aiohttp_cors
2024-04-14 19:08:25 +08:00
from aiortc import RTCPeerConnection , RTCSessionDescription
2024-09-08 22:53:37 +08:00
from aiortc . rtcrtpsender import RTCRtpSender
2024-04-14 19:08:25 +08:00
from webrtc import HumanPlayer
2023-12-19 09:41:52 +08:00
import argparse
import shutil
import asyncio
2024-10-05 17:25:01 +08:00
import string
2024-02-25 18:54:40 +08:00
2023-12-19 09:41:52 +08:00
app = Flask ( __name__ )
sockets = Sockets ( app )
2024-07-17 08:21:31 +08:00
nerfreals = [ ]
statreals = [ ]
2024-02-25 18:54:40 +08:00
2023-12-19 09:41:52 +08:00
2023-12-28 13:11:18 +08:00
@sockets.route ( ' /humanecho ' )
2023-12-19 09:41:52 +08:00
def echo_socket ( ws ) :
# 获取WebSocket对象
#ws = request.environ.get('wsgi.websocket')
# 如果没有获取到,返回错误信息
if not ws :
print ( ' 未建立连接! ' )
return ' Please use WebSocket '
# 否则,循环接收和发送消息
else :
print ( ' 建立连接! ' )
while True :
message = ws . receive ( )
2024-03-23 18:15:35 +08:00
if not message or len ( message ) == 0 :
2023-12-19 09:41:52 +08:00
return ' 输入信息为空 '
else :
2024-06-02 22:25:19 +08:00
nerfreal . put_msg_txt ( message )
2024-01-27 11:13:16 +08:00
2024-02-25 18:54:40 +08:00
2024-10-05 17:25:01 +08:00
# def llm_response(message):
# from llm.LLM import LLM
# # llm = LLM().init_model('Gemini', model_path= 'gemini-pro',api_key='Your API Key', proxy_url=None)
# # llm = LLM().init_model('ChatGPT', model_path= 'gpt-3.5-turbo',api_key='Your API Key')
# llm = LLM().init_model('VllmGPT', model_path= 'THUDM/chatglm3-6b')
# response = llm.chat(message)
# print(response)
# return response
def llm_response ( message , nerfreal ) :
start = time . perf_counter ( )
from openai import OpenAI
client = OpenAI (
# 如果您没有配置环境变量, 请在此处用您的API Key进行替换
api_key = os . getenv ( " DASHSCOPE_API_KEY " ) ,
# 填写DashScope SDK的base_url
base_url = " https://dashscope.aliyuncs.com/compatible-mode/v1 " ,
)
end = time . perf_counter ( )
print ( f " llm Time init: { end - start } s " )
completion = client . chat . completions . create (
model = " qwen-plus " ,
messages = [ { ' role ' : ' system ' , ' content ' : ' You are a helpful assistant. ' } ,
{ ' role ' : ' user ' , ' content ' : message } ] ,
stream = True ,
# 通过以下设置, 在流式输出的最后一行展示token使用信息
stream_options = { " include_usage " : True }
)
result = " "
first = True
for chunk in completion :
if len ( chunk . choices ) > 0 :
#print(chunk.choices[0].delta.content)
if first :
end = time . perf_counter ( )
print ( f " llm Time to first chunk: { end - start } s " )
first = False
msg = chunk . choices [ 0 ] . delta . content
lastpos = 0
#msglist = re.split('[,.!;:,。!?]',msg)
for i , char in enumerate ( msg ) :
if char in " ,.!;:,。!?:; " :
result = result + msg [ lastpos : i + 1 ]
lastpos = i + 1
if len ( result ) > 10 :
print ( result )
nerfreal . put_msg_txt ( result )
result = " "
result = result + msg [ lastpos : ]
end = time . perf_counter ( )
print ( f " llm Time to last chunk: { end - start } s " )
nerfreal . put_msg_txt ( result )
2024-02-25 18:54:40 +08:00
2024-01-27 11:13:16 +08:00
@sockets.route ( ' /humanchat ' )
def chat_socket ( ws ) :
# 获取WebSocket对象
#ws = request.environ.get('wsgi.websocket')
# 如果没有获取到,返回错误信息
if not ws :
print ( ' 未建立连接! ' )
return ' Please use WebSocket '
# 否则,循环接收和发送消息
else :
print ( ' 建立连接! ' )
while True :
message = ws . receive ( )
if len ( message ) == 0 :
return ' 输入信息为空 '
else :
2024-01-27 19:38:13 +08:00
res = llm_response ( message )
2024-06-02 22:25:19 +08:00
nerfreal . put_msg_txt ( res )
2024-04-14 19:08:25 +08:00
#####webrtc###############################
pcs = set ( )
#@app.route('/offer', methods=['POST'])
async def offer ( request ) :
params = await request . json ( )
offer = RTCSessionDescription ( sdp = params [ " sdp " ] , type = params [ " type " ] )
2024-07-17 08:21:31 +08:00
sessionid = len ( nerfreals )
for index , value in enumerate ( statreals ) :
if value == 0 :
sessionid = index
break
if sessionid > = len ( nerfreals ) :
print ( ' reach max session ' )
return - 1
statreals [ sessionid ] = 1
2024-04-14 19:08:25 +08:00
pc = RTCPeerConnection ( )
pcs . add ( pc )
@pc.on ( " connectionstatechange " )
async def on_connectionstatechange ( ) :
print ( " Connection state is %s " % pc . connectionState )
if pc . connectionState == " failed " :
await pc . close ( )
pcs . discard ( pc )
2024-07-17 08:21:31 +08:00
statreals [ sessionid ] = 0
if pc . connectionState == " closed " :
pcs . discard ( pc )
statreals [ sessionid ] = 0
2024-04-14 19:08:25 +08:00
2024-07-17 08:21:31 +08:00
player = HumanPlayer ( nerfreals [ sessionid ] )
2024-04-14 19:08:25 +08:00
audio_sender = pc . addTrack ( player . audio )
video_sender = pc . addTrack ( player . video )
2024-09-08 22:53:37 +08:00
capabilities = RTCRtpSender . getCapabilities ( " video " )
preferences = list ( filter ( lambda x : x . name == " H264 " , capabilities . codecs ) )
preferences + = list ( filter ( lambda x : x . name == " VP8 " , capabilities . codecs ) )
preferences + = list ( filter ( lambda x : x . name == " rtx " , capabilities . codecs ) )
transceiver = pc . getTransceivers ( ) [ 1 ]
transceiver . setCodecPreferences ( preferences )
2024-04-14 19:08:25 +08:00
await pc . setRemoteDescription ( offer )
2023-12-19 09:41:52 +08:00
2024-04-14 19:08:25 +08:00
answer = await pc . createAnswer ( )
await pc . setLocalDescription ( answer )
#return jsonify({"sdp": pc.localDescription.sdp, "type": pc.localDescription.type})
return web . Response (
content_type = " application/json " ,
text = json . dumps (
2024-07-17 08:21:31 +08:00
{ " sdp " : pc . localDescription . sdp , " type " : pc . localDescription . type , " sessionid " : sessionid }
2024-04-14 19:08:25 +08:00
) ,
)
2024-05-06 08:14:06 +08:00
async def human ( request ) :
params = await request . json ( )
2024-07-17 08:21:31 +08:00
sessionid = params . get ( ' sessionid ' , 0 )
2024-06-30 09:41:31 +08:00
if params . get ( ' interrupt ' ) :
2024-07-17 08:21:31 +08:00
nerfreals [ sessionid ] . pause_talk ( )
2024-06-30 09:41:31 +08:00
2024-05-06 08:14:06 +08:00
if params [ ' type ' ] == ' echo ' :
2024-07-17 08:21:31 +08:00
nerfreals [ sessionid ] . put_msg_txt ( params [ ' text ' ] )
2024-05-06 08:14:06 +08:00
elif params [ ' type ' ] == ' chat ' :
2024-10-05 17:25:01 +08:00
res = await asyncio . get_event_loop ( ) . run_in_executor ( None , llm_response , params [ ' text ' ] , nerfreals [ sessionid ] )
#nerfreals[sessionid].put_msg_txt(res)
2024-05-06 08:14:06 +08:00
return web . Response (
content_type = " application/json " ,
text = json . dumps (
{ " code " : 0 , " data " : " ok " }
) ,
)
2024-04-14 19:08:25 +08:00
2024-09-21 10:55:30 +08:00
async def humanaudio ( request ) :
try :
form = await request . post ( )
sessionid = int ( form . get ( ' sessionid ' , 0 ) )
fileobj = form [ " file " ]
filename = fileobj . filename
filebytes = fileobj . file . read ( )
nerfreals [ sessionid ] . put_audio_file ( filebytes )
return web . Response (
content_type = " application/json " ,
text = json . dumps (
{ " code " : 0 , " msg " : " ok " }
) ,
)
except Exception as e :
return web . Response (
content_type = " application/json " ,
text = json . dumps (
{ " code " : - 1 , " msg " : " err " , " data " : " " + e . args [ 0 ] + " " }
) ,
)
2024-08-03 08:26:17 +08:00
async def set_audiotype ( request ) :
params = await request . json ( )
sessionid = params . get ( ' sessionid ' , 0 )
nerfreals [ sessionid ] . set_curr_state ( params [ ' audiotype ' ] , params [ ' reinit ' ] )
return web . Response (
content_type = " application/json " ,
text = json . dumps (
{ " code " : 0 , " data " : " ok " }
) ,
)
2024-09-01 18:37:43 +08:00
async def record ( request ) :
params = await request . json ( )
sessionid = params . get ( ' sessionid ' , 0 )
if params [ ' type ' ] == ' start_record ' :
# nerfreals[sessionid].put_msg_txt(params['text'])
2024-09-07 13:44:59 +08:00
nerfreals [ sessionid ] . start_recording ( " data/record_lasted.mp4 " )
2024-09-01 18:37:43 +08:00
elif params [ ' type ' ] == ' end_record ' :
nerfreals [ sessionid ] . stop_recording ( )
return web . Response (
content_type = " application/json " ,
text = json . dumps (
{ " code " : 0 , " data " : " ok " }
) ,
)
2024-09-17 22:11:46 +08:00
async def is_speaking ( request ) :
params = await request . json ( )
sessionid = params . get ( ' sessionid ' , 0 )
return web . Response (
content_type = " application/json " ,
text = json . dumps (
{ " code " : 0 , " data " : nerfreals [ sessionid ] . is_speaking ( ) }
) ,
)
2024-04-14 19:08:25 +08:00
async def on_shutdown ( app ) :
# close peer connections
coros = [ pc . close ( ) for pc in pcs ]
await asyncio . gather ( * coros )
pcs . clear ( )
2024-04-27 18:08:57 +08:00
async def post ( url , data ) :
try :
async with aiohttp . ClientSession ( ) as session :
async with session . post ( url , data = data ) as response :
return await response . text ( )
except aiohttp . ClientError as e :
print ( f ' Error: { e } ' )
async def run ( push_url ) :
pc = RTCPeerConnection ( )
pcs . add ( pc )
@pc.on ( " connectionstatechange " )
async def on_connectionstatechange ( ) :
print ( " Connection state is %s " % pc . connectionState )
if pc . connectionState == " failed " :
await pc . close ( )
pcs . discard ( pc )
2024-07-17 08:21:31 +08:00
player = HumanPlayer ( nerfreals [ 0 ] )
2024-04-27 18:08:57 +08:00
audio_sender = pc . addTrack ( player . audio )
video_sender = pc . addTrack ( player . video )
await pc . setLocalDescription ( await pc . createOffer ( ) )
answer = await post ( push_url , pc . localDescription . sdp )
await pc . setRemoteDescription ( RTCSessionDescription ( sdp = answer , type = ' answer ' ) )
2024-06-09 09:04:04 +08:00
##########################################
# os.environ['MKL_SERVICE_FORCE_INTEL'] = '1'
# os.environ['MULTIPROCESSING_METHOD'] = 'forkserver'
2023-12-19 09:41:52 +08:00
if __name__ == ' __main__ ' :
2024-06-09 09:04:04 +08:00
multiprocessing . set_start_method ( ' spawn ' )
2023-12-19 09:41:52 +08:00
parser = argparse . ArgumentParser ( )
parser . add_argument ( ' --pose ' , type = str , default = " data/data_kf.json " , help = " transforms.json, pose source " )
2024-02-25 18:54:40 +08:00
parser . add_argument ( ' --au ' , type = str , default = " data/au.csv " , help = " eye blink area " )
2024-03-31 12:01:28 +08:00
parser . add_argument ( ' --torso_imgs ' , type = str , default = " " , help = " torso images path " )
2023-12-19 09:41:52 +08:00
parser . add_argument ( ' -O ' , action = ' store_true ' , help = " equals --fp16 --cuda_ray --exp_eye " )
parser . add_argument ( ' --data_range ' , type = int , nargs = ' * ' , default = [ 0 , - 1 ] , help = " data range to use " )
parser . add_argument ( ' --workspace ' , type = str , default = ' data/video ' )
parser . add_argument ( ' --seed ' , type = int , default = 0 )
### training options
parser . add_argument ( ' --ckpt ' , type = str , default = ' data/pretrained/ngp_kf.pth ' )
parser . add_argument ( ' --num_rays ' , type = int , default = 4096 * 16 , help = " num rays sampled per image for each training step " )
parser . add_argument ( ' --cuda_ray ' , action = ' store_true ' , help = " use CUDA raymarching instead of pytorch " )
parser . add_argument ( ' --max_steps ' , type = int , default = 16 , help = " max num steps sampled per ray (only valid when using --cuda_ray) " )
parser . add_argument ( ' --num_steps ' , type = int , default = 16 , help = " num steps sampled per ray (only valid when NOT using --cuda_ray) " )
parser . add_argument ( ' --upsample_steps ' , type = int , default = 0 , help = " num steps up-sampled per ray (only valid when NOT using --cuda_ray) " )
parser . add_argument ( ' --update_extra_interval ' , type = int , default = 16 , help = " iter interval to update extra status (only valid when using --cuda_ray) " )
parser . add_argument ( ' --max_ray_batch ' , type = int , default = 4096 , help = " batch size of rays at inference to avoid OOM (only valid when NOT using --cuda_ray) " )
### loss set
parser . add_argument ( ' --warmup_step ' , type = int , default = 10000 , help = " warm up steps " )
parser . add_argument ( ' --amb_aud_loss ' , type = int , default = 1 , help = " use ambient aud loss " )
parser . add_argument ( ' --amb_eye_loss ' , type = int , default = 1 , help = " use ambient eye loss " )
parser . add_argument ( ' --unc_loss ' , type = int , default = 1 , help = " use uncertainty loss " )
parser . add_argument ( ' --lambda_amb ' , type = float , default = 1e-4 , help = " lambda for ambient loss " )
### network backbone options
parser . add_argument ( ' --fp16 ' , action = ' store_true ' , help = " use amp mixed precision training " )
parser . add_argument ( ' --bg_img ' , type = str , default = ' white ' , help = " background image " )
parser . add_argument ( ' --fbg ' , action = ' store_true ' , help = " frame-wise bg " )
parser . add_argument ( ' --exp_eye ' , action = ' store_true ' , help = " explicitly control the eyes " )
parser . add_argument ( ' --fix_eye ' , type = float , default = - 1 , help = " fixed eye area, negative to disable, set to 0-0.3 for a reasonable eye " )
parser . add_argument ( ' --smooth_eye ' , action = ' store_true ' , help = " smooth the eye area sequence " )
parser . add_argument ( ' --torso_shrink ' , type = float , default = 0.8 , help = " shrink bg coords to allow more flexibility in deform " )
### dataset options
parser . add_argument ( ' --color_space ' , type = str , default = ' srgb ' , help = " Color space, supports (linear, srgb) " )
parser . add_argument ( ' --preload ' , type = int , default = 0 , help = " 0 means load data from disk on-the-fly, 1 means preload to CPU, 2 means GPU. " )
# (the default value is for the fox dataset)
parser . add_argument ( ' --bound ' , type = float , default = 1 , help = " assume the scene is bounded in box[-bound, bound]^3, if > 1, will invoke adaptive ray marching. " )
parser . add_argument ( ' --scale ' , type = float , default = 4 , help = " scale camera location into box[-bound, bound]^3 " )
parser . add_argument ( ' --offset ' , type = float , nargs = ' * ' , default = [ 0 , 0 , 0 ] , help = " offset of camera location " )
parser . add_argument ( ' --dt_gamma ' , type = float , default = 1 / 256 , help = " dt_gamma (>=0) for adaptive ray marching. set to 0 to disable, >0 to accelerate rendering (but usually with worse quality) " )
parser . add_argument ( ' --min_near ' , type = float , default = 0.05 , help = " minimum near distance for camera " )
parser . add_argument ( ' --density_thresh ' , type = float , default = 10 , help = " threshold for density grid to be occupied (sigma) " )
parser . add_argument ( ' --density_thresh_torso ' , type = float , default = 0.01 , help = " threshold for density grid to be occupied (alpha) " )
parser . add_argument ( ' --patch_size ' , type = int , default = 1 , help = " [experimental] render patches in training, so as to apply LPIPS loss. 1 means disabled, use [64, 32, 16] to enable " )
parser . add_argument ( ' --init_lips ' , action = ' store_true ' , help = " init lips region " )
parser . add_argument ( ' --finetune_lips ' , action = ' store_true ' , help = " use LPIPS and landmarks to fine tune lips region " )
parser . add_argument ( ' --smooth_lips ' , action = ' store_true ' , help = " smooth the enc_a in a exponential decay way... " )
parser . add_argument ( ' --torso ' , action = ' store_true ' , help = " fix head and train torso " )
parser . add_argument ( ' --head_ckpt ' , type = str , default = ' ' , help = " head model " )
### GUI options
parser . add_argument ( ' --gui ' , action = ' store_true ' , help = " start a GUI " )
parser . add_argument ( ' --W ' , type = int , default = 450 , help = " GUI width " )
parser . add_argument ( ' --H ' , type = int , default = 450 , help = " GUI height " )
parser . add_argument ( ' --radius ' , type = float , default = 3.35 , help = " default GUI camera radius from center " )
parser . add_argument ( ' --fovy ' , type = float , default = 21.24 , help = " default GUI camera fovy " )
parser . add_argument ( ' --max_spp ' , type = int , default = 1 , help = " GUI rendering max sample per pixel " )
### else
parser . add_argument ( ' --att ' , type = int , default = 2 , help = " audio attention mode (0 = turn off, 1 = left-direction, 2 = bi-direction) " )
parser . add_argument ( ' --aud ' , type = str , default = ' ' , help = " audio source (empty will load the default, else should be a path to a npy file) " )
parser . add_argument ( ' --emb ' , action = ' store_true ' , help = " use audio class + embedding instead of logits " )
parser . add_argument ( ' --ind_dim ' , type = int , default = 4 , help = " individual code dim, 0 to turn off " )
parser . add_argument ( ' --ind_num ' , type = int , default = 10000 , help = " number of individual codes, should be larger than training dataset size " )
parser . add_argument ( ' --ind_dim_torso ' , type = int , default = 8 , help = " individual code dim, 0 to turn off " )
parser . add_argument ( ' --amb_dim ' , type = int , default = 2 , help = " ambient dimension " )
parser . add_argument ( ' --part ' , action = ' store_true ' , help = " use partial training data (1/10) " )
parser . add_argument ( ' --part2 ' , action = ' store_true ' , help = " use partial training data (first 15s) " )
parser . add_argument ( ' --train_camera ' , action = ' store_true ' , help = " optimize camera pose " )
parser . add_argument ( ' --smooth_path ' , action = ' store_true ' , help = " brute-force smooth camera pose trajectory with a window size " )
parser . add_argument ( ' --smooth_path_window ' , type = int , default = 7 , help = " smoothing window size " )
# asr
parser . add_argument ( ' --asr ' , action = ' store_true ' , help = " load asr for real-time app " )
parser . add_argument ( ' --asr_wav ' , type = str , default = ' ' , help = " load the wav and use as input " )
parser . add_argument ( ' --asr_play ' , action = ' store_true ' , help = " play out the audio " )
#parser.add_argument('--asr_model', type=str, default='deepspeech')
2024-04-05 20:59:55 +08:00
parser . add_argument ( ' --asr_model ' , type = str , default = ' cpierse/wav2vec2-large-xlsr-53-esperanto ' ) #
2023-12-19 09:41:52 +08:00
# parser.add_argument('--asr_model', type=str, default='facebook/wav2vec2-large-960h-lv60-self')
2024-04-05 20:59:55 +08:00
# parser.add_argument('--asr_model', type=str, default='facebook/hubert-large-ls960-ft')
2023-12-19 09:41:52 +08:00
parser . add_argument ( ' --asr_save_feats ' , action = ' store_true ' )
# audio FPS
parser . add_argument ( ' --fps ' , type = int , default = 50 )
# sliding window left-middle-right length (unit: 20ms)
parser . add_argument ( ' -l ' , type = int , default = 10 )
2024-04-05 08:55:21 +08:00
parser . add_argument ( ' -m ' , type = int , default = 8 )
2023-12-19 09:41:52 +08:00
parser . add_argument ( ' -r ' , type = int , default = 10 )
2024-03-23 21:13:21 +08:00
parser . add_argument ( ' --fullbody ' , action = ' store_true ' , help = " fullbody human " )
parser . add_argument ( ' --fullbody_img ' , type = str , default = ' data/fullbody/img ' )
parser . add_argument ( ' --fullbody_width ' , type = int , default = 580 )
parser . add_argument ( ' --fullbody_height ' , type = int , default = 1080 )
parser . add_argument ( ' --fullbody_offset_x ' , type = int , default = 0 )
parser . add_argument ( ' --fullbody_offset_y ' , type = int , default = 0 )
2024-05-26 11:10:03 +08:00
#musetalk opt
parser . add_argument ( ' --avatar_id ' , type = str , default = ' avator_1 ' )
parser . add_argument ( ' --bbox_shift ' , type = int , default = 5 )
2024-05-31 22:39:03 +08:00
parser . add_argument ( ' --batch_size ' , type = int , default = 16 )
2024-05-26 11:10:03 +08:00
2024-08-03 12:58:49 +08:00
# parser.add_argument('--customvideo', action='store_true', help="custom video")
# parser.add_argument('--customvideo_img', type=str, default='data/customvideo/img')
# parser.add_argument('--customvideo_imgnum', type=int, default=1)
2024-05-04 10:10:41 +08:00
2024-08-03 08:26:17 +08:00
parser . add_argument ( ' --customvideo_config ' , type = str , default = ' ' )
2024-09-08 22:53:37 +08:00
parser . add_argument ( ' --tts ' , type = str , default = ' edgetts ' ) #xtts gpt-sovits cosyvoice
2024-04-21 18:19:24 +08:00
parser . add_argument ( ' --REF_FILE ' , type = str , default = None )
2024-06-09 09:43:12 +08:00
parser . add_argument ( ' --REF_TEXT ' , type = str , default = None )
parser . add_argument ( ' --TTS_SERVER ' , type = str , default = ' http://127.0.0.1:9880 ' ) # http://localhost:9000
# parser.add_argument('--CHARACTER', type=str, default='test')
# parser.add_argument('--EMOTION', type=str, default='default')
2024-02-25 18:54:40 +08:00
2024-06-17 08:21:03 +08:00
parser . add_argument ( ' --model ' , type = str , default = ' ernerf ' ) #musetalk wav2lip
2024-05-26 11:10:03 +08:00
parser . add_argument ( ' --transport ' , type = str , default = ' rtcpush ' ) #rtmp webrtc rtcpush
parser . add_argument ( ' --push_url ' , type = str , default = ' http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream ' ) #rtmp://localhost/live/livestream
2024-07-17 08:21:31 +08:00
parser . add_argument ( ' --max_session ' , type = int , default = 1 ) #multi session count
2024-05-06 08:14:06 +08:00
parser . add_argument ( ' --listenport ' , type = int , default = 8010 )
2024-05-05 13:18:18 +08:00
2023-12-19 09:41:52 +08:00
opt = parser . parse_args ( )
2024-06-02 22:25:19 +08:00
#app.config.from_object(opt)
2024-05-26 11:10:03 +08:00
#print(app.config)
2024-08-03 08:26:17 +08:00
opt . customopt = [ ]
if opt . customvideo_config != ' ' :
with open ( opt . customvideo_config , ' r ' ) as file :
opt . customopt = json . load ( file )
2024-02-25 18:54:40 +08:00
2024-05-26 11:10:03 +08:00
if opt . model == ' ernerf ' :
2024-05-31 22:39:03 +08:00
from ernerf . nerf_triplane . provider import NeRFDataset_Test
from ernerf . nerf_triplane . utils import *
from ernerf . nerf_triplane . network import NeRFNetwork
from nerfreal import NeRFReal
2024-05-26 11:10:03 +08:00
# assert test mode
opt . test = True
opt . test_train = False
#opt.train_camera =True
# explicit smoothing
opt . smooth_path = True
opt . smooth_lips = True
assert opt . pose != ' ' , ' Must provide a pose source '
# if opt.O:
opt . fp16 = True
opt . cuda_ray = True
opt . exp_eye = True
opt . smooth_eye = True
if opt . torso_imgs == ' ' : #no img,use model output
opt . torso = True
# assert opt.cuda_ray, "Only support CUDA ray mode."
opt . asr = True
if opt . patch_size > 1 :
# assert opt.patch_size > 16, "patch_size should > 16 to run LPIPS loss."
assert opt . num_rays % ( opt . patch_size * * 2 ) == 0 , " patch_size ** 2 should be dividable by num_rays. "
seed_everything ( opt . seed )
print ( opt )
device = torch . device ( ' cuda ' if torch . cuda . is_available ( ) else ' cpu ' )
model = NeRFNetwork ( opt )
criterion = torch . nn . MSELoss ( reduction = ' none ' )
metrics = [ ] # use no metric in GUI for faster initialization...
print ( model )
trainer = Trainer ( ' ngp ' , opt , model , device = device , workspace = opt . workspace , criterion = criterion , fp16 = opt . fp16 , metrics = metrics , use_checkpoint = opt . ckpt )
test_loader = NeRFDataset_Test ( opt , device = device ) . dataloader ( )
model . aud_features = test_loader . _data . auds
model . eye_areas = test_loader . _data . eye_area
# we still need test_loader to provide audio features for testing.
2024-07-17 08:21:31 +08:00
for _ in range ( opt . max_session ) :
nerfreal = NeRFReal ( opt , trainer , test_loader )
nerfreals . append ( nerfreal )
2024-05-26 11:10:03 +08:00
elif opt . model == ' musetalk ' :
from musereal import MuseReal
print ( opt )
2024-07-17 08:21:31 +08:00
for _ in range ( opt . max_session ) :
nerfreal = MuseReal ( opt )
nerfreals . append ( nerfreal )
2024-06-17 08:21:03 +08:00
elif opt . model == ' wav2lip ' :
from lipreal import LipReal
print ( opt )
2024-07-17 08:21:31 +08:00
for _ in range ( opt . max_session ) :
nerfreal = LipReal ( opt )
nerfreals . append ( nerfreal )
for _ in range ( opt . max_session ) :
statreals . append ( 0 )
2023-12-19 09:41:52 +08:00
2024-04-14 19:08:25 +08:00
if opt . transport == ' rtmp ' :
thread_quit = Event ( )
2024-07-17 08:21:31 +08:00
rendthrd = Thread ( target = nerfreals [ 0 ] . render , args = ( thread_quit , ) )
2024-04-14 19:08:25 +08:00
rendthrd . start ( )
2023-12-19 09:41:52 +08:00
#############################################################################
2024-04-14 19:08:25 +08:00
appasync = web . Application ( )
appasync . on_shutdown . append ( on_shutdown )
appasync . router . add_post ( " /offer " , offer )
2024-05-06 08:14:06 +08:00
appasync . router . add_post ( " /human " , human )
2024-09-21 10:55:30 +08:00
appasync . router . add_post ( " /humanaudio " , humanaudio )
2024-08-03 08:26:17 +08:00
appasync . router . add_post ( " /set_audiotype " , set_audiotype )
2024-09-01 18:37:43 +08:00
appasync . router . add_post ( " /record " , record )
2024-09-17 22:11:46 +08:00
appasync . router . add_post ( " /is_speaking " , is_speaking )
2024-04-14 19:08:25 +08:00
appasync . router . add_static ( ' / ' , path = ' web ' )
2024-05-12 10:30:47 +08:00
# Configure default CORS settings.
cors = aiohttp_cors . setup ( appasync , defaults = {
" * " : aiohttp_cors . ResourceOptions (
allow_credentials = True ,
expose_headers = " * " ,
allow_headers = " * " ,
)
} )
# Configure CORS on all routes.
for route in list ( appasync . router . routes ( ) ) :
cors . add ( route )
2024-08-23 23:19:38 +08:00
pagename = ' webrtcapi.html '
if opt . transport == ' rtmp ' :
pagename = ' echoapi.html '
elif opt . transport == ' rtcpush ' :
pagename = ' rtcpushapi.html '
print ( ' start http server; http://<serverip>: ' + str ( opt . listenport ) + ' / ' + pagename )
2024-04-14 19:08:25 +08:00
def run_server ( runner ) :
loop = asyncio . new_event_loop ( )
asyncio . set_event_loop ( loop )
loop . run_until_complete ( runner . setup ( ) )
2024-05-06 08:14:06 +08:00
site = web . TCPSite ( runner , ' 0.0.0.0 ' , opt . listenport )
2024-04-14 19:08:25 +08:00
loop . run_until_complete ( site . start ( ) )
2024-04-27 18:08:57 +08:00
if opt . transport == ' rtcpush ' :
loop . run_until_complete ( run ( opt . push_url ) )
2024-04-14 19:08:25 +08:00
loop . run_forever ( )
2024-07-09 08:20:44 +08:00
#Thread(target=run_server, args=(web.AppRunner(appasync),)).start()
run_server ( web . AppRunner ( appasync ) )
2024-02-25 18:54:40 +08:00
2024-04-14 19:08:25 +08:00
#app.on_shutdown.append(on_shutdown)
#app.router.add_post("/offer", offer)
2024-07-09 08:20:44 +08:00
# print('start websocket server')
# server = pywsgi.WSGIServer(('0.0.0.0', 8000), app, handler_class=WebSocketHandler)
# server.serve_forever()
2023-12-19 09:41:52 +08:00