main.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. # 打印文件名,和前缀:正在计算
  29. print(f"正在计算文件{filepath}的MD5值...")
  30. hash_md5 = hashlib.md5()
  31. with open(filepath, "rb") as f:
  32. for chunk in iter(lambda: f.read(8192), b""):
  33. hash_md5.update(chunk)
  34. return hash_md5.hexdigest()
  35. def scan_files():
  36. """扫描视频文件并维护MD5缓存(支持子目录)"""
  37. cache = load_md5_cache()
  38. updated = False
  39. files = []
  40. # 递归遍历所有子目录
  41. for root, dirs, filenames in os.walk(VIDEO_DIR,followlinks=True):
  42. for filename in filenames:
  43. # 过滤非视频文件
  44. ext = filename.split('.')[-1].lower()
  45. if ext not in ['mp4', 'avi', 'mov', 'mkv', 'aac', 'mp3', 'flac']:
  46. continue
  47. filepath = os.path.join(root, filename)
  48. try:
  49. stat = os.stat(filepath)
  50. current_size = stat.st_size
  51. current_mtime = stat.st_mtime
  52. # 使用相对路径作为缓存键(可选)
  53. rel_path = os.path.relpath(filepath, VIDEO_DIR)
  54. # 检查缓存有效性
  55. if rel_path in cache:
  56. cached_size, cached_mtime, cached_md5 = cache[rel_path]
  57. if cached_size == current_size and cached_mtime == current_mtime:
  58. files.append({'filename': filename, 'md5': cached_md5, 'path': filepath})
  59. continue
  60. # 需要更新缓存
  61. md5 = compute_md5(filepath)
  62. cache[rel_path] = (current_size, current_mtime, md5)
  63. updated = True
  64. files.append({'filename': filename, 'md5': md5, 'path': filepath})
  65. except Exception as e:
  66. print(f"Error processing {filepath}: {str(e)}")
  67. # 保存更新后的缓存
  68. if updated:
  69. save_md5_cache(cache)
  70. return files
  71. def load_weights():
  72. """加载权重数据"""
  73. try:
  74. with open(WEIGHT_FILE, 'r') as f:
  75. return json.load(f)
  76. except:
  77. return {}
  78. def save_weights(weights):
  79. """保存权重数据"""
  80. with open(WEIGHT_FILE, 'w') as f:
  81. json.dump(weights, f)
  82. @app.route('/')
  83. def index():
  84. return send_file('index.html')
  85. @app.route('/files')
  86. def get_files():
  87. """文件列表接口"""
  88. files = scan_files()
  89. weights = load_weights()
  90. # 合并权重数据
  91. for f in files:
  92. f['weight'] = weights.get(f['md5'], 5)
  93. return jsonify(files)
  94. @app.route('/random')
  95. def get_random():
  96. """加权随机接口"""
  97. files = scan_files()
  98. weights = load_weights()
  99. # 构建权重列表
  100. weighted = []
  101. for f in files:
  102. weight = weights.get(f['md5'], 5)
  103. weighted.append( (f, max(0, min(10, weight))) )
  104. # 加权随机选择
  105. total = sum(w for _, w in weighted)
  106. if total == 0:
  107. return jsonify(random.choice(files))
  108. rand = random.uniform(0, total)
  109. current = 0
  110. for f, w in weighted:
  111. current += w
  112. if rand <= current:
  113. return jsonify(f)
  114. return jsonify(files[0])
  115. @app.route('/play/<md5>')
  116. def play_video(md5):
  117. """播放接口"""
  118. for f in scan_files():
  119. if f['md5'] == md5:
  120. return send_file(f['path'])
  121. return "Not Found", 404
  122. @app.route('/weight/<md5>', methods=['POST'])
  123. def update_weight(md5):
  124. """设置权重"""
  125. weights = load_weights()
  126. try:
  127. weight = int(request.json.get('weight', 5))
  128. weights[md5] = max(0, min(10, weight))
  129. save_weights(weights)
  130. return jsonify({'status': 'ok'})
  131. except:
  132. return jsonify({'status': 'error'}), 400
  133. if __name__ == '__main__':
  134. os.makedirs(VIDEO_DIR, exist_ok=True)
  135. app.run(debug=True, host='0.0.0.0', port=5000,threaded=True)