import json import io import requests import uuid import time from urllib.parse import quote from app import create_app from extensions import db, s3_client from config import Config from models import GenerationRecord app = create_app() def sync_old_videos(): with app.app_context(): print("🔍 开始扫描未同步的视频记录...") # 获取所有包含 'video' 字样的记录 (简单过滤) records = GenerationRecord.query.filter(GenerationRecord.image_urls.like('%video%')).all() count = 0 success_count = 0 for r in records: try: data = json.loads(r.image_urls) updated = False new_data = [] for item in data: # 检查是否是视频且 URL 不是 MinIO 的地址 if isinstance(item, dict) and item.get('type') == 'video': url = item.get('url') if url and Config.MINIO['public_url'] not in url: print(f"⏳ 正在同步记录 {r.id}: {url[:50]}...") # 尝试下载并转存 try: with requests.get(url, stream=True, timeout=60) as req: if req.status_code == 200: content_type = req.headers.get('content-type', 'video/mp4') ext = ".mp4" base_filename = f"video-{uuid.uuid4().hex}" full_filename = f"{base_filename}{ext}" video_io = io.BytesIO() for chunk in req.iter_content(chunk_size=8192): video_io.write(chunk) video_io.seek(0) # 上传至 MinIO s3_client.upload_fileobj( video_io, Config.MINIO["bucket"], full_filename, ExtraArgs={"ContentType": content_type} ) final_url = f"{Config.MINIO['public_url']}{quote(full_filename)}" item['url'] = final_url updated = True print(f"✅ 同步成功: {final_url}") else: print(f"❌ 下载失败 (Status {req.status_code}),可能链接已过期") except Exception as e: print(f"❌ 同步异常: {e}") new_data.append(item) if updated: r.image_urls = json.dumps(new_data) db.session.commit() success_count += 1 count += 1 except Exception as e: print(f"处理记录 {r.id} 出错: {e}") print(f"\n🎉 扫描完成! 成功同步了 {success_count} 个视频。") if __name__ == "__main__": sync_old_videos()