赞
踩
git clone https://github.com/OpenTalker/SadTalker.git
cd SadTalker
conda create -n sadtalker python=3.8
conda activate sadtalker
# GPU版本
pip install torch==1.12.1+cu113 torchvision==0.13.1+cu113 torchaudio==0.12.1 --extra-index-url https://download.pytorch.org/whl/cu113
# CPU版本(https://pytorch.org/get-started/previous-versions/)
# pip install torch==1.12.1+cpu torchvision==0.13.1+cpu torchaudio==0.12.1 --extra-index-url https://download.pytorch.org/whl/cpu
conda install ffmpeg
# 如果报错,加上--use-pep517
pip install -r requirements.txt --use-pep517 -i https://pypi.douban.com/simple
### Coqui TTS is optional for gradio demo.
### pip install TTS
pip install chardet
bash scripts/download_models.sh
- 预训练模型会下载到
checkpoints
目录下- GFP-GAN人脸复原模型会下载到
gfpgan/weights
目录下
sh webui.sh
# webui.sh运行出错,也可以分解成如下命令运行
python3 -m venv venv
source ./venv/Scripts/activate
pip install Cython
python3 launcher.py
# 使用默认参数运行
python inference.py --driven_audio examples/driven_audio/chinese_poem1.wav \
--source_image examples/source_image/full4.jpeg \
--enhancer gfpgan
# 最佳实践
python inference.py --driven_audio examples/driven_audio/chinese_poem1.wav \
--source_image examples/source_image/art_6.png \
--result_dir ./results \
--still \
--expression_scale 1 \
--preprocess full \
--enhancer gfpgan
如果使用CPU运行,则加上
--cpu
参数
解决方案: 修改numpy
版本,安装numpy 1.24
之前的版本
pip uninstall numpy
pip install numpy==1.23.5
复制inference.py
到inference2.py
,在def main(args):
函数最后一行增加
return os.path.abspath(save_dir+'.mp4')
提供HTTP接口,就能方便被其它系统调用了,编写一个python
脚本
from argparse import ArgumentParser
import torch
import uvicorn
from fastapi import FastAPI, APIRouter
# http请求和响应参数需要继承BaseModel
from pydantic import BaseModel
import inference2
context_path = "/sadtalker"
# 指定API前缀
router = APIRouter(prefix=context_path)
class MakeVideoRequest(BaseModel):
source_image: str="full_body_1.png"
driven_audio: str="./examples/driven_audio/bus_chinese.wav"
# 相对./results的子目录,最终会在这个目录下生成.mp4视频文件
result_dir: str=""
still: bool=True
expression_scale: float=1.
preprocess: str="full"
enhancer: str="gfpgan"
cpu: bool=False
verbose: bool=False
class MakeVideoResponse(BaseModel):
video_path: str
def __init__(self, video_path) -> None:
super().__init__(video_path=video_path)
self.video_path = video_path
# 绑定路由和视图函数
@router.post("/video/make", response_model=MakeVideoResponse)
async def makeVideo(request:MakeVideoRequest):
parser = ArgumentParser()
parser.add_argument("--driven_audio", default=request.driven_audio, help="path to driven audio")
parser.add_argument("--source_image", default="./examples/source_image/"+request.source_image, help="path to source image")
parser.add_argument("--ref_eyeblink", default=None, help="path to reference video providing eye blinking")
parser.add_argument("--ref_pose", default=None, help="path to reference video providing pose")
parser.add_argument("--checkpoint_dir", default='./checkpoints', help="path to output")
parser.add_argument("--result_dir", default="./results"+request.result_dir, help="path to output")
parser.add_argument("--pose_style", type=int, default=0, help="input pose style from [0, 46)")
parser.add_argument("--batch_size", type=int, default=2, help="the batch size of facerender")
parser.add_argument("--size", type=int, default=256, help="the image size of the facerender")
parser.add_argument("--expression_scale", type=float, default=request.expression_scale, help="the batch size of facerender")
parser.add_argument('--input_yaw', nargs='+', type=int, default=None, help="the input yaw degree of the user ")
parser.add_argument('--input_pitch', nargs='+', type=int, default=None, help="the input pitch degree of the user")
parser.add_argument('--input_roll', nargs='+', type=int, default=None, help="the input roll degree of the user")
parser.add_argument('--enhancer', type=str, default=request.enhancer, help="Face enhancer, [gfpgan, RestoreFormer]")
parser.add_argument('--background_enhancer', type=str, default=None, help="background enhancer, [realesrgan]")
parser.add_argument("--cpu", dest="cpu", default=request.cpu, action="store_true")
parser.add_argument("--face3dvis", action="store_true", help="generate 3d face and 3d landmarks")
parser.add_argument("--still", action="store_true", help="can crop back to the original videos for the full body aniamtion")
parser.add_argument("--preprocess", default=request.preprocess, choices=['crop', 'extcrop', 'resize', 'full', 'extfull'], help="how to preprocess the images" )
parser.add_argument("--verbose",action="store_true",default=request.verbose, help="saving the intermedia output or not" )
parser.add_argument("--old_version",action="store_true", help="use the pth other than safetensor version" )
# net structure and parameters
parser.add_argument('--net_recon', type=str, default='resnet50', choices=['resnet18', 'resnet34', 'resnet50'], help='useless')
parser.add_argument('--init_path', type=str, default=None, help='Useless')
parser.add_argument('--use_last_fc',default=False, help='zero initialize the last fc')
parser.add_argument('--bfm_folder', type=str, default='./checkpoints/BFM_Fitting/')
parser.add_argument('--bfm_model', type=str, default='BFM_model_front.mat', help='bfm model')
# default renderer parameters
parser.add_argument('--focal', type=float, default=1015.)
parser.add_argument('--center', type=float, default=112.)
parser.add_argument('--camera_d', type=float, default=10.)
parser.add_argument('--z_near', type=float, default=5.)
parser.add_argument('--z_far', type=float, default=15.)
args = parser.parse_args()
if torch.cuda.is_available() and not args.cpu:
args.device = "cuda"
else:
args.device = "cpu"
print("参数: ", args)
video_path = inference2.main(args)
respnose = MakeVideoResponse(video_path)
return respnose
@router.post("/demo")
async def demo():
print("hello world")
return "hello world"
def main():
# 类似于 app = Flask(__name__)
# 设置接口文档地址
app = FastAPI(openapi_url=context_path+"/openapi.json",
docs_url=context_path+"/docs",
redoc_url=context_path+"/redoc")
app.include_router(router)
# 启动服务,因为我们这个文件叫做 main.py
# 所以需要启动 main.py 里面的 app
# 第一个参数 "main:app" 就表示这个含义
# 然后是 host 和 port 表示监听的 ip 和端口
uvicorn.run(app, host="0.0.0.0", port=8100)
# 在 Windows 中必须加上 if __name__ == "__main__"
# 否则会抛出 RuntimeError: This event loop is already running
if __name__ == "__main__":
main()
nohup python sadtalker_http.py &
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。