GMapiServer/sanjuuni_utils.py
2025-05-04 17:32:22 +08:00

147 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import uuid
import subprocess
import requests
import tempfile
import shutil
import logging
from contextlib import contextmanager
import time # 导入 time 模块
@contextmanager
def temp_directory(dir=None):
temp_dir = tempfile.mkdtemp(dir=dir)
try:
yield temp_dir
finally:
pass
def download_file(url, temp_dir):
try:
headers = {
'User-Agent': 'Mozilla/5.0',
'Accept': '*/*'
}
logging.info(f"开始从URL下载文件: {url}")
response = requests.get(url, headers=headers, stream=True, timeout=30)
response.raise_for_status()
file_path = os.path.join(temp_dir, 'input_audio')
with open(file_path, 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
file_size = os.path.getsize(file_path)
if file_size < 1024:
error_msg = f"下载的文件太小(仅{file_size}字节),可能无效"
logging.error(error_msg)
raise Exception(error_msg)
logging.info(f"文件下载成功,保存到: {file_path} (大小: {file_size}字节)")
return file_path
except Exception as e:
logging.error(f"{url} 下载文件时出错: {e}")
raise
def execute_sanjuuni(input_path, output_path, sanjuuni_args):
try:
cmd = ['lib/sanjuuni/sanjuuni', '-i', input_path] + sanjuuni_args + ['-o', output_path]
logging.info(f"执行Sanjuuni命令: {' '.join(cmd)}")
result = subprocess.run(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
encoding='utf-8',
errors='replace'
)
if result.returncode != 0:
error_msg = f"Sanjuuni处理失败返回码: {result.returncode}, 错误: {result.stderr}"
logging.error(error_msg)
raise Exception(error_msg)
logging.info("Sanjuuni处理成功完成")
return True
except Exception as e:
logging.error(f"执行Sanjuuni时出错: {e}")
raise
def process_sanjuuni(data, file_registry, file_lock):
try:
temp_dir = tempfile.mkdtemp(dir='temp_files')
logging.info(f"创建临时目录: {temp_dir}")
input_url = data.get('input_url')
sanjuuni_args = data.get('args', []) # 从请求数据中获取 args 参数
# 定义不允许的参数
disallowed_params = [
'-s', '--http=', '-w', '--websocket=', '-u', '--websocket-client=',
'-T', '--streamed', '--disable-opencl', '-i', '--input=', '-o', '--output=',
'-S', '--subtitles='
]
# 检查是否有不允许的参数
for arg in sanjuuni_args:
for param in disallowed_params:
if arg.startswith(param):
error_msg = f"不允许使用参数: {arg}"
logging.error(error_msg)
raise ValueError(error_msg)
subtitle = data.get('subtitle', '')
output_format = data.get('output_format', 'lua')
# 构建 sanjuuni 参数
if 'format' in data:
sanjuuni_args.extend(['-f', data['format']])
if output_format == 'lua':
sanjuuni_args.append('-l')
elif output_format == 'nfp':
sanjuuni_args.append('-n')
elif output_format == 'raw':
sanjuuni_args.append('-r')
elif output_format == 'bimg':
sanjuuni_args.append('-b')
elif output_format == '32vid':
sanjuuni_args.append('-3')
else:
raise ValueError(f"Unsupported output format: {output_format}")
input_path = download_file(input_url, temp_dir)
output_id = str(uuid.uuid4())[:8]
output_filename = f"{output_id}.{output_format}"
output_path = os.path.join(temp_dir, output_filename)
execute_sanjuuni(input_path, output_path, sanjuuni_args)
with file_lock:
file_registry[output_id] = {
'path': os.path.abspath(output_path),
'filename': output_filename,
'last_access': time.time(), # 使用 time.time() 记录最后访问时间
'download_count': 0
}
logging.info(f"已注册新文件ID: {output_id}, 路径: {output_path}")
return {
'status': 'success',
'download_url': f"http://ffmpeg.liulikeji.cn/download/{output_id}/{output_filename}",
'file_id': output_id,
'temp_dir': temp_dir # 返回临时目录路径
}
except Exception as e:
logging.error(f"处理过程中出错: {e}")
return {'error': str(e)}