123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- import os
- import hashlib
- import random
- import json
- from flask import Flask, jsonify, send_file, request
- from flask_cors import CORS
- app = Flask(__name__)
- CORS(app)
- # 配置文件路径
- VIDEO_DIR = "/177_data/media/MV" # 视频存放目录
- WEIGHT_FILE = "weights.json" # 权重存储文件
- MD5_CACHE_FILE = "md5_cache.json" # MD5缓存文件
- def load_md5_cache():
- """加载MD5缓存文件"""
- try:
- with open(MD5_CACHE_FILE, 'r') as f:
- cache = json.load(f)
- return {k: (v[0], v[1], v[2]) for k, v in cache.items()}
- except (FileNotFoundError, json.JSONDecodeError):
- return {}
- def save_md5_cache(cache):
- """保存MD5缓存文件"""
- serializable = {k: [v[0], v[1], v[2]] for k, v in cache.items()}
- with open(MD5_CACHE_FILE, 'w') as f:
- json.dump(serializable, f)
- def compute_md5(filepath):
- """计算文件的MD5值"""
- # 打印文件名,和前缀:正在计算
- print(f"正在计算文件{filepath}的MD5值...")
- hash_md5 = hashlib.md5()
- with open(filepath, "rb") as f:
- for chunk in iter(lambda: f.read(8192), b""):
- hash_md5.update(chunk)
- return hash_md5.hexdigest()
- def scan_files():
- """扫描视频文件并维护MD5缓存(支持子目录)"""
- cache = load_md5_cache()
- updated = False
- files = []
- # 递归遍历所有子目录
- for root, dirs, filenames in os.walk(VIDEO_DIR,followlinks=True):
- for filename in filenames:
- # 过滤非视频文件
- ext = filename.split('.')[-1].lower()
- if ext not in ['mp4', 'avi', 'mov', 'mkv', 'aac', 'mp3', 'flac']:
- continue
- filepath = os.path.join(root, filename)
- try:
- stat = os.stat(filepath)
- current_size = stat.st_size
- current_mtime = stat.st_mtime
- # 使用相对路径作为缓存键(可选)
- rel_path = os.path.relpath(filepath, VIDEO_DIR)
-
- # 检查缓存有效性
- if rel_path in cache:
- cached_size, cached_mtime, cached_md5 = cache[rel_path]
- if cached_size == current_size and cached_mtime == current_mtime:
- files.append({'filename': filename, 'md5': cached_md5, 'path': filepath})
- continue
- # 需要更新缓存
- md5 = compute_md5(filepath)
- cache[rel_path] = (current_size, current_mtime, md5)
- updated = True
- files.append({'filename': filename, 'md5': md5, 'path': filepath})
- except Exception as e:
- print(f"Error processing {filepath}: {str(e)}")
- # 保存更新后的缓存
- if updated:
- save_md5_cache(cache)
- return files
- def load_weights():
- """加载权重数据"""
- try:
- with open(WEIGHT_FILE, 'r') as f:
- return json.load(f)
- except:
- return {}
- def save_weights(weights):
- """保存权重数据"""
- with open(WEIGHT_FILE, 'w') as f:
- json.dump(weights, f)
- @app.route('/')
- def index():
- return send_file('index.html')
- @app.route('/files')
- def get_files():
- """文件列表接口"""
- files = scan_files()
- weights = load_weights()
-
- # 合并权重数据
- for f in files:
- f['weight'] = weights.get(f['md5'], 5)
-
- return jsonify(files)
- @app.route('/random')
- def get_random():
- """加权随机接口"""
- files = scan_files()
- weights = load_weights()
-
- # 构建权重列表
- weighted = []
- for f in files:
- weight = weights.get(f['md5'], 5)
- weighted.append( (f, max(0, min(10, weight))) )
-
- # 加权随机选择
- total = sum(w for _, w in weighted)
- if total == 0:
- return jsonify(random.choice(files))
-
- rand = random.uniform(0, total)
- current = 0
- for f, w in weighted:
- current += w
- if rand <= current:
- return jsonify(f)
- return jsonify(files[0])
- @app.route('/play/<md5>')
- def play_video(md5):
- """播放接口"""
- for f in scan_files():
- if f['md5'] == md5:
- return send_file(f['path'])
- return "Not Found", 404
- @app.route('/weight/<md5>', methods=['POST'])
- def update_weight(md5):
- """设置权重"""
- weights = load_weights()
- try:
- weight = int(request.json.get('weight', 5))
- weights[md5] = max(0, min(10, weight))
- save_weights(weights)
- return jsonify({'status': 'ok'})
- except:
- return jsonify({'status': 'error'}), 400
- if __name__ == '__main__':
- os.makedirs(VIDEO_DIR, exist_ok=True)
- app.run(debug=True, host='0.0.0.0', port=5000)
|