feat:get url download speed

This commit is contained in:
guorong.zheng 2024-12-03 18:13:44 +08:00
parent d6a95d2a40
commit 2b57f47556
3 changed files with 72 additions and 2 deletions

@ -39,6 +39,7 @@ fake-useragent = "*"
gunicorn = "*"
pillow = "*"
yt-dlp = "*"
m3u8 = "*"
[requires]
python_version = "3.13"

11
Pipfile.lock generated

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "607118c241d8006851d09df1f7eaa5299ede1023bfdf43911c258ce406732c3d"
"sha256": "c1675cff542fd8928f33bdc97dcb2a78bf11fda60b23d4d38317a5b56eb52e20"
},
"pipfile-spec": 6,
"requires": {
@ -441,6 +441,15 @@
"markers": "python_version >= '3.7'",
"version": "==3.1.4"
},
"m3u8": {
"hashes": [
"sha256:566d0748739c552dad10f8c87150078de6a0ec25071fa48e6968e96fc6dcba5d",
"sha256:7ade990a1667d7a653bcaf9413b16c3eb5cd618982ff46aaff57fe6d9fa9c0fd"
],
"index": "aliyun",
"markers": "python_version >= '3.7'",
"version": "==6.0.0"
},
"markupsafe": {
"hashes": [
"sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4",

@ -2,7 +2,9 @@ import asyncio
import re
import subprocess
from time import time
from urllib.parse import quote
import m3u8
import yt_dlp
from aiohttp import ClientSession, TCPConnector
@ -13,6 +15,62 @@ from utils.tools import is_ipv6, remove_cache_info, get_resolution_value, get_lo
logger = get_logger(constants.log_path)
async def get_speed_with_download(url, timeout=config.sort_timeout):
"""
Get the speed of the url with a total timeout
"""
start_time = time()
total_size = 0
total_time = 0
try:
async with ClientSession(
connector=TCPConnector(ssl=False), trust_env=True
) as session:
async with session.get(url, timeout=timeout) as response:
async for chunk in response.content.iter_any():
if chunk:
total_size += len(chunk)
except Exception as e:
pass
finally:
end_time = time()
total_time += end_time - start_time
average_speed = (total_size / total_time if total_time > 0 else 0) / 1024
return average_speed
async def get_speed_m3u8(url, timeout=config.sort_timeout):
"""
Get the speed of the m3u8 url with a total timeout
"""
start_time = time()
total_size = 0
total_time = 0
try:
url = quote(url, safe=':/?$&=@')
m3u8_obj = m3u8.load(url)
async with ClientSession(
connector=TCPConnector(ssl=False), trust_env=True
) as session:
for segment in m3u8_obj.segments:
if time() - start_time > timeout:
break
ts_url = segment.absolute_uri
async with session.get(ts_url, timeout=timeout) as response:
file_size = 0
async for chunk in response.content.iter_any():
if chunk:
file_size += len(chunk)
end_time = time()
download_time = end_time - start_time
total_size += file_size
total_time += download_time
except Exception as e:
pass
average_speed = (total_size / total_time if total_time > 0 else 0) / 1024
return average_speed
def get_info_yt_dlp(url, timeout=config.sort_timeout):
"""
Get the url info by yt_dlp
@ -54,7 +112,7 @@ async def get_speed_requests(url, timeout=config.sort_timeout, proxy=None):
Get the speed of the url by requests
"""
async with ClientSession(
connector=TCPConnector(verify_ssl=False), trust_env=True
connector=TCPConnector(ssl=False), trust_env=True
) as session:
start = time()
end = None
@ -171,6 +229,8 @@ async def get_speed(url, ipv6_proxy=None, callback=None):
return speed_cache[cache_key][0]
if ipv6_proxy and url_is_ipv6:
speed = (0, None)
elif '.m3u8' in url:
speed = await get_speed_m3u8(url)
else:
speed = await get_speed_yt_dlp(url)
if cache_key and cache_key not in speed_cache: