main.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import os
  2. import hashlib
  3. import random
  4. import json
  5. from flask import Flask, jsonify, send_file, request
  6. from flask_cors import CORS
  7. app = Flask(__name__)
  8. CORS(app)
  9. # 配置文件路径
  10. VIDEO_DIR = "/177_data/media/MV" # 视频存放目录
  11. WEIGHT_FILE = "weights.json" # 权重存储文件
  12. MD5_CACHE_FILE = "md5_cache.json" # MD5缓存文件
  13. def load_md5_cache():
  14. """加载MD5缓存文件"""
  15. try:
  16. with open(MD5_CACHE_FILE, 'r') as f:
  17. cache = json.load(f)
  18. return {k: (v[0], v[1], v[2]) for k, v in cache.items()}
  19. except (FileNotFoundError, json.JSONDecodeError):
  20. return {}
  21. def save_md5_cache(cache):
  22. """保存MD5缓存文件"""
  23. serializable = {k: [v[0], v[1], v[2]] for k, v in cache.items()}
  24. with open(MD5_CACHE_FILE, 'w') as f:
  25. json.dump(serializable, f)
  26. def compute_md5(filepath):
  27. """计算文件的MD5值"""
  28. hash_md5 = hashlib.md5()
  29. with open(filepath, "rb") as f:
  30. for chunk in iter(lambda: f.read(8192), b""):
  31. hash_md5.update(chunk)
  32. return hash_md5.hexdigest()
  33. def scan_files():
  34. """扫描视频文件并维护MD5缓存"""
  35. cache = load_md5_cache()
  36. updated = False
  37. files = []
  38. for filename in os.listdir(VIDEO_DIR):
  39. # 过滤非视频文件
  40. if filename.split('.')[-1].lower() not in ['mp4', 'avi', 'mov', 'mkv']:
  41. continue
  42. filepath = os.path.join(VIDEO_DIR, filename)
  43. if not os.path.isfile(filepath):
  44. continue
  45. try:
  46. stat = os.stat(filepath)
  47. current_size = stat.st_size
  48. current_mtime = stat.st_mtime
  49. # 检查缓存有效性
  50. if filename in cache:
  51. cached_size, cached_mtime, cached_md5 = cache[filename]
  52. if cached_size == current_size and cached_mtime == current_mtime:
  53. files.append({'filename': filename, 'md5': cached_md5, 'path': filepath})
  54. continue
  55. # 需要更新缓存
  56. md5 = compute_md5(filepath)
  57. cache[filename] = (current_size, current_mtime, md5)
  58. updated = True
  59. files.append({'filename': filename, 'md5': md5, 'path': filepath})
  60. except Exception as e:
  61. print(f"Error processing {filename}: {str(e)}")
  62. # 保存更新后的缓存
  63. if updated:
  64. save_md5_cache(cache)
  65. return files
  66. def load_weights():
  67. """加载权重数据"""
  68. try:
  69. with open(WEIGHT_FILE, 'r') as f:
  70. return json.load(f)
  71. except:
  72. return {}
  73. def save_weights(weights):
  74. """保存权重数据"""
  75. with open(WEIGHT_FILE, 'w') as f:
  76. json.dump(weights, f)
  77. @app.route('/')
  78. def index():
  79. return send_file('index.html')
  80. @app.route('/files')
  81. def get_files():
  82. """文件列表接口"""
  83. files = scan_files()
  84. weights = load_weights()
  85. # 合并权重数据
  86. for f in files:
  87. f['weight'] = weights.get(f['md5'], 5)
  88. return jsonify(files)
  89. @app.route('/random')
  90. def get_random():
  91. """加权随机接口"""
  92. files = scan_files()
  93. weights = load_weights()
  94. # 构建权重列表
  95. weighted = []
  96. for f in files:
  97. weight = weights.get(f['md5'], 5)
  98. weighted.append( (f, max(0, min(10, weight))) )
  99. # 加权随机选择
  100. total = sum(w for _, w in weighted)
  101. if total == 0:
  102. return jsonify(random.choice(files))
  103. rand = random.uniform(0, total)
  104. current = 0
  105. for f, w in weighted:
  106. current += w
  107. if rand <= current:
  108. return jsonify(f)
  109. return jsonify(files[0])
  110. @app.route('/play/<md5>')
  111. def play_video(md5):
  112. """播放接口"""
  113. for f in scan_files():
  114. if f['md5'] == md5:
  115. return send_file(f['path'])
  116. return "Not Found", 404
  117. @app.route('/weight/<md5>', methods=['POST'])
  118. def update_weight(md5):
  119. """设置权重"""
  120. weights = load_weights()
  121. try:
  122. weight = int(request.json.get('weight', 5))
  123. weights[md5] = max(0, min(10, weight))
  124. save_weights(weights)
  125. return jsonify({'status': 'ok'})
  126. except:
  127. return jsonify({'status': 'error'}), 400
  128. if __name__ == '__main__':
  129. os.makedirs(VIDEO_DIR, exist_ok=True)
  130. app.run(debug=True, host='0.0.0.0', port=5000)