ai_v/sync_videos_manual.py

84 lines
3.6 KiB
Python
Raw Normal View History

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()