123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- import os
- import cv2
- import re
- import time
- import threading
- from queue import Queue
- import requests
- import eventlet
- eventlet.monkey_patch()
- # 线程安全的队列,用于存储下载任务
- task_queue = Queue()
- # 线程安全的列表,用于存储结果
- results = []
- channels = []
- with open("IPTV.txt", 'r', encoding='utf-8') as file:
- lines = file.readlines()
- for line in lines:
- line = line.strip()
- if line:
- channel_name, channel_url = line.split(',')
- channels.append((channel_name, channel_url))
- # 定义工作线程函数
- def worker():
- while True:
- # 从队列中获取一个任务
- channel_name, channel_url = task_queue.get()
- try:
- channel_url_t = channel_url.rstrip(channel_url.split('/')[-1]) # m3u8链接前缀
- lines = requests.get(channel_url).text.strip().split('\n') # 获取m3u8文件内容
- ts_lists = [line.split('/')[-1] for line in lines if line.startswith('#') == False] # 获取m3u8文件下视频流后缀
- ts_lists_0 = ts_lists[0].rstrip(ts_lists[0].split('.ts')[-1]) # m3u8链接前缀
- ts_url = channel_url_t + ts_lists[0] # 拼接单个视频片段下载链接
- # 多获取的视频数据进行5秒钟限制
- with eventlet.Timeout(5, False):
- start_time = time.time()
- content = requests.get(ts_url).content
- end_time = time.time()
- response_time = (end_time - start_time) * 1
- if content:
- with open(ts_lists_0, 'ab') as f:
- f.write(content) # 写入文件
- file_size = len(content)
- download_speed = file_size / response_time / 1024
- normalized_speed = min(max(download_speed / 1024, 0.001), 100) # 将速率从kB/s转换为MB/s并限制在1~100之间
- # 获取帧宽度和帧高度
- cap = cv2.VideoCapture(ts_lists_0)
- frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
- frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
- cap.release()
- # 删除下载的文件
- os.remove(ts_lists_0)
- if frame_width != 0:
- result = channel_name, channel_url, f"{normalized_speed:.3f} MB/s", f"{frame_width}X{frame_height}"
- results.append(result)
- print(f"可用频道数:{len(results)}")
- except:
- pass
- # 标记任务完成
- task_queue.task_done()
- # 创建多个工作线程
- num_threads = 10
- for _ in range(num_threads):
- t = threading.Thread(target=worker, daemon=True) # 将工作线程设置为守护线程
- t.start()
- # 添加下载任务到队列
- for channel in channels:
- task_queue.put(channel)
- # 等待所有任务完成
- task_queue.join()
- def channel_key(channel_name):
- match = re.search(r'\d+', channel_name)
- if match:
- return int(match.group())
- else:
- return float('inf') # 返回一个无穷大的数字作为关键字
- # 对频道进行排序
- results.sort(key=lambda x: (x[0], -float(x[2].split()[0])))
- results.sort(key=lambda x: channel_key(x[0]))
- # 将结果写入文件
- with open("download_results.txt", 'w', encoding='utf-8') as file:
- for result in results:
- channel_name, channel_url, speed, resolution = result
- file.write(f"{channel_name},{channel_url},{speed},{resolution}\n")
- with open("download_speed.txt", 'w', encoding='utf-8') as file:
- for result in results:
- channel_name, channel_url, speed, resolution = result
- file.write(f"{channel_name},{channel_url}\n")
|