itvtest(1080).py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import os
  2. import re
  3. import time
  4. import datetime
  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. error_channels = []
  16. with open("itv.txt", 'r', encoding='utf-8') as file:
  17. lines = file.readlines()
  18. for line in lines:
  19. line = line.strip()
  20. if line:
  21. channel_name, channel_url = line.split(',')
  22. channels.append((channel_name, channel_url))
  23. # 定义工作线程函数
  24. def worker():
  25. while True:
  26. # 从队列中获取一个任务
  27. channel_name, channel_url = task_queue.get()
  28. try:
  29. response = requests.get(channel_url, timeout=1)
  30. if response.status_code == 200:
  31. channel_url_t = channel_url.rstrip(channel_url.split('/')[-1]) # m3u8链接前缀
  32. lines = requests.get(channel_url,timeout=1).text.strip().split('\n') # 获取m3u8文件内容
  33. ts_lists = [line.split('/')[-1] for line in lines if line.startswith('#') == False] # 获取m3u8文件下视频流后缀
  34. file_size = 0
  35. start_time = time.time()
  36. # 多获取的视频数据进行12秒钟限制
  37. with eventlet.Timeout(12, False):
  38. for i in range(len(ts_lists)):
  39. ts_url = channel_url_t + ts_lists[i] # 拼接单个视频片段下载链接
  40. response = requests.get(ts_url, stream=True, timeout=1)
  41. for chunk in response.iter_content(chunk_size=1024):
  42. if chunk:
  43. file_size += len(chunk)
  44. response.close()
  45. end_time = time.time()
  46. response_time = end_time - start_time
  47. if response_time >=12:
  48. file_size = 0
  49. download_speed = file_size / response_time / 1024
  50. normalized_speed =download_speed / 1024 # 将速率从kB/s转换为MB/s
  51. ts_url = channel_url_t + ts_lists[0] # 拼接单个视频片段下载链接
  52. if normalized_speed >= 1:
  53. if file_size >= 12000000:
  54. result = channel_name, channel_url, f"{normalized_speed:.3f} MB/s"
  55. results.append(result)
  56. numberx = (len(results) + len(error_channels)) / len(channels) * 100
  57. print(f"可用频道:{len(results)} , 网速:{normalized_speed:.3f} MB/s , 不可用频道:{len(error_channels)} 个 , 总频道:{len(channels)} 个 ,总进度:{numberx:.2f} %。")
  58. else:
  59. error_channel = channel_name, channel_url
  60. error_channels.append(error_channel)
  61. numberx = (len(results) + len(error_channels)) / len(channels) * 100
  62. print(f"可用频道:{len(results)} 个 , 不可用频道:{len(error_channels)} , 网速:{normalized_speed:.3f} MB/s , 总频道:{len(channels)} 个 ,总进度:{numberx:.2f} %。")
  63. else:
  64. error_channel = channel_name, channel_url
  65. error_channels.append(error_channel)
  66. numberx = (len(results) + len(error_channels)) / len(channels) * 100
  67. print(f"可用频道:{len(results)} 个 , 不可用频道:{len(error_channels)} , 网速:{normalized_speed:.3f} MB/s , 总频道:{len(channels)} 个 ,总进度:{numberx:.2f} %。")
  68. else:
  69. error_channel = channel_name, channel_url
  70. error_channels.append(error_channel)
  71. numberx = (len(results) + len(error_channels)) / len(channels) * 100
  72. print(
  73. f"可用频道:{len(results)} 个 , 不可用频道:{len(error_channels)} 个 , 总频道:{len(channels)} 个 ,总进度:{numberx:.2f} %。")
  74. except:
  75. error_channel = channel_name, channel_url
  76. error_channels.append(error_channel)
  77. numberx = (len(results) + len(error_channels)) / len(channels) * 100
  78. print(f"可用频道:{len(results)} 个 , 不可用频道:{len(error_channels)} 个 , 总频道:{len(channels)} 个 ,总进度:{numberx:.2f} %。")
  79. # 标记任务完成
  80. task_queue.task_done()
  81. # 创建多个工作线程
  82. num_threads = 10
  83. for _ in range(num_threads):
  84. t = threading.Thread(target=worker, daemon=True)
  85. t.start()
  86. # 添加下载任务到队列
  87. for channel in channels:
  88. task_queue.put(channel)
  89. # 等待所有任务完成
  90. task_queue.join()
  91. def channel_key(channel_name):
  92. match = re.search(r'\d+', channel_name)
  93. if match:
  94. return int(match.group())
  95. else:
  96. return float('inf') # 返回一个无穷大的数字作为关键字
  97. # 对频道进行排序
  98. results.sort(key=lambda x: (x[0], -float(x[2].split()[0])))
  99. results.sort(key=lambda x: channel_key(x[0]))
  100. now_today = datetime.date.today()
  101. # 将结果写入文件
  102. with open("itv_results.txt", 'w', encoding='utf-8') as file:
  103. for result in results:
  104. channel_name, channel_url, speed = result
  105. file.write(f"{channel_name},{channel_url},{speed}\n")
  106. with open("itv_speed.txt", 'w', encoding='utf-8') as file:
  107. for result in results:
  108. channel_name, channel_url, speed = result
  109. file.write(f"{channel_name},{channel_url}\n")
  110. result_counter = 8 # 每个频道需要的个数
  111. with open("itvlist.txt", 'w', encoding='utf-8') as file:
  112. channel_counters = {}
  113. file.write('央视频道,#genre#\n')
  114. for result in results:
  115. channel_name, channel_url, speed = result
  116. if 'CCTV' in channel_name:
  117. if channel_name in channel_counters:
  118. if channel_counters[channel_name] >= result_counter:
  119. continue
  120. else:
  121. file.write(f"{channel_name},{channel_url}\n")
  122. channel_counters[channel_name] += 1
  123. else:
  124. file.write(f"{channel_name},{channel_url}\n")
  125. channel_counters[channel_name] = 1
  126. channel_counters = {}
  127. file.write('卫视频道,#genre#\n')
  128. for result in results:
  129. channel_name, channel_url, speed = result
  130. if '卫视' in channel_name:
  131. if channel_name in channel_counters:
  132. if channel_counters[channel_name] >= result_counter:
  133. continue
  134. else:
  135. file.write(f"{channel_name},{channel_url}\n")
  136. channel_counters[channel_name] += 1
  137. else:
  138. file.write(f"{channel_name},{channel_url}\n")
  139. channel_counters[channel_name] = 1
  140. channel_counters = {}
  141. file.write('其他频道,#genre#\n')
  142. for result in results:
  143. channel_name, channel_url, speed = result
  144. if 'CCTV' not in channel_name and '卫视' not in channel_name and '测试' not in channel_name:
  145. if channel_name in channel_counters:
  146. if channel_counters[channel_name] >= result_counter:
  147. continue
  148. else:
  149. file.write(f"{channel_name},{channel_url}\n")
  150. channel_counters[channel_name] += 1
  151. else:
  152. file.write(f"{channel_name},{channel_url}\n")
  153. channel_counters[channel_name] = 1
  154. file.write(f"{now_today}更新,#genre#\n")