添加视频切片功能
This commit is contained in:
92
main.py
92
main.py
@@ -15,6 +15,7 @@ app = Flask(__name__)
|
||||
try:
|
||||
from ffmpeg_utils import process_ffmpeg
|
||||
from sanjuuni_utils import process_sanjuuni
|
||||
from video_frame_utils import process_video_frame_extraction
|
||||
from file_cleanup import start_cleanup_thread
|
||||
except ImportError as e:
|
||||
logging.error(f"导入模块时出错: {e}")
|
||||
@@ -23,6 +24,8 @@ except ImportError as e:
|
||||
return {'error': 'FFmpeg模块未正确导入'}
|
||||
def process_sanjuuni(*args, **kwargs):
|
||||
return {'error': 'Sanjuuni模块未正确导入'}
|
||||
def process_video_frame_extraction(*args, **kwargs):
|
||||
return {'error': '视频帧提取模块未正确导入'}
|
||||
def start_cleanup_thread():
|
||||
pass
|
||||
|
||||
@@ -37,6 +40,14 @@ enter_parameter_table = {
|
||||
"input_url": str,
|
||||
"output_format": str,
|
||||
"args": list
|
||||
},
|
||||
"video_frame": {
|
||||
"video_url": str,
|
||||
"w": int,
|
||||
"h": int,
|
||||
"fps": int,
|
||||
"force_resolution": bool,
|
||||
"pad_to_target": bool
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,11 +151,11 @@ def sanjuuni_async_api():
|
||||
|
||||
# 生成任务ID
|
||||
task_id = str(uuid.uuid4())[:8]
|
||||
|
||||
|
||||
# 获取请求的主机信息用于构建URL
|
||||
host = request.host
|
||||
scheme = request.scheme
|
||||
|
||||
|
||||
# 初始化任务状态
|
||||
with task_lock:
|
||||
task_registry[task_id] = {
|
||||
@@ -155,7 +166,7 @@ def sanjuuni_async_api():
|
||||
'last_returned_index': 0, # 记录最后返回的日志索引
|
||||
'progress': 0
|
||||
}
|
||||
|
||||
|
||||
# 启动异步任务
|
||||
thread = threading.Thread(
|
||||
target=run_async_task,
|
||||
@@ -163,9 +174,9 @@ def sanjuuni_async_api():
|
||||
)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
||||
|
||||
status_url = f"{scheme}://{host}/api/task/{task_id}"
|
||||
|
||||
|
||||
logging.info(f"创建异步Sanjuuni任务: {task_id}")
|
||||
return jsonify({
|
||||
'status': 'success',
|
||||
@@ -174,6 +185,53 @@ def sanjuuni_async_api():
|
||||
'message': '任务已创建,请使用状态URL查询进度'
|
||||
}), 202
|
||||
|
||||
@app.route('/api/video_frame/async', methods=['POST'])
|
||||
def video_frame_async_api():
|
||||
"""创建异步视频帧提取任务"""
|
||||
logging.info("收到异步视频帧提取API请求")
|
||||
data = request.get_json()
|
||||
|
||||
# 检测参数类型
|
||||
error_response, status_code = validate_request(data, "video_frame")
|
||||
if error_response:
|
||||
return error_response, status_code
|
||||
|
||||
# 生成任务ID
|
||||
task_id = str(uuid.uuid4())[:8]
|
||||
|
||||
# 获取请求的主机信息用于构建URL
|
||||
host = request.host
|
||||
scheme = request.scheme
|
||||
|
||||
# 初始化任务状态
|
||||
with task_lock:
|
||||
task_registry[task_id] = {
|
||||
'status': 'pending',
|
||||
'type': 'video_frame',
|
||||
'create_time': time.time(),
|
||||
'logs': [],
|
||||
'last_returned_index': 0, # 记录最后返回的日志索引
|
||||
'progress': 0
|
||||
}
|
||||
|
||||
# 启动异步任务
|
||||
thread = threading.Thread(
|
||||
target=run_async_task,
|
||||
args=(task_id, process_video_frame_extraction, data)
|
||||
)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
||||
status_url = f"{scheme}://{host}/api/task/{task_id}"
|
||||
|
||||
logging.info(f"创建异步视频帧提取任务: {task_id}")
|
||||
return jsonify({
|
||||
'status': 'success',
|
||||
'task_id': task_id,
|
||||
'status_url': status_url,
|
||||
'message': '任务已创建,请使用状态URL查询进度'
|
||||
}), 202
|
||||
|
||||
@app.route('/api/task/<task_id>', methods=['GET'])
|
||||
def get_task_status(task_id):
|
||||
"""查询任务状态和进度(自动返回新增日志)"""
|
||||
@@ -307,6 +365,30 @@ def download_file_endpoint(file_id, filename):
|
||||
logging.error(f"下载文件时出错: {e}")
|
||||
return jsonify({'status': 'error', 'error': str(e)}), 500
|
||||
|
||||
@app.route('/frames/<job_id>/<filename>', methods=['GET'])
|
||||
def serve_video_frames(job_id, filename):
|
||||
"""提供视频帧和音频文件访问"""
|
||||
import os
|
||||
from flask import send_from_directory
|
||||
from video_frame_utils import FRAMES_ROOT
|
||||
|
||||
safe_job = os.path.basename(job_id)
|
||||
safe_file = os.path.basename(filename)
|
||||
dir_path = os.path.join(FRAMES_ROOT, safe_job)
|
||||
|
||||
if not os.path.isdir(dir_path):
|
||||
return jsonify({"error": "文件不存在"}), 404
|
||||
|
||||
allowed = safe_file.endswith(('.png', '.dfpwm'))
|
||||
if not allowed:
|
||||
return jsonify({"error": "文件类型不支持"}), 400
|
||||
|
||||
try:
|
||||
return send_from_directory(dir_path, safe_file)
|
||||
except Exception as e:
|
||||
logging.error(f"提供文件时出错: {e}")
|
||||
return jsonify({"error": "文件访问失败"}), 500
|
||||
|
||||
@app.route('/health', methods=['GET'])
|
||||
def health_check():
|
||||
"""健康检查接口,直接返回 'ok'"""
|
||||
|
||||
Reference in New Issue
Block a user