1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import requests
import subprocess
import os
import re
from concurrent.futures import ThreadPoolExecutor

# 基础URL模板和ID范围
BASE_URL = "http://zxrr.jx.chinamobile.com:8080/PLTV/88888910/224/322122{}/index.m3u8"
START_ID = 5000
END_ID = 6000

def clean_resolution(resolution):
"""清理分辨率字符串,去除换行符和多余空格"""
return re.sub(r'\s+', '', resolution).strip()

def check_and_capture_stream(stream_id):
url = BASE_URL.format(stream_id)
try:
# 检查M3U8是否可用
response = requests.get(url, timeout=5)
if response.status_code == 200 and "#EXTM3U" in response.text:
print(f"Found valid stream: {url}")

# 临时文件名
temp_image = f"temp_{stream_id}.jpg"
final_image = None

try:
# 使用FFmpeg捕获2秒后的帧
ffmpeg_cmd = [
'ffmpeg',
'-y', # 覆盖已存在文件
'-i', url,
'-ss', '00:00:02', # 跳转到2秒
'-frames:v', '1', # 只捕获1帧
'-f', 'image2',
temp_image
]

# 运行FFmpeg命令
subprocess.run(ffmpeg_cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=10)

# 如果成功生成临时图片,获取分辨率并重命名文件
if os.path.exists(temp_image):
# 获取视频分辨率
probe_cmd = [
'ffprobe',
'-v', 'error',
'-select_streams', 'v:0',
'-show_entries', 'stream=width,height',
'-of', 'csv=s=x:p=0',
url
]
result = subprocess.run(probe_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=5)

if result.returncode == 0:
resolution = clean_resolution(result.stdout)
if 'x' in resolution:
final_image = f"{resolution}_322122{stream_id}.jpg"
try:
os.rename(temp_image, final_image)
print(f"Saved screenshot: {final_image}")
except OSError as e:
print(f"Error renaming file: {e}")
# 如果重命名失败,使用默认文件名
final_image = f"resolution_322122{stream_id}.jpg"
os.rename(temp_image, final_image)
print(f"Saved screenshot with default name: {final_image}")
else:
print(f"Could not determine resolution for {url}")
# 使用默认文件名保存
final_image = f"unknown_resolution_322122{stream_id}.jpg"
os.rename(temp_image, final_image)
else:
print(f"Could not get resolution for {url}")
# 使用默认文件名保存
final_image = f"unknown_resolution_322122{stream_id}.jpg"
os.rename(temp_image, final_image)

except subprocess.TimeoutExpired:
print(f"FFmpeg timed out for {url}")
except subprocess.CalledProcessError as e:
print(f"FFmpeg failed for {url}: {e.stderr}")
except Exception as e:
print(f"Error processing {url}: {str(e)}")
finally:
# 清理临时文件
if os.path.exists(temp_image) and not final_image:
os.remove(temp_image)
else:
print(f"Invalid or unavailable stream: {url}")
except requests.RequestException:
pass # 忽略连接错误

def main():
# 使用线程池加速扫描
with ThreadPoolExecutor(max_workers=10) as executor:
executor.map(check_and_capture_stream, range(START_ID, END_ID + 1))

if __name__ == "__main__":
main()