download_speed.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import os
  2. import cv2
  3. import re
  4. import time
  5. import threading
  6. from queue import Queue
  7. import requests
  8. import eventlet
  9. eventlet.monkey_patch()
  10. # 线程安全的队列,用于存储下载任务
  11. task_queue = Queue()
  12. # 线程安全的列表,用于存储结果
  13. results = []
  14. channels = []
  15. with open("IPTV.txt", 'r', encoding='utf-8') as file:
  16. lines = file.readlines()
  17. for line in lines:
  18. line = line.strip()
  19. if line:
  20. channel_name, channel_url = line.split(',')
  21. channels.append((channel_name, channel_url))
  22. # 定义工作线程函数
  23. def worker():
  24. while True:
  25. # 从队列中获取一个任务
  26. channel_name, channel_url = task_queue.get()
  27. try:
  28. channel_url_t = channel_url.rstrip(channel_url.split('/')[-1]) # m3u8链接前缀
  29. lines = requests.get(channel_url).text.strip().split('\n') # 获取m3u8文件内容
  30. ts_lists = [line.split('/')[-1] for line in lines if line.startswith('#') == False] # 获取m3u8文件下视频流后缀
  31. ts_lists_0 = ts_lists[0].rstrip(ts_lists[0].split('.ts')[-1]) # m3u8链接前缀
  32. ts_url = channel_url_t + ts_lists[0] # 拼接单个视频片段下载链接
  33. # 多获取的视频数据进行5秒钟限制
  34. with eventlet.Timeout(5, False):
  35. start_time = time.time()
  36. content = requests.get(ts_url).content
  37. end_time = time.time()
  38. response_time = (end_time - start_time) * 1
  39. if content:
  40. with open(ts_lists_0, 'ab') as f:
  41. f.write(content) # 写入文件
  42. file_size = len(content)
  43. download_speed = file_size / response_time / 1024
  44. normalized_speed = min(max(download_speed / 1024, 0.001), 100) # 将速率从kB/s转换为MB/s并限制在1~100之间
  45. # 获取帧宽度和帧高度
  46. cap = cv2.VideoCapture(ts_lists_0)
  47. frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
  48. frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
  49. cap.release()
  50. # 删除下载的文件
  51. os.remove(ts_lists_0)
  52. if frame_width != 0:
  53. result = channel_name, channel_url, f"{normalized_speed:.3f} MB/s", f"{frame_width}X{frame_height}"
  54. results.append(result)
  55. print(f"可用频道数:{len(results)}")
  56. except:
  57. pass
  58. # 标记任务完成
  59. task_queue.task_done()
  60. # 创建多个工作线程
  61. num_threads = 10
  62. for _ in range(num_threads):
  63. t = threading.Thread(target=worker, daemon=True) # 将工作线程设置为守护线程
  64. t.start()
  65. # 添加下载任务到队列
  66. for channel in channels:
  67. task_queue.put(channel)
  68. # 等待所有任务完成
  69. task_queue.join()
  70. def channel_key(channel_name):
  71. match = re.search(r'\d+', channel_name)
  72. if match:
  73. return int(match.group())
  74. else:
  75. return float('inf') # 返回一个无穷大的数字作为关键字
  76. # 对频道进行排序
  77. results.sort(key=lambda x: (x[0], -float(x[2].split()[0])))
  78. results.sort(key=lambda x: channel_key(x[0]))
  79. # 将结果写入文件
  80. with open("download_results.txt", 'w', encoding='utf-8') as file:
  81. for result in results:
  82. channel_name, channel_url, speed, resolution = result
  83. file.write(f"{channel_name},{channel_url},{speed},{resolution}\n")
  84. with open("download_speed.txt", 'w', encoding='utf-8') as file:
  85. for result in results:
  86. channel_name, channel_url, speed, resolution = result
  87. file.write(f"{channel_name},{channel_url}\n")