File size: 6,136 Bytes
1ef9436 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@File : streamer_info.py
@Time : 2024/08/10
@Project : https://github.com/PeterH0323/Streamer-Sales
@Author : HinGwenWong
@Version : 1.0
@Desc : 主播管理信息页面接口
"""
from typing import Tuple
import uuid
from pathlib import Path
import requests
from fastapi import APIRouter, Depends
from loguru import logger
from ...web_configs import API_CONFIG, WEB_CONFIGS
from ..database.streamer_info_db import create_or_update_db_streamer_by_id, delete_streamer_id, get_db_streamer_info
from ..models.streamer_info_model import StreamerInfo
from ..utils import ResultCode, make_poster_by_video_first_frame, make_return_data
from .users import get_current_user_info
router = APIRouter(
prefix="/streamer",
tags=["streamer"],
responses={404: {"description": "Not found"}},
)
async def gen_digital_human(user_id, streamer_id: int, new_streamer_info: StreamerInfo) -> Tuple[str, str]:
"""生成数字人视频
Args:
user_id (int): 用户 ID
streamer_id (int): 主播 ID
new_streamer_info (StreamerInfo): 新的主播信息
Returns:
str: 数字人视频地址
str: 数字人头像/海报地址
"""
streamer_info_db = await get_db_streamer_info(user_id, streamer_id)
streamer_info_db = streamer_info_db[0]
new_base_mp4_path = new_streamer_info.base_mp4_path.replace(API_CONFIG.REQUEST_FILES_URL, "")
if streamer_info_db.base_mp4_path.replace(API_CONFIG.REQUEST_FILES_URL, "") == new_base_mp4_path:
# 数字人视频没更新,跳过
return streamer_info_db.base_mp4_path, streamer_info_db.poster_image
# 调取接口生成进行数字人预处理
# new_streamer_info.base_mp4_path 是 服务器地址,需要进行转换
video_local_dir = Path(WEB_CONFIGS.SERVER_FILE_ROOT).joinpath(
WEB_CONFIGS.STREAMER_FILE_DIR, WEB_CONFIGS.STREAMER_INFO_FILES_DIR
)
digital_human_gen_info = {
"user_id": str(user_id),
"request_id": str(uuid.uuid1()),
"streamer_id": str(new_streamer_info.streamer_id),
"video_path": str(video_local_dir.joinpath(Path(new_streamer_info.base_mp4_path).name)),
}
logger.info(f"Getting digital human preprocessing: {new_streamer_info.streamer_id}")
_ = requests.post(API_CONFIG.DIGITAL_HUMAN_PREPROCESS_URL, json=digital_human_gen_info)
# 根据视频第一帧生成头图
poster_save_name = Path(new_streamer_info.base_mp4_path).stem + ".png"
make_poster_by_video_first_frame(str(video_local_dir.joinpath(Path(new_streamer_info.base_mp4_path).name)), poster_save_name)
# 生成头图服务器地址
poster_server_url = str(Path(new_streamer_info.base_mp4_path).parent.joinpath(poster_save_name))
if "http://" not in poster_server_url and "http:/" in poster_server_url:
poster_server_url = poster_server_url.replace("http:/", "http://")
return new_streamer_info.base_mp4_path, poster_server_url
@router.get("/list", summary="获取所有主播信息接口,用于用户进行主播的选择")
async def get_streamer_info_api(user_id: int = Depends(get_current_user_info)):
"""获取所有主播信息,用于用户进行主播的选择"""
streamer_list = await get_db_streamer_info(user_id)
return make_return_data(True, ResultCode.SUCCESS, "成功", streamer_list)
@router.get("/info/{streamerId}", summary="用于获取特定主播的信息接口")
async def get_streamer_info_api(streamerId: int, user_id: int = Depends(get_current_user_info)):
"""用于获取特定主播的信息"""
streamer_list = await get_db_streamer_info(user_id, streamerId)
if len(streamer_list) == 1:
streamer_list = streamer_list[0]
return make_return_data(True, ResultCode.SUCCESS, "成功", streamer_list)
@router.post("/create", summary="新增主播信息接口")
async def create_streamer_info_api(streamerItem: StreamerInfo, user_id: int = Depends(get_current_user_info)):
"""新增主播信息"""
streamer_info = streamerItem
streamer_info.user_id = user_id
streamer_info.streamer_id = None
poster_image = streamer_info.poster_image
base_mp4_path = streamer_info.base_mp4_path
streamer_info.poster_image = ""
streamer_info.base_mp4_path = ""
# 更新数据库,才能拿到 stream_id
streamer_id = create_or_update_db_streamer_by_id(0, streamer_info, user_id)
streamer_info.poster_image = poster_image
streamer_info.base_mp4_path = base_mp4_path
streamer_info.streamer_id = streamer_id
# 数字人视频对其进行初始化,同时生成头图
video_info = await gen_digital_human(user_id, streamer_id, streamer_info)
streamer_info.base_mp4_path = video_info[0]
streamer_info.poster_image = video_info[1]
streamer_info.avatar = video_info[1]
create_or_update_db_streamer_by_id(streamer_id, streamer_info, user_id)
return make_return_data(True, ResultCode.SUCCESS, "成功", streamer_id)
@router.put("/edit/{streamer_id}", summary="修改主播信息接口")
async def edit_streamer_info_api(streamer_id: int, streamer_info: StreamerInfo, user_id: int = Depends(get_current_user_info)):
"""修改主播信息"""
# 如果更新了数字人视频对其进行初始化,同时生成头图
video_info = await gen_digital_human(user_id, streamer_id, streamer_info)
streamer_info.base_mp4_path = video_info[0]
streamer_info.poster_image = video_info[1]
streamer_info.avatar = video_info[1]
# 更新数据库
create_or_update_db_streamer_by_id(streamer_id, streamer_info, user_id)
return make_return_data(True, ResultCode.SUCCESS, "成功", streamer_id)
@router.delete("/delete/{streamerId}", summary="删除主播接口")
async def upload_product_api(streamerId: int, user_id: int = Depends(get_current_user_info)):
process_success_flag = await delete_streamer_id(streamerId, user_id)
if not process_success_flag:
return make_return_data(False, ResultCode.FAIL, "失败", "")
return make_return_data(True, ResultCode.SUCCESS, "成功", "")
|