import requests from concurrent.futures import ThreadPoolExecutor, as_completed from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt from .models import VideoGeneration def update_single_video_status(task, query_type): """ 更新单个视频的状态,适用于并发调用 """ url = '' headers = {} if query_type == 'revid': url = f"https://www.revid.ai/api/public/v2/status?pid={task.pid}" headers = { "key": "c4c0f516-33c0-4f5c-9d29-3b1d4e6a93c3", "Content-Type": "text/plain" } elif query_type == 'runwayml': url = f"https://api.aivideoapi.com/status?uuid={task.pid}" headers = { "Authorization": "12e76710fad2047db8c0cc6b25987e2a2", "Content-Type": "application/json" } try: response = requests.get(url, headers=headers) response.raise_for_status() data = response.json() # print(f"任务 PID: {task.pid} - 查询类型: {query_type}") # print(f"API响应: {data}") # 根据API响应,更新数据库状态 if query_type == 'runwayml': status = data.get('status') video_url = data.get('url', None) gif_url = data.get('gif_url', None) if status == 'success': task.status = 'completed' task.video_url = video_url task.gif_url = gif_url elif status in ['in queue', 'submitted']: task.status = 'pending' else: task.status = 'failed' task.description = 'RunwayML 视频生成失败' elif query_type == 'revid': success = data.get('success') status = data.get('status') video_url = data.get('videoUrl', None) error_message = data.get('error', '') if success == 1: if status == 'ready': task.status = 'completed' task.video_url = video_url elif status == 'building': task.status = 'pending' elif status == 'error': task.status = 'failed' task.description = error_message task.save() return task.pid, task.status, task.video_url except requests.exceptions.RequestException as e: # print(f"任务 PID: {task.pid} 请求失败,错误: {e}") return task.pid, 'failed', None @csrf_exempt def scan_and_update_video_status(request): """ 扫描所有未完成任务,并发更新每个任务的状态 """ tasks = VideoGeneration.objects.filter(status__in=['pending', 'in_progress']) task_count = tasks.count() # print(f"开始处理 {task_count} 个任务") results = [] if task_count > 0: # 使用并发线程池来处理请求 with ThreadPoolExecutor(max_workers=5) as executor: future_to_task = { executor.submit(update_single_video_status, task, 'revid' if task.slug in ['music-to-video', 'create-tiktok-video', 'create-avatar-video'] else 'runwayml'): task for task in tasks } for future in as_completed(future_to_task): try: task_pid, task_status, task_video_url = future.result() results.append({ 'pid': task_pid, 'status': task_status, 'video_url': task_video_url }) except Exception as e: print(f"Error: {e}") # print("任务处理完成,结果:", results) return JsonResponse({'code': 200, 'message': 'ok', 'data': results})