Compare commits
131 Commits
9caa6e4dee
...
f9db587e9a
Author | SHA1 | Date |
---|---|---|
![]() |
f9db587e9a | |
![]() |
8e592e3a50 | |
![]() |
db1246ae58 | |
![]() |
b5c273e7ae | |
![]() |
d73f5941c4 | |
![]() |
d4c35773cf | |
![]() |
6a8bd34ddf | |
![]() |
8752dbe81d | |
![]() |
4ae07b77a6 | |
![]() |
b2765b0236 | |
![]() |
8e146c2ad8 | |
![]() |
fcc659c688 | |
![]() |
901e8d955b | |
![]() |
0416c37acc | |
![]() |
7dfb32504f | |
![]() |
262e8f69d2 | |
![]() |
7cf811e930 | |
![]() |
ef8d20123b | |
![]() |
be6d9d6f2c | |
![]() |
0b82dc281b | |
![]() |
c75d1f7c7b | |
![]() |
7761d057cd | |
![]() |
b3c085b90b | |
![]() |
588869fe7e | |
![]() |
eb9610653f | |
![]() |
32626a36ec | |
![]() |
022c58cf94 | |
![]() |
e00cee457e | |
![]() |
797131354d | |
![]() |
ea7487d537 | |
![]() |
a26ad0543a | |
![]() |
3b528b77ce | |
![]() |
4945aa4f5d | |
![]() |
c59f0ba5ff | |
![]() |
0525508d19 | |
![]() |
249447ff7b | |
![]() |
06cf6d780f | |
![]() |
c64b6ce466 | |
![]() |
f6a5470649 | |
![]() |
6942c253e2 | |
![]() |
5eceeefb45 | |
![]() |
2a3ec486e8 | |
![]() |
d575edd288 | |
![]() |
6bcf828ef7 | |
![]() |
a47c5bc0cf | |
![]() |
e28e493ad9 | |
![]() |
3eae868fe0 | |
![]() |
2923ced8ce | |
![]() |
4e1b913c7e | |
![]() |
e3c5589a35 | |
![]() |
ce93f2550c | |
![]() |
7542a49215 | |
![]() |
5af2dbc458 | |
![]() |
2dd4e1d7aa | |
![]() |
eeeab91693 | |
![]() |
224ea41c5a | |
![]() |
1773568619 | |
![]() |
1324e75593 | |
![]() |
0dd6d04bf5 | |
![]() |
212db1cecc | |
![]() |
dcfec8696a | |
![]() |
c5f1f7b8a9 | |
![]() |
fd72ca5b05 | |
![]() |
b9a77a66f2 | |
![]() |
ef9b1d894f | |
![]() |
aad526ebff | |
![]() |
52a26294da | |
![]() |
db1ab27ae9 | |
![]() |
921625db32 | |
![]() |
b3ad178f87 | |
![]() |
f5d4a781f2 | |
![]() |
53be0c2291 | |
![]() |
613e2bfbb5 | |
![]() |
d3a770f586 | |
![]() |
625889bde1 | |
![]() |
e83756fa77 | |
![]() |
0d54838f1a | |
![]() |
3570c9c249 | |
![]() |
2813aa1df2 | |
![]() |
adef4023d2 | |
![]() |
378b1d5a0f | |
![]() |
b783bf27f7 | |
![]() |
86086adbf8 | |
![]() |
569153c644 | |
![]() |
9ec0310e65 | |
![]() |
fb167df9cc | |
![]() |
e482ff7325 | |
![]() |
ebea4534d7 | |
![]() |
86db9c627e | |
![]() |
a57cf81185 | |
![]() |
c3e55bea18 | |
![]() |
8fc735aa20 | |
![]() |
41c34f00ac | |
![]() |
340006884e | |
![]() |
b68f94d6bb | |
![]() |
5595e35c29 | |
![]() |
9e0b084036 | |
![]() |
f20bb01594 | |
![]() |
27eccdb69f | |
![]() |
668c271454 | |
![]() |
532b0e2f92 | |
![]() |
0de4e39988 | |
![]() |
2c0d4acd60 | |
![]() |
42a89c479d | |
![]() |
89c0733cce | |
![]() |
bfe494e352 | |
![]() |
827213e137 | |
![]() |
685929606f | |
![]() |
0f9031c0b8 | |
![]() |
b5ff415aa2 | |
![]() |
399050cc74 | |
![]() |
a6de40b700 | |
![]() |
1669a07a80 | |
![]() |
ce4180ab8f | |
![]() |
ee87f7fb13 | |
![]() |
275dc64929 | |
![]() |
d31e61d496 | |
![]() |
55ce5605c1 | |
![]() |
7644e3cd18 | |
![]() |
bfc7704211 | |
![]() |
2e30eb7471 | |
![]() |
fa28643b71 | |
![]() |
ebe471eb76 | |
![]() |
c9e5aa3ed2 | |
![]() |
b67fc30f19 | |
![]() |
bbd306e409 | |
![]() |
3ca066751e | |
![]() |
743cda1f4c | |
![]() |
fc30548ffb | |
![]() |
b6abbeefb3 | |
![]() |
0f56e3f96a |
|
@ -0,0 +1,51 @@
|
|||
name: EPG Update
|
||||
on:
|
||||
schedule:
|
||||
- cron: '55 0 */2 * *' # 每2天凌晨00点55分执行任务,上海时区的UTC时间
|
||||
workflow_dispatch: # 允许手动触发工作流
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
# 使用 actions/checkout@v3 动作检出仓库代码到工作目录
|
||||
- name: Set up Git user
|
||||
run: |
|
||||
git config --local user.name "github-actions[bot]"
|
||||
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||
# 设置本地 Git 用户名和邮箱,以便后续提交代码时使用
|
||||
- name: Create live directory
|
||||
run: mkdir -p live
|
||||
# 创建 live 文件夹
|
||||
- name: Download EPG File
|
||||
run: wget http://epg.51zmt.top:8000/e.xml -O live/epg.xml
|
||||
# 使用 wget 命令从指定 URL 下载 EPG 文件并保存到 live 文件夹下
|
||||
- name: Calculate SHA-256 hash of live/epg.xml
|
||||
id: calculate_hash
|
||||
run: |
|
||||
echo "hash=$(sha256sum live/epg.xml | awk '{print $1}')" >> "$GITHUB_ENV"
|
||||
# 计算下载的 epg.xml 文件的 SHA-256 哈希值,并将其存储在环境变量 hash 中,使用 $GITHUB_ENV 文件
|
||||
- name: Get previous SHA-256 hash from last commit
|
||||
id: get_previous_hash
|
||||
run: |
|
||||
if [ -f live/epg.xml ]; then
|
||||
echo "previous_hash=$(git show HEAD:live/epg.xml | sha256sum | awk '{print $1}')" >> "$GITHUB_ENV"
|
||||
else
|
||||
echo "previous_hash=none" >> "$GITHUB_ENV"
|
||||
fi
|
||||
# 获取上次提交中 epg.xml 文件的 SHA-256 哈希值,并将其存储在环境变量 previous_hash 中,使用 $GITHUB_ENV 文件。如果文件在上次提交中不存在,则将 previous_hash 设置为 none
|
||||
- name: Compare hashes and update if different
|
||||
run: |
|
||||
if [ "${{ env.hash }}" != "${{ env.previous_hash }}" ]; then
|
||||
git add live/epg.xml
|
||||
git commit -m "Auto-update epg files."
|
||||
git push origin main
|
||||
else
|
||||
echo "No changes detected in live/epg.xml, skipping commit."
|
||||
fi
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# 比较当前 epg.xml 文件的哈希值与上次提交中的哈希值。
|
||||
# 如果哈希值不同,则将文件添加到 Git 并提交更改,然后推送到 main 分支。
|
||||
# 如果哈希值相同,则输出 "No changes detected in live/epg.xml, skipping commit." 并跳过提交和推送
|
|
@ -1,69 +0,0 @@
|
|||
name: 电视直播汇总M3U下载
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '55 0 */2 * *' # 每2天凌晨00点55分执行任务,上海时区的UTC时间
|
||||
workflow_dispatch: # 允许手动触发
|
||||
|
||||
env:
|
||||
TZ: Asia/Shanghai # 设置时区为上海
|
||||
|
||||
jobs:
|
||||
download-and-process:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write # 确保 GITHUB_TOKEN 有写入权限
|
||||
|
||||
steps:
|
||||
- name: 检出仓库
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: 设置Python环境
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.8'
|
||||
|
||||
- name: 安装依赖
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install requests
|
||||
|
||||
- name: 运行Python脚本
|
||||
run: python app.py
|
||||
|
||||
- name: 检查文件是否生成
|
||||
run: |
|
||||
if [ -f "live/live.m3u" ]; then
|
||||
echo "live.m3u 文件已生成"
|
||||
else
|
||||
echo "警告: live.m3u 文件未生成"
|
||||
fi
|
||||
if [ -f "live/live.txt" ]; then
|
||||
echo "live.txt 文件已生成"
|
||||
else
|
||||
echo "警告: live.txt 文件未生成"
|
||||
fi
|
||||
|
||||
- name: 插入指定说明文字
|
||||
run: |
|
||||
DATE=$(date +"%m/%d")
|
||||
if [ -f "live/live.m3u" ]; then
|
||||
sed -i '1i #EXTM3U x-tvg-url="https://epg.v1.mk/fy.xml"' live/live.m3u
|
||||
sed -i '2i #EXTINF:-1 tvg-logo="https://codeberg.org/alantang/photo/raw/branch/main/photo_2025-03-16_10-57-18.jpg" group-title="收藏频道",更新'"$DATE"'' live/live.m3u
|
||||
sed -i '3i http://tencentplaygzrb01.gztv.com/live/zonghes.m3u8' live/live.m3u
|
||||
fi
|
||||
|
||||
- name: 提交更改
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
DATE=$(date +"%Y-%m-%d %H:%M:%S")
|
||||
git config --global user.name "GitHub Actions"
|
||||
git config --global user.email "actions@github.com"
|
||||
git add live/*
|
||||
if git diff-index --quiet HEAD --; then
|
||||
echo "没有更改需要提交更新: $DATE"
|
||||
else
|
||||
git commit -m "自动更新 M3U 播放列表: $DATE"
|
||||
git push https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}
|
||||
fi
|
|
@ -0,0 +1,53 @@
|
|||
name: IPTV Update
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '55 0 */2 * *' # 每2天凌晨00点55分执行任务,上海时区的UTC时间
|
||||
# 允许手动触发工作流
|
||||
workflow_dispatch:
|
||||
branches:
|
||||
- main # 仅在 main 分支上允许手动触发
|
||||
|
||||
jobs:
|
||||
run_script:
|
||||
runs-on: ubuntu-latest # 使用最新的 Ubuntu 运行器
|
||||
|
||||
steps:
|
||||
- name: Checkout repository # 检出代码库到运行器中
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python # 设置 Python 环境
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.10' # 使用 Python 版本 3.10
|
||||
|
||||
- name: Cache dependencies # 缓存 pip 依赖项以加速后续构建
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pip # 依赖项的缓存路径
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} # 生成缓存键
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip- # 如果完全匹配的 key 不存在,则尝试使用此恢复键
|
||||
|
||||
- name: Install dependencies # 安装项目所需的 Python 包
|
||||
run: |
|
||||
pip install aiohttp # 安装 aiohttp 库
|
||||
pip install requests # 安装 requests 库
|
||||
|
||||
- name: Run Python script # 执行主脚本
|
||||
run: python main.py
|
||||
|
||||
- name: Commit and push if changed # 如果有更改,则提交并推送
|
||||
run: |
|
||||
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git config --local user.name "github-actions[bot]"
|
||||
git add -A # 添加所有更改到暂存区
|
||||
# 如果有更改被暂存,则创建并推送一个新的提交
|
||||
if ! git diff --staged --quiet; then
|
||||
git commit -m "Auto-update live files" # 提交信息
|
||||
git pull --rebase # 拉取远程更新并变基
|
||||
git push # 推送更改到远程仓库
|
||||
fi
|
||||
|
||||
env:
|
||||
TZ: Asia/Shanghai # 设置环境变量,将时区设置为上海
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024-PRESENT Govin <https://github.com/guovin>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
After Width: | Height: | Size: 95 KiB |
After Width: | Height: | Size: 166 KiB |
After Width: | Height: | Size: 91 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 497 KiB |
After Width: | Height: | Size: 3.3 MiB |
After Width: | Height: | Size: 2.0 MiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 83 KiB |
After Width: | Height: | Size: 83 KiB |
|
@ -1,5 +1,5 @@
|
|||
<div align="center">
|
||||
<img src="./Pictures/TangImage240.png" alt="logo"/>
|
||||
<img src="./Pictures/333.png" alt="logo"/>
|
||||
<h1 align="center">影视点播直播源</h1>
|
||||
</div>
|
||||
|
||||
|
@ -155,6 +155,7 @@ https://www.tutieshi.com/
|
|||
# Github国内代理:https://ghproxy.link https://xiake.pro/
|
||||
|
||||
|
||||
https://ghfile.geekertao.top/https://github.com/
|
||||
https://cors.zme.ink/https://raw.githubusercontent.com/
|
||||
https://slink.ltd/https://raw.githubusercontent.com/
|
||||
https://gh.tryxd.cn/https://raw.githubusercontent.com/
|
||||
|
|
145
X.json
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"spider":"https://fs-im-kefu.7moor-fs1.com/ly/4d2c3f00-7d4c-11e5-af15-41bf63ae4ea0/1746629246668/f0508.txt;md5;fe5929df64eb2358effeb032359732e5",
|
||||
"spider":"https://fs-im-kefu.7moor-fs1.com/ly/4d2c3f00-7d4c-11e5-af15-41bf63ae4ea0/1748426350403/f0528.txt;md5;fc7b0752fe1f29b6c7a544e6af548599",
|
||||
"wallpaper":"http://王二小放牛娃牛逼.999888987.xyz","logo":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/X/main/Pictures/yellow.gif",
|
||||
|
||||
"sites":[
|
||||
|
@ -7,7 +7,7 @@
|
|||
{"key":"玩偶","name":"🤹♂️┃饭硬┃玩偶哥哥","type":3,"api":"csp_WoGGGuard","searchable":1,"quickSearch":1,"changeable":0,"ext":{"Cloud-drive":"tvfan/Cloud-drive.txt","from":"4k|auto","siteUrl":"https://www.wogg.net/","danMu":"弹"}},
|
||||
{"key":"Wogg","name":"🎩┃PG┃玩偶哥哥","type":3,"api":"csp_Wogg","quickSearch":1, "changeable":1, "filterable":1, "timeout":60, "ext":"./lib/tokenm.json$$$http://wogg.888484.xyz/$$$noproxy$$$1$$$./lib/wogg.json$$$WOGG","jar":"./pg.jar;md5;fd53509ee96e1519441cfa9f182fe66a"},
|
||||
{"key":"豆","name":"🎁┃豆瓣┃影视","type": 3, "api": "csp_DouDouGuard","indexs":1,"searchable": 0,"quickSearch": 0,"filterable": 0},
|
||||
{"key":"YGP","name":"🚀┃叨观荐影┃预告片","type":3,"api":"csp_YGPGuard","searchable":0,"quickSearch":0,"changeable":0},
|
||||
{"key":"YGP","name":"🚀┃叨观┃预告片","type":3,"api":"csp_YGPGuard","searchable":0,"quickSearch":0,"changeable":0},
|
||||
{"key":"原创","name":"🧧┃修罗┃影视","type":3,"api":"csp_YCyzGuard","timeout":15,"playerType":1,"searchable":1,"quickSearch":1,"changeable":1},
|
||||
{"key":"白白","name":"🐟┃素白┃秒播","type":3,"api":"csp_SbaibaiGuard","playerType":2,"searchable":1,"quickSearch":1,"changeable":1},
|
||||
{"key":"Guazi","name":"🍉┃瓜子┃秒播","type":3,"api":"csp_Guazi","quickSearch":1, "changeable":1, "filterable":1, "timeout":60, "ext": "","jar":"./pg.jar;md5;fd53509ee96e1519441cfa9f182fe66a"},
|
||||
|
@ -17,10 +17,11 @@
|
|||
{"key":"Lib","name":"🏈┃Libvio┃秒播","type":3,"api":"csp_LibvioGuard","searchable":1,"quickSearch":1,"changeable":1,"ext":{"Cloud-drive":"tvfan/Cloud-drive.txt","from":"4k|auto"}},
|
||||
{"key":"木耳","name":"🍄┃猫木耳┃秒播","type":1,"api":"https://json02.heimuer.xyz/api.php/provide/vod","searchable":1,"filterable":1,"changeable":1,"timeout":10,"categories":["剧情片","动作片","冒险片","同性片","喜剧片","奇幻片","恐怖片","悬疑片","惊悚片","灾难片","爱情片","犯罪片","科幻片","歌舞片","战争片","经典片","动画电影","网络电影","其他片","国产剧","港剧","韩剧","日剧","泰剧","台剧","欧美剧","新马剧","其他剧","国产综艺","港台综艺","韩国综艺","日本综艺","欧美综艺","新马泰综艺","其他综艺","古装短剧","虐恋短剧","逆袭短剧","神豪短剧","重生短剧","复仇短剧","穿越短剧","甜宠短剧","强者短剧","欧美动漫","日本动漫","韩国动漫","国产动漫","港台动漫"],"header":{"user-agent":"Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/125.0.0.0Safari/537.36"}},
|
||||
{"key":"网盘配置","name": "🐧┃网盘及彈幕┃配置","type": 3,"api": "csp_Config","searchable": 0,"changeable": 0,"ext":"./lib/tokenm.json","jar":"./pg.jar;md5;fd53509ee96e1519441cfa9f182fe66a","style": {"type": "rect","ratio": 1.5}},
|
||||
|
||||
|
||||
##PY源系列
|
||||
{"key": "苹果","name": "🍎┃小小苹果┃TV","type": 3,"api": "./py/小苹果.py","searchable": 1,"quickSearch": 1,"changeable": 1,"filterable": 1,"timeout": 60},
|
||||
{"key": "火车","name": "🚂┃火车太顺┃TV","type": 3,"api": "./py/火车太顺APP.py","searchable": 1,"quickSearch": 1,"changeable": 1,"filterable": 1,"timeout": 60},
|
||||
{"key": "热播","name": "📻┃热播影视┃TV","type": 3,"api": "./py/热播APP.py","searchable": 1,"quickSearch": 1,"changeable": 1,"filterable": 1,"timeout": 60},
|
||||
{"key": "海马","name": "🏇┃海马影视┃TV","type": 3,"api": "./py/海马影视APP.py","searchable": 1,"quickSearch": 1,"changeable": 1,"filterable": 1,"timeout": 60},
|
||||
{"key": "边缘","name": "🍨┃边缘影视┃TV","type": 3,"api": "./py/边缘影视.py","searchable": 1,"quickSearch": 1,"changeable": 1,"filterable": 1,"timeout": 60},
|
||||
{"key": "零度","name": "🐼┃零度影视┃TV","type": 3,"api": "./py/零度影视.py","searchable": 1,"quickSearch": 1,"changeable": 1,"filterable": 1,"timeout": 60},
|
||||
|
@ -65,7 +66,7 @@
|
|||
{"key":"糯米","name":"🍓糯米┃秒播","type":3,"api":"csp_NmyswvGuard","timeout":10,"searchable":1,"quickSearch":1,"changeable":1},
|
||||
{"key":"文采","name":"💮文采┃秒播","type":3,"api":"csp_JpysGuard","timeout":10,"playerType":2,"searchable":1,"quickSearch":1,"changeable":1},
|
||||
{"key":"溢彩","name":"💡溢彩┃秒播","type":3,"api":"csp_AppSxGuard","timeout":10,"searchable":1,"quickSearch":1,"changeable":1,"ext":"rfOb1uAWbkRHp7hdxprG9un3+TfN183v1zIyaYDoDAIaLw5L8Dp8+v88LrEL3dBzrmWbdMBX0WNm7HtkQuw0AIzUurGBVyPqCKzDmbriATuukhctJlsLo8KxCw=="},
|
||||
{"key":"Lib","name":"🌟立播┃秒播","type":3,"api":"csp_LibvioGuard","timeout":10,"searchable":1,"quickSearch":1,"changeable":1,"ext":{"Cloud-drive":"tvfan/Cloud-drive.txt","from":"4k|auto"}},
|
||||
{"key":"Lib","name": "🌟立播┃秒播","type":3,"api":"csp_LibvioGuard","timeout":10,"searchable":1,"quickSearch":1,"changeable":1,"ext":{"Cloud-drive":"tvfan/Cloud-drive.txt","from":"4k|auto"}},
|
||||
{"key":"zxzj","name":"🍊在线┃秒播","type":3,"api":"csp_ZxzjGuard","timeout":10,"searchable":1,"quickSearch":1,"changeable":1,"ext":"https://www.zxzjhd.com/"},
|
||||
{"key":"厂长","name":"📔厂长┃不卡","type":3,"api":"csp_NewCzGuard","timeout":10,"playerType":2,"searchable":1,"quickSearch":1,"changeable":1},
|
||||
{"key":"比特","name":"🍄比特┃手机","type":3,"api":"csp_BttwooGuard","timeout":10,"searchable":1,"quickSearch":1,"changeable":1},
|
||||
|
@ -240,158 +241,94 @@
|
|||
|
||||
"lives": [
|
||||
{"name": "🦸┃tangTV直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/JunTV/refs/heads/main/output/result.m3u","playerType":1},
|
||||
{"name": "👟┃chaoMAN直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/SuperMAN/refs/heads/main/output/result.m3u","playerType":1},
|
||||
|
||||
{"name": "🛬┃极速直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/iptv_api/refs/heads/main/live_ipv4.m3u","playerType":1},
|
||||
{"name": "🥮┃666直播","type": 0,"url": "http://api.mytv666.top/lives/free.php?type=txt","playerType":1},
|
||||
{"name": "📢┃xTV直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/X/refs/heads/main/live/live_ipv4.m3u","playerType":1},
|
||||
{"name": "👟┃SuperMAN直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/SuperMAN/refs/heads/main/output/result.m3u","playerType":1},
|
||||
{"name": "🥮┃aTV直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/aTV/refs/heads/master/output/result.m3u","playerType":1},
|
||||
{"name": "🛬┃iptv_api直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/iptv_api/refs/heads/main/output/live_ipv4.m3u","playerType":1},
|
||||
{"name": "📺┃vbskycn直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/vbskycn/iptv/master/tv/iptv4.m3u","playerType":1},
|
||||
{"name": "🎃┃全国秒播TV","type":0,"url":"http://live.nctv.top/x.txt","playerType":1},
|
||||
{"name": "🎳┃咪咕直播","type": 0,"url": "https://cnb.cool/junchao.tang/llive/-/git/raw/main/咪咕直播","playerType":1},
|
||||
{"name": "🪭┃晓峰直播","type": 0,"url": "http://晓峰.azip.dpdns.org:5008/?type=m3u","playerType":1},
|
||||
|
||||
//{"name": "🪭┃晓峰直播","type": 0,"url": "http://晓峰.azip.dpdns.org:5008/?type=m3u","playerType":1},
|
||||
{"name": "🍳┃台湾全岛直播","api": "csp_MQiTV","jar": "./jar/custom_spider.jar","ext": "https://59.125.210.231:4433"},
|
||||
{"name": "🤿┃IPTV_SuperA直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/IPTV_SuperA/refs/heads/main/output/result.m3u","playerType":1},
|
||||
{"name": "🪂┃IPTV_SuperB直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/IPTV_SuperB/refs/heads/main/output/live_ipv4.m3u","playerType":1},
|
||||
{"name": "🎒┃JunTV直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/girl/refs/heads/master/tv/iptv4.m3u","playerType":1},
|
||||
{"name": "🥎┃IPTV_SuperD直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/iptv_SuperD/refs/heads/dist/live.m3u","playerType":1},
|
||||
|
||||
{"name": "🎒┃girlTV直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/girl/refs/heads/master/tv/iptv4.m3u","playerType":1},
|
||||
{"name": "🏮┃WorkTV直播","type":0,"url":"https://cnb.cool/junchao.tang/llive/-/git/raw/main/电视.txt","playerType":1},
|
||||
{"name": "🥩┃luck9V直播","type":0,"url":"https://cnb.cool/junchao.tang/llive/-/git/raw/main/luck9.txt","playerType":1},
|
||||
{"name": "🍬┃assets直播","type":0,"url":"http://1.94.31.214/live/livelite.txt","playerType":1},
|
||||
{"name": "🧀┃香港直播","type":0,"url":"https://smart.pendy.dpdns.org/m3u/Smart.m3u","playerType":1},
|
||||
{"name": "🎃┃中港台馬電視台頻道","type":0,"url":"http://209.141.59.146:50509/?type=m3u","playerType":1},
|
||||
{"name": "🛺┃knnnn直播电视","type": 3,"api": "https://framagit.org/knnnn/n/-/raw/main/j/kzb.py","ext": {}},
|
||||
{"name": "🥎┃IPTV_SuperD直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/iptv_SuperD/refs/heads/dist/live.m3u","playerType":1},
|
||||
{"name": "🧀┃香港台湾秒播","type":0,"url":"https://smart.pendy.dpdns.org/m3u/Smart.m3u","playerType":1},
|
||||
{"name": "🎃┃uploads頻道","type":0,"url":"https://upld.zone.id/uploads/q9iq9e5iq/lvse.txt","playerType":1},
|
||||
//{"name": "🛺┃knnnn直播电视","type": 3,"api": "https://framagit.org/knnnn/n/-/raw/main/j/kzb.py","ext": {}},
|
||||
{"name": "🐮┃牛牛直播","type" : 0,"url" : "https://web.banye.tech:7777/tv/hlj.txt","ua" : "okhttp/3.15","epg" : "http://127.0.0.1:10079/p/0/proxy/http://epg.112114.xyz/?ch={name}&date={date}","logo" : "http://127.0.0.1:10079/p/0/proxy/https://epg.112114.xyz/logo/{name}.png"},
|
||||
{"name": "🐝┃蜜蜂直播","type" : 0,"url" : "https://iptv.catvod.com/tv.m3u","ua" : "okhttp/3.15","epg" : "http://127.0.0.1:10079/p/0/proxy/http://epg.112114.xyz/?ch={name}&date={date}","logo" : "http://127.0.0.1:10079/p/0/proxy/https://epg.112114.xyz/logo/{name}.png"},
|
||||
{"name": "🍳┃SMT直播","type": 3,"api": "https://gh.tryxd.cn/https://raw.githubusercontent.com/doube-ba/Sub/refs/heads/main/live/live_smt_proxy_001.py","ext": {"proxy": {"http": "http://127.0.0.1:10809","https": "http://127.0.0.1:10809"}}},
|
||||
//{"name": "🍳┃SMT直播","type": 3,"api": "https://gh.tryxd.cn/https://raw.githubusercontent.com/doube-ba/Sub/refs/heads/main/live/live_smt_proxy_001.py","ext": {"proxy": {"http": "http://127.0.0.1:10809","https": "http://127.0.0.1:10809"}}},
|
||||
{"name": "🍔┃hostemail直播","type" : 0,"url" : "https://gh.tryxd.cn/https://raw.githubusercontent.com/hostemail/cdn/main/live/tv.txt","ua" : "okhttp/3.15","epg" : "http://127.0.0.1:10079/p/0/proxy/http://epg.112114.xyz/?ch={name}&date={date}","logo" : "http://127.0.0.1:10079/p/0/proxy/https://epg.112114.xyz/logo/{name}.png"},
|
||||
|
||||
{"name": "🦆┃SuperMAN直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/SuperMAN/refs/heads/main/output/user_result.txt","playerType":1},
|
||||
{"name": "💤┃JunTV直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/JunTV/refs/heads/main/output/user_result.txt","playerType":1},
|
||||
|
||||
|
||||
{"name": "🛩️┃沐佬直播","type": 3,"api": "https://json.doube.eu.org/python/live_kzb.py","ext": "68747470733A2F2F6A7A623132332E7A68756261696368656E672E636F6D2F70726F642D6170692F697074762F676574497074764C697374"},
|
||||
{"name": "🩰┃Meroser直播","type": 0,"url": "https://gitlab.com/Meroser/IPTV/-/raw/main/IPTV-demo.m3u","playerType":1},
|
||||
{"name": "🍾┃Kilvn直播","type":0,"url":"https://live.kilvn.com/iptv.m3u","playerType":1},
|
||||
{"name": "🥨┃pxiptv直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/pxiptv/live/main/iptv.m3u","playerType":1},
|
||||
{"name": "🐶┃jun直播","type": 0,"url": "https://cnb.cool/junchao.tang/llive/-/git/raw/main/Alan_result.txt","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
{"name": "🥭┃aktvspace直播","type": 0,"url": "http://aktv.space/live.m3u","playerType":1},
|
||||
{"name": "🍔┃IPTV_auto直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/IPTV/main/live_ipv4.m3u","playerType":1},
|
||||
//{"name": "🥭┃aktvspace直播","type": 0,"url": "http://aktv.space/live.m3u","playerType":1},
|
||||
{"name": "🍔┃IPTV_auto直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/IPTV/main/live_ipv4.m3u","playerType":1},
|
||||
{"name": "🎏┃LITV直播","type": 3,"api": "https://gh.tryxd.cn/https://raw.githubusercontent.com/qingtingjjjjjjj/iptv-auto-update/main/my.txt","ext": {"proxy": {"http": "http://127.0.0.1:10809","https": "http://127.0.0.1:10809"}}},
|
||||
{"name": "🏎️┃A自家源直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/Collect-IPTV/refs/heads/main/mylive.m3u","playerType":1},
|
||||
{"name": "🚗┃X自家源直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/X/refs/heads/main/live/live.m3u","playerType":1},
|
||||
{"name": "🚕┃D自家源直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/X/main/live.m3u","playerType":1},
|
||||
{"name": "📢┃PG直播","type": 0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/pg/refs/heads/main/live.m3u","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
{"name": "🐻┃台湾直播","type":0,"url":"http://cccccccoccccccc.ccccocccc.cc/uploads/TW.txt","playerType":1},
|
||||
{"name": "🤗┃Biptv直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/X/refs/heads/main/live/biptv.txt","playerType":1},
|
||||
{"name": "🐻┃MytvSuper直播","type":0,"url":"https://cnb.cool/junchao.tang/llive/-/git/raw/main/MytvSuper.m3u","playerType":1},
|
||||
//{"name": "🤗┃Biptv直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/X/refs/heads/main/live/biptv.txt","playerType":1},
|
||||
{"name": "🧧┃ITV直播","url": "https://cnb.cool/junchao.tang/llive/-/git/raw/main/itv.txt","epg": "http://epg.51zmt.top:8000/e.xml","ua": "okhttp/3.15","catchup": {"type": "append","replace": "livemode=1,livemode=4","source": "&starttime=${(b)yyyyMMdd'T'HHmm}00.00Z&endtime=${(e)yyyyMMdd'T'HHmm}00.00Z"}},
|
||||
{"name": "🐻┃tvzb直播","type":0,"url":"https://cnb.cool/junchao.tang/llive/-/git/raw/main/tvzb.txt","playerType":1},
|
||||
{"name": "🐸┃Yuanz港·澳·台直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com//alantang1977/yuanzl77/refs/heads/main/live.m3u","playerType":1},
|
||||
{"name": "🥨┃lalifeier-IPTV直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/lalifeier/IPTV/main/m3u/IPTV.m3u","playerType":1},
|
||||
{"name": "👑┃big直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/big-mouth-cn/tv/main/iptv-ok.m3u","playerType":1},
|
||||
{"name": "🤿┃mytvsources直播","type":0,"url":"https://codeberg.org/alfredisme/mytvsources/raw/branch/main/mylist-ipv6.m3u","playerType":1},{"name": "🍵┃PLTV直播","type":0,"url":"https://codeberg.org/lxxcp/live/raw/branch/main/gsdx.txt","playerType":1},
|
||||
{"name": "🏮┃codeberg·IPTV直播","type":0,"url":"https://codeberg.org/sy147258/iptv/raw/branch/main/电视","playerType":1},
|
||||
{"name": "🤿┃mytvsources直播","type":0,"url":"https://codeberg.org/alfredisme/mytvsources/raw/branch/main/mylist-ipv6.m3u","playerType":1},
|
||||
{"name": "🍵┃中国IPTV直播","type":0,"url":"https://cnb.cool/junchao.tang/llive/-/git/raw/main/中国IPTV","playerType":1},
|
||||
//{"name": "🏮┃codeberg·IPTV直播","type":0,"url":"https://codeberg.org/sy147258/iptv/raw/branch/main/电视","playerType":1},
|
||||
{"name": "🚌┃hipy直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/hjdhnx/hipy-sniffer/refs/heads/main/static/lives/lives.txt","playerType":1},
|
||||
{"name": "🚎┃xhztv·IPTV直播","type":0,"url":"http://xhztv.top/zbc.txt","playerType":1},
|
||||
{"name": "🚑┃auto-iptv直播","type":0,"url":"http://47.120.41.246:8899/zb.txt","playerType":1},
|
||||
{"name": "😁┃Gather港·澳·台","type":0,"url":"https://tv.iill.top/m3u/MyTV","playerType":1},
|
||||
{"name": "🍌┃Gather电视直播","type":0,"url":"https://tv.iill.top/m3u/Gather","playerType":1},
|
||||
{"name": "🐲┃Gather网络直播","type":0,"url":"https://tv.iill.top/m3u/Live","playerType":1},
|
||||
{"name": "🌞┃日后港·澳·台","type": 0,"url": "http://rihou.cc:567/gggg.nzk","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
{"name": "🔥┃野火港·澳·韩·台直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/tianya7981/jiekou/refs/heads/main/野火959","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
{"name": "🍜┃mytv港·澳·韩·台直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/qingtingjjjjjjj/iptv-auto-update/main/my.txt","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
{"name": "🥬┃BOX港·澳·韩·台直播","type": 0,"url": "http://8.138.7.223/live.txt","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
{"name": "🐏┃Live肥羊直播","type": 3,"api": "csp_Feiyang","url": "tv.m3u","ext": "https://gh.tryxd.cn/https://raw.githubusercontent.com/lystv/fmapp/ok/apk/allinone/v7/allinone;md5;https://gh.tryxd.cn/https://raw.githubusercontent.com/lystv/fmapp/ok/apk/allinone/v7/md5","jar": "https://gh.tryxd.cn/https://raw.githubusercontent.com/FongMi/CatVodSpider/main/jar/custom_spider.jar"},
|
||||
//{"name": "🥬┃BOX港·澳·韩·台直播","type": 0,"url": "http://8.138.7.223/live.txt","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
//{"name": "🐏┃Live肥羊直播","type": 3,"api": "csp_Feiyang","url": "tv.m3u","ext": "https://gh.tryxd.cn/https://raw.githubusercontent.com/lystv/fmapp/ok/apk/allinone/v7/allinone;md5;https://gh.tryxd.cn/https://raw.githubusercontent.com/lystv/fmapp/ok/apk/allinone/v7/md5","jar": "https://gh.tryxd.cn/https://raw.githubusercontent.com/FongMi/CatVodSpider/main/jar/custom_spider.jar"},
|
||||
{"name": "🐤┃Guovin直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/Guovin/iptv-api/gd/output/result.m3u","playerType": 1,"epg": "http://epg.51zmt.top:8000/api/diyp/?ch={name}&date={date}","logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
|
||||
{"name": "🎳┃judy直播","type": 0,"url": "https://smart.pendy.dpdns.org/m3u/merged_judy.m3u","epg": "http://epg.51zmt.top:8000/api/diyp/?ch={name}&date={date}","logo": "https://epg.iill.top/logo/{name}.png","ua": "xieanqishiwoerzi/0.0.1","timeout": 10,"playerType": 2},
|
||||
{"name": "🧸┃CCSH直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/CCSH/IPTV/main/live.m3u","playerType":1},
|
||||
{"name": "🪭┃IPTV-CCSH直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/IPTV-CCSH/refs/heads/main/live.m3u","playerType":1},
|
||||
|
||||
{"name": "🛺┃IPTV-CCSH直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/IPTV-CCSH/refs/heads/main/live.m3u","playerType":1},
|
||||
{"name": "🐏┃ssili126直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/ssili126/tv/main/itvlist.txt","playerType":1},
|
||||
{"name": "〽️┃欧歌电视","type": 0,"url": "https://xn--pggp-rp5imh.v.nxog.top/m//tv/","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
//{"name": "〽️┃欧歌电视","type": 0,"url": "https://xn--pggp-rp5imh.v.nxog.top/m//tv/","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
{"name": "🎂┃suxuang直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/suxuang/myIPTV/main/ipv6.m3u","playerType":1},
|
||||
{"name": "👟┃iptv365直播","type": 0,"url": "https://live.iptv365.org/live.txt","playerType":1},
|
||||
{"name": "😎┃咪咕直播","type": 0,"url": "https://yun.urldwz.com/f/Q6y3ca/migu.m3u","timeout": 10},
|
||||
{"name": "🛍️┃myernestlu直播","type": 0,"url": "https://myernestlu.github.io/zby.txt","playerType":1},
|
||||
{"name": "🛍️┃zbefine直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/zbefine/iptv/main/iptv.m3u","playerType":1},
|
||||
{"name": "🛍️┃vamoschuck直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/vamoschuck/TV/main/M3U","playerType":1},
|
||||
{"name": "🛍️┃hong_kong直播","type": 0,"url": "https://epg.pw/test_channels_hong_kong.m3u","playerType":1},
|
||||
//{"name": "🛍️┃hong_kong直播","type": 0,"url": "https://epg.pw/test_channels_hong_kong.m3u","playerType":1},
|
||||
{"name": "🛍️┃zhiboyuan直播","type": 0,"url": "https://gitee.com/xxy002/zhiboyuan/raw/master/dsy","playerType":1},
|
||||
{"name": "🛍️┃channels直播","type": 0,"url": "https://epg.pw/test_channels.m3u","playerType":1},
|
||||
{"name": "🛍️┃Free-TV直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/Free-TV/IPTV/master/playlist.m3u8","playerType":1},
|
||||
{"name": "⚕️┃iptv粤Live","type": 0,"url": "http://box.1890222.xyz:8081/iptv/live.m3u","playerType":1},
|
||||
{"name": "🐰┃wwb521粤港澳","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/wwb521/live/main/tv.m3u","playerType":1},
|
||||
{"name": "🍡┃kimwang1978直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/kimwang1978/collect-tv-txt/main/merged_output_simple.txt","playerType":1},
|
||||
{"name": "✨┃PGTV直播","type": 0,"url": "https://git.gra.phite.ro/alantang/pg/raw/branch/main/live.m3u","playerType":1},
|
||||
//{"name": "🍡┃kimwang1978直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/kimwang1978/collect-tv-txt/main/merged_output_simple.txt","playerType":1},
|
||||
{"name": "✨┃555TV直播","type": 0,"url": "http://rihou.cc:555/gggg.nzk","playerType":1},
|
||||
{"name": "🎁┃migu直播","type": 0,"url": "https://json.doube.eu.org/live/migu/Sub.php","playerType":1},
|
||||
{"name": "🍟┃Kimentanm直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/Kimentanm/aptv/master/m3u/iptv.m3u","playerType":1},
|
||||
//{"name": "🍟┃Kimentanm直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/Kimentanm/aptv/master/m3u/iptv.m3u","playerType":1},
|
||||
{"name": "🎗️┃butterfly直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/butterfly202400/dsy/refs/heads/main/ln2403.m3u","playerType":1},
|
||||
{"name": "🐸┃全面直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/Ftindy/IPTV-URL/main/Collect.m3u","playerType":1},
|
||||
{"name": "❤️┃春盈直播","type": 0,"url": "http://home.jundie.top:81/Cat/tv/live.txt","playerType":1},
|
||||
{"name": "🤡┃全球直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/Free-TV/IPTV/master/playlist.m3u8","playerType":1},
|
||||
{"name": "📺┃vbskycn直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/vbskycn/iptv/master/tv/iptv4.m3u","playerType":1},
|
||||
{"name": "🍭┃vbskycn直播","type": 0,"url": "https://live.zbds.top/tv/iptv4.txt","playerType":1},
|
||||
{"name": "🦐┃龙伊直播","type":0,"url":"https://龙伊.top/直播","playerType":1,"epg":"https://api.龙伊.top/epg/epg.php?ch={name}&date={date}","logo":"https://api.龙伊.top/epg/images/{name}.png"},
|
||||
//{"name": "🦐┃龙伊直播","type":0,"url":"https://龙伊.top/直播","playerType":1,"epg":"https://api.龙伊.top/epg/epg.php?ch={name}&date={date}","logo":"https://api.龙伊.top/epg/images/{name}.png"},
|
||||
{"name": "🍉┃fanmingming直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/fanmingming/live/refs/heads/main/tv/m3u/ipv6.m3u","playerType":1},
|
||||
{"name": "🎏┃范明直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/fanmingming/live/refs/heads/main/tv/m3u/ipv6.m3u","playerType":1},
|
||||
{"name": "✍️┃qingwen07直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/qingwen07/awesome-iptv/main/tvbox_live_all.txt","playerType":1},
|
||||
{"name": "🔢┃serv00直播","type":0,"url":"https://a90120.serv00.net/anbox/p3plink.txt","playerType":1},
|
||||
{
|
||||
"name": "4GTV - 台湾",
|
||||
"url": "docker.livednow.dpdns.org/?type=m3u",
|
||||
"ua": "judy/5.2.1"
|
||||
},
|
||||
{
|
||||
"name": "香港视频 - 安卓",
|
||||
"url": "https://smart.pendy.dpdns.org/m3u/MytvSuper.m3u",
|
||||
"ua": "judy/5.2.1"
|
||||
},
|
||||
{
|
||||
"name": "鲍鱼",
|
||||
"type": 0,
|
||||
"url": "http://lisha521.dynv6.net.fh4u.org/tv.txt",
|
||||
"playerType": 1
|
||||
},
|
||||
{
|
||||
"name": "蝴蝶",
|
||||
"type": 0,
|
||||
"url": "http://lisha521.dynv6.net.fh4u.org/iptv.txt",
|
||||
"epg": "http://epg.51zmt.top:8000/api/diyp/?ch={name}&date={date}",
|
||||
"logo": "https://epg.iill.top/logo/{name}.png",
|
||||
"ua": "okhttp/3.15,AptvPlayer/1.4.0",
|
||||
"timeout": 10,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"name": "一线天",
|
||||
"type": 0,
|
||||
"url": "http://lisha521.dynv6.net.fh4u.org/hlj.txt",
|
||||
"ua": "okhttp/3.15",
|
||||
"epg": "http://127.0.0.1:10079/p/0/proxy/http://epg.112114.xyz/?ch={name}&date={date}",
|
||||
"logo": "http://127.0.0.1:10079/p/0/proxy/https://epg.112114.xyz/logo/{name}.png"
|
||||
},
|
||||
{
|
||||
"name": "青龙",
|
||||
"type": 0,
|
||||
"url": "http://rihou.cc:555/gggg.nzk",
|
||||
"playerType": 1,
|
||||
"ua": "okhttp/3.15",
|
||||
"epg": "http://epg.112114.xyz/?ch={name}&date={date}",
|
||||
"logo": "https://epg.112114.eu.org/logo/{name}.png"
|
||||
},
|
||||
{
|
||||
"name": "白虎",
|
||||
"type": 0,
|
||||
"url": "http://lisha521.dynv6.net.fh4u.org/live.txt",
|
||||
"playerType": 1,
|
||||
"ua": "okhttp/3.15",
|
||||
"epg": "http://epg.112114.xyz/?ch={name}&date={date}",
|
||||
"logo": "https://epg.112114.xyz/logo/{name}.png"
|
||||
},
|
||||
{
|
||||
"name": "馒头",
|
||||
"type": 0,
|
||||
"url": "http://127.0.0.1:10079/c/3600/null/http://lisha521.dynv6.net.fh4u.org/live1.txt",
|
||||
"playerType": 2,
|
||||
"ua": "okhttp/3.15",
|
||||
"epg": "http://epg.112114.xyz/?ch={name}&date={date}",
|
||||
"logo": "https://epg.112114.xyz/logo/{name}.png"
|
||||
},
|
||||
{"name": "👓┃gshtwy直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/gshtwy/MyTv/refs/heads/main/MyTv.m3u","playerType":1}],
|
||||
{"name": "🔢┃Hotel_iptv直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/Hotel_iptv/refs/heads/main/itvlist.txt","playerType":1},
|
||||
{"name": "👓┃gshtwy直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/gshtwy/MyTv/refs/heads/main/MyTv.m3u","playerType":1}],
|
||||
|
||||
"hosts": [
|
||||
"cache.ott.ystenlive.itv.cmvideo.cn=itv.dns.xuran1983.cn",
|
||||
|
|
142
aTV.json
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"spider":"https://fs-im-kefu.7moor-fs1.com/ly/4d2c3f00-7d4c-11e5-af15-41bf63ae4ea0/1746629246668/f0508.txt;md5;fe5929df64eb2358effeb032359732e5",
|
||||
"spider":"https://fs-im-kefu.7moor-fs1.com/ly/4d2c3f00-7d4c-11e5-af15-41bf63ae4ea0/1748426350403/f0528.txt;md5;fc7b0752fe1f29b6c7a544e6af548599",
|
||||
"wallpaper":"http://王二小放牛娃牛逼.999888987.xyz","logo":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/X/main/Pictures/yellow.gif",
|
||||
|
||||
"sites":[
|
||||
|
@ -88,148 +88,94 @@
|
|||
{"key":"csp_Anime1","name":"📯SP┃日本┃动漫","type":3,"api":"csp_Anime1","searchable":1,"quickSearch":1,"filterable":1}],
|
||||
|
||||
"lives": [
|
||||
{"name": "🦸┃tang直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/JunTV/refs/heads/main/output/result.m3u","playerType":1},
|
||||
{"name": "👟┃chao直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/SuperMAN/refs/heads/main/output/result.m3u","playerType":1},
|
||||
{"name": "🛬┃极速直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/iptv_api/refs/heads/main/live_ipv4.m3u","playerType":1},
|
||||
{"name": "🦸┃tangTV直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/JunTV/refs/heads/main/output/result.m3u","playerType":1},
|
||||
{"name": "📢┃JunTV直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/X/refs/heads/main/live/live_ipv4.m3u","playerType":1},
|
||||
{"name": "👟┃chaoMAN直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/SuperMAN/refs/heads/main/output/result.m3u","playerType":1},
|
||||
{"name": "🛬┃iptv_api直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/iptv_api/refs/heads/main/output/live_ipv4.m3u","playerType":1},
|
||||
{"name": "📺┃vbskycn直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/vbskycn/iptv/master/tv/iptv4.m3u","playerType":1},
|
||||
{"name": "🎃┃全国秒播TV","type":0,"url":"http://live.nctv.top/x.txt","playerType":1},
|
||||
{"name": "🥮┃666直播","type": 0,"url": "http://api.mytv666.top/lives/free.php?type=txt","playerType":1},
|
||||
{"name": "🎳┃咪咕直播","type": 0,"url": "https://cnb.cool/junchao.tang/llive/-/git/raw/main/咪咕直播","playerType":1},
|
||||
{"name": "🪭┃晓峰直播","type": 0,"url": "http://晓峰.azip.dpdns.org:5008/?type=m3u","playerType":1},
|
||||
{"name": "🍳┃台湾全岛直播","api": "csp_MQiTV","jar": "./jar/custom_spider.jar","ext": "https://59.125.210.231:4433"},
|
||||
{"name": "🤿┃IPTV_SuperA直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/IPTV_SuperA/refs/heads/main/output/result.m3u","playerType":1},
|
||||
{"name": "🪂┃IPTV_SuperB直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/IPTV_SuperB/refs/heads/main/output/live_ipv4.m3u","playerType":1},
|
||||
{"name": "🎒┃JunTV直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/girl/refs/heads/master/tv/iptv4.m3u","playerType":1},
|
||||
{"name": "🥎┃IPTV_SuperD直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/iptv_SuperD/refs/heads/dist/live.m3u","playerType":1},
|
||||
|
||||
{"name": "🎒┃girlTV直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/girl/refs/heads/master/tv/iptv4.m3u","playerType":1},
|
||||
{"name": "🏮┃WorkTV直播","type":0,"url":"https://cnb.cool/junchao.tang/llive/-/git/raw/main/电视.txt","playerType":1},
|
||||
{"name": "🥩┃luck9V直播","type":0,"url":"https://cnb.cool/junchao.tang/llive/-/git/raw/main/luck9.txt","playerType":1},
|
||||
//{"name": "🍬┃assets直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/yaoxieyoulei/YYKM_assets/refs/heads/main/webview.m3u","playerType":1},
|
||||
{"name": "🧀┃香港直播","type":0,"url":"https://smart.pendy.dpdns.org/m3u/Smart.m3u","playerType":1},
|
||||
{"name": "🎃┃中港台馬電視台頻道","type":0,"url":"http://209.141.59.146:50509/?type=m3u","playerType":1},
|
||||
{"name": "🛺┃knnnn直播电视","type": 3,"api": "https://framagit.org/knnnn/n/-/raw/main/j/kzb.py","ext": {}},
|
||||
{"name": "🥎┃IPTV_SuperD直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/iptv_SuperD/refs/heads/dist/live.m3u","playerType":1},
|
||||
{"name": "🍬┃assets直播","type":0,"url":"http://1.94.31.214/live/livelite.txt","playerType":1},
|
||||
{"name": "🧀┃香港台湾秒播","type":0,"url":"https://smart.pendy.dpdns.org/m3u/Smart.m3u","playerType":1},
|
||||
//{"name": "🎃┃中港台馬電視台頻道","type":0,"url":"http://209.141.59.146:50509/?type=m3u","playerType":1},
|
||||
//{"name": "🛺┃knnnn直播电视","type": 3,"api": "https://framagit.org/knnnn/n/-/raw/main/j/kzb.py","ext": {}},
|
||||
{"name": "🐮┃牛牛直播","type" : 0,"url" : "https://web.banye.tech:7777/tv/hlj.txt","ua" : "okhttp/3.15","epg" : "http://127.0.0.1:10079/p/0/proxy/http://epg.112114.xyz/?ch={name}&date={date}","logo" : "http://127.0.0.1:10079/p/0/proxy/https://epg.112114.xyz/logo/{name}.png"},
|
||||
{"name": "🐝┃蜜蜂直播","type" : 0,"url" : "https://iptv.catvod.com/tv.m3u","ua" : "okhttp/3.15","epg" : "http://127.0.0.1:10079/p/0/proxy/http://epg.112114.xyz/?ch={name}&date={date}","logo" : "http://127.0.0.1:10079/p/0/proxy/https://epg.112114.xyz/logo/{name}.png"},
|
||||
{"name": "🍳┃SMT直播","type": 3,"api": "https://gh.tryxd.cn/https://raw.githubusercontent.com/doube-ba/Sub/refs/heads/main/live/live_smt_proxy_001.py","ext": {"proxy": {"http": "http://127.0.0.1:10809","https": "http://127.0.0.1:10809"}}},
|
||||
//{"name": "🍳┃SMT直播","type": 3,"api": "https://gh.tryxd.cn/https://raw.githubusercontent.com/doube-ba/Sub/refs/heads/main/live/live_smt_proxy_001.py","ext": {"proxy": {"http": "http://127.0.0.1:10809","https": "http://127.0.0.1:10809"}}},
|
||||
{"name": "🍔┃hostemail直播","type" : 0,"url" : "https://gh.tryxd.cn/https://raw.githubusercontent.com/hostemail/cdn/main/live/tv.txt","ua" : "okhttp/3.15","epg" : "http://127.0.0.1:10079/p/0/proxy/http://epg.112114.xyz/?ch={name}&date={date}","logo" : "http://127.0.0.1:10079/p/0/proxy/https://epg.112114.xyz/logo/{name}.png"},
|
||||
{"name": "🦆┃tang直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/JunTV/refs/heads/main/output/user_result.txt","playerType":1},
|
||||
|
||||
{"name": "🦆┃SuperMAN直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/SuperMAN/refs/heads/main/output/user_result.txt","playerType":1},
|
||||
{"name": "💤┃JunTV直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/JunTV/refs/heads/main/output/user_result.txt","playerType":1},
|
||||
|
||||
{"name": "🩰┃Meroser直播","type": 0,"url": "https://gitlab.com/Meroser/IPTV/-/raw/main/IPTV-demo.m3u","playerType":1},
|
||||
{"name": "🍾┃Kilvn直播","type":0,"url":"https://live.kilvn.com/iptv.m3u","playerType":1},
|
||||
{"name": "🥨┃pxiptv直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/pxiptv/live/main/iptv.m3u","playerType":1},
|
||||
{"name": "🐶┃jun直播","type": 0,"url": "https://cnb.cool/junchao.tang/llive/-/git/raw/main/Alan_result.txt","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
{"name": "🥭┃aktvspace直播","type": 0,"url": "http://aktv.space/live.m3u","playerType":1},
|
||||
{"name": "🍔┃IPTV_auto直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/IPTV/main/live_ipv4.m3u","playerType":1},
|
||||
//{"name": "🥭┃aktvspace直播","type": 0,"url": "http://aktv.space/live.m3u","playerType":1},
|
||||
{"name": "🍔┃IPTV_auto直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/IPTV/main/live_ipv4.m3u","playerType":1},
|
||||
{"name": "🎏┃LITV直播","type": 3,"api": "https://gh.tryxd.cn/https://raw.githubusercontent.com/qingtingjjjjjjj/iptv-auto-update/main/my.txt","ext": {"proxy": {"http": "http://127.0.0.1:10809","https": "http://127.0.0.1:10809"}}},
|
||||
{"name": "🏎️┃A自家源直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/Collect-IPTV/refs/heads/main/mylive.m3u","playerType":1},
|
||||
{"name": "🚗┃B自家源直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/X/refs/heads/main/live/live.m3u","playerType":1},
|
||||
{"name": "🚕┃D自家源直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/X/main/live.m3u","playerType":1},
|
||||
{"name": "📢┃联合直播","type": 0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/pg/refs/heads/main/live.m3u","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
{"name": "🐻┃台湾直播","type":0,"url":"http://cccccccoccccccc.ccccocccc.cc/uploads/TW.txt","playerType":1},
|
||||
{"name": "🤗┃Biptv直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/X/refs/heads/main/live/biptv.txt","playerType":1},
|
||||
{"name": "📢┃PG直播","type": 0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/pg/refs/heads/main/live.m3u","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
//{"name": "🐻┃台湾直播","type":0,"url":"http://cccccccoccccccc.ccccocccc.cc/uploads/TW.txt","playerType":1},
|
||||
//{"name": "🤗┃Biptv直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/X/refs/heads/main/live/biptv.txt","playerType":1},
|
||||
{"name": "🧧┃ITV直播","url": "https://cnb.cool/junchao.tang/llive/-/git/raw/main/itv.txt","epg": "http://epg.51zmt.top:8000/e.xml","ua": "okhttp/3.15","catchup": {"type": "append","replace": "livemode=1,livemode=4","source": "&starttime=${(b)yyyyMMdd'T'HHmm}00.00Z&endtime=${(e)yyyyMMdd'T'HHmm}00.00Z"}},
|
||||
{"name": "🐻┃tvzb直播","type":0,"url":"https://cnb.cool/junchao.tang/llive/-/git/raw/main/tvzb.txt","playerType":1},
|
||||
{"name": "🐸┃Yuanz港·澳·台直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com//alantang1977/yuanzl77/refs/heads/main/live.m3u","playerType":1},
|
||||
{"name": "🥨┃lalifeier-IPTV直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/lalifeier/IPTV/main/m3u/IPTV.m3u","playerType":1},
|
||||
{"name": "👑┃big直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/big-mouth-cn/tv/main/iptv-ok.m3u","playerType":1},
|
||||
{"name": "🤿┃mytvsources直播","type":0,"url":"https://codeberg.org/alfredisme/mytvsources/raw/branch/main/mylist-ipv6.m3u","playerType":1},{"name": "🍵┃PLTV直播","type":0,"url":"https://codeberg.org/lxxcp/live/raw/branch/main/gsdx.txt","playerType":1},
|
||||
{"name": "🏮┃codeberg·IPTV直播","type":0,"url":"https://codeberg.org/sy147258/iptv/raw/branch/main/电视","playerType":1},
|
||||
{"name": "🤿┃mytvsources直播","type":0,"url":"https://codeberg.org/alfredisme/mytvsources/raw/branch/main/mylist-ipv6.m3u","playerType":1},
|
||||
//{"name": "🍵┃PLTV直播","type":0,"url":"https://codeberg.org/lxxcp/live/raw/branch/main/gsdx.txt","playerType":1},
|
||||
//{"name": "🏮┃codeberg·IPTV直播","type":0,"url":"https://codeberg.org/sy147258/iptv/raw/branch/main/电视","playerType":1},
|
||||
{"name": "🚌┃hipy直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/hjdhnx/hipy-sniffer/refs/heads/main/static/lives/lives.txt","playerType":1},
|
||||
{"name": "🚎┃xhztv·IPTV直播","type":0,"url":"http://xhztv.top/zbc.txt","playerType":1},
|
||||
{"name": "🚑┃auto-iptv直播","type":0,"url":"http://47.120.41.246:8899/zb.txt","playerType":1},
|
||||
{"name": "😁┃Gather港·澳·台","type":0,"url":"https://tv.iill.top/m3u/MyTV","playerType":1},
|
||||
{"name": "🍌┃Gather电视直播","type":0,"url":"https://tv.iill.top/m3u/Gather","playerType":1},
|
||||
{"name": "🐲┃Gather网络直播","type":0,"url":"https://tv.iill.top/m3u/Live","playerType":1},
|
||||
{"name": "🌞┃日后港·澳·台","type": 0,"url": "http://rihou.cc:567/gggg.nzk","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
{"name": "🔥┃野火港·澳·韩·台直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/tianya7981/jiekou/refs/heads/main/野火959","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
{"name": "🍜┃mytv港·澳·韩·台直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/qingtingjjjjjjj/iptv-auto-update/main/my.txt","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
{"name": "🥬┃BOX港·澳·韩·台直播","type": 0,"url": "http://8.138.7.223/live.txt","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
{"name": "🐏┃Live肥羊直播","type": 3,"api": "csp_Feiyang","url": "tv.m3u","ext": "https://gh.tryxd.cn/https://raw.githubusercontent.com/lystv/fmapp/ok/apk/allinone/v7/allinone;md5;https://gh.tryxd.cn/https://raw.githubusercontent.com/lystv/fmapp/ok/apk/allinone/v7/md5","jar": "https://gh.tryxd.cn/https://raw.githubusercontent.com/FongMi/CatVodSpider/main/jar/custom_spider.jar"},
|
||||
//{"name": "🥬┃BOX港·澳·韩·台直播","type": 0,"url": "http://8.138.7.223/live.txt","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
//{"name": "🐏┃Live肥羊直播","type": 3,"api": "csp_Feiyang","url": "tv.m3u","ext": "https://gh.tryxd.cn/https://raw.githubusercontent.com/lystv/fmapp/ok/apk/allinone/v7/allinone;md5;https://gh.tryxd.cn/https://raw.githubusercontent.com/lystv/fmapp/ok/apk/allinone/v7/md5","jar": "https://gh.tryxd.cn/https://raw.githubusercontent.com/FongMi/CatVodSpider/main/jar/custom_spider.jar"},
|
||||
{"name": "🐤┃Guovin直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/Guovin/iptv-api/gd/output/result.m3u","playerType": 1,"epg": "http://epg.51zmt.top:8000/api/diyp/?ch={name}&date={date}","logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
{"name": "🧸┃CCSH直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/CCSH/IPTV/main/live.txt","playerType":1},
|
||||
{"name": "🎳┃judy直播","type": 0,"url": "https://smart.pendy.dpdns.org/m3u/merged_judy.m3u","epg": "http://epg.51zmt.top:8000/api/diyp/?ch={name}&date={date}","logo": "https://epg.iill.top/logo/{name}.png","ua": "xieanqishiwoerzi/0.0.1","timeout": 10,"playerType": 2},
|
||||
{"name": "🧸┃CCSH直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/CCSH/IPTV/main/live.m3u","playerType":1},
|
||||
{"name": "🛺┃IPTV-CCSH直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/IPTV-CCSH/refs/heads/main/live.m3u","playerType":1},
|
||||
{"name": "🐏┃ssili126直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/ssili126/tv/main/itvlist.txt","playerType":1},
|
||||
{"name": "〽️┃欧歌电视","type": 0,"url": "https://xn--pggp-rp5imh.v.nxog.top/m//tv/","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
//{"name": "〽️┃欧歌电视","type": 0,"url": "https://xn--pggp-rp5imh.v.nxog.top/m//tv/","playerType": 1,"logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
{"name": "🎂┃suxuang直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/suxuang/myIPTV/main/ipv6.m3u","playerType":1},
|
||||
{"name": "👟┃iptv365直播","type": 0,"url": "https://live.iptv365.org/live.txt","playerType":1},
|
||||
{"name": "😎┃咪咕直播","type": 0,"url": "https://yun.urldwz.com/f/Q6y3ca/migu.m3u","timeout": 10},
|
||||
{"name": "🛍️┃myernestlu直播","type": 0,"url": "https://myernestlu.github.io/zby.txt","playerType":1},
|
||||
{"name": "🛍️┃zbefine直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/zbefine/iptv/main/iptv.m3u","playerType":1},
|
||||
{"name": "🛍️┃vamoschuck直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/vamoschuck/TV/main/M3U","playerType":1},
|
||||
{"name": "🛍️┃hong_kong直播","type": 0,"url": "https://epg.pw/test_channels_hong_kong.m3u","playerType":1},
|
||||
//{"name": "🛍️┃hong_kong直播","type": 0,"url": "https://epg.pw/test_channels_hong_kong.m3u","playerType":1},
|
||||
{"name": "🛍️┃zhiboyuan直播","type": 0,"url": "https://gitee.com/xxy002/zhiboyuan/raw/master/dsy","playerType":1},
|
||||
{"name": "🛍️┃channels直播","type": 0,"url": "https://epg.pw/test_channels.m3u","playerType":1},
|
||||
{"name": "🛍️┃Free-TV直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/Free-TV/IPTV/master/playlist.m3u8","playerType":1},
|
||||
{"name": "⚕️┃iptv粤Live","type": 0,"url": "http://box.1890222.xyz:8081/iptv/live.m3u","playerType":1},
|
||||
{"name": "🐰┃wwb521粤港澳","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/wwb521/live/main/tv.m3u","playerType":1},
|
||||
{"name": "🍡┃kimwang1978直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/kimwang1978/collect-tv-txt/main/merged_output_simple.txt","playerType":1},
|
||||
{"name": "✨┃PGTV直播","type": 0,"url": "https://git.gra.phite.ro/alantang/pg/raw/branch/main/live.m3u","playerType":1},
|
||||
//{"name": "🍡┃kimwang1978直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/kimwang1978/collect-tv-txt/main/merged_output_simple.txt","playerType":1},
|
||||
{"name": "✨┃555TV直播","type": 0,"url": "http://rihou.cc:555/gggg.nzk","playerType":1},
|
||||
{"name": "🎁┃migu直播","type": 0,"url": "https://json.doube.eu.org/live/migu/Sub.php","playerType":1},
|
||||
{"name": "🍟┃Kimentanm直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/Kimentanm/aptv/master/m3u/iptv.m3u","playerType":1},
|
||||
//{"name": "🍟┃Kimentanm直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/Kimentanm/aptv/master/m3u/iptv.m3u","playerType":1},
|
||||
{"name": "🎗️┃butterfly直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/butterfly202400/dsy/refs/heads/main/ln2403.m3u","playerType":1},
|
||||
{"name": "🐸┃全面直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/Ftindy/IPTV-URL/main/Collect.m3u","playerType":1},
|
||||
{"name": "❤️┃春盈直播","type": 0,"url": "http://home.jundie.top:81/Cat/tv/live.txt","playerType":1},
|
||||
{"name": "🤡┃全球直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/Free-TV/IPTV/master/playlist.m3u8","playerType":1},
|
||||
{"name": "📺┃vbskycn直播","type": 0,"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/vbskycn/iptv/master/tv/iptv4.m3u","playerType":1},
|
||||
{"name": "🍭┃vbskycn直播","type": 0,"url": "https://live.zbds.top/tv/iptv4.txt","playerType":1},
|
||||
{"name": "🦐┃龙伊直播","type":0,"url":"https://龙伊.top/直播","playerType":1,"epg":"https://api.龙伊.top/epg/epg.php?ch={name}&date={date}","logo":"https://api.龙伊.top/epg/images/{name}.png"},
|
||||
//{"name": "🦐┃龙伊直播","type":0,"url":"https://龙伊.top/直播","playerType":1,"epg":"https://api.龙伊.top/epg/epg.php?ch={name}&date={date}","logo":"https://api.龙伊.top/epg/images/{name}.png"},
|
||||
{"name": "🍉┃fanmingming直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/fanmingming/live/refs/heads/main/tv/m3u/ipv6.m3u","playerType":1},
|
||||
{"name": "🎏┃范明直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/fanmingming/live/refs/heads/main/tv/m3u/ipv6.m3u","playerType":1},
|
||||
{"name": "✍️┃qingwen07直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/qingwen07/awesome-iptv/main/tvbox_live_all.txt","playerType":1},
|
||||
{"name": "🔢┃serv00直播","type":0,"url":"https://a90120.serv00.net/anbox/p3plink.txt","playerType":1},
|
||||
{
|
||||
"name": "4GTV - 台湾",
|
||||
"url": "docker.livednow.dpdns.org/?type=m3u",
|
||||
"ua": "judy/5.2.1"
|
||||
},
|
||||
{
|
||||
"name": "香港视频 - 安卓",
|
||||
"url": "https://smart.pendy.dpdns.org/m3u/MytvSuper.m3u",
|
||||
"ua": "judy/5.2.1"
|
||||
},
|
||||
{
|
||||
"name": "鲍鱼",
|
||||
"type": 0,
|
||||
"url": "http://lisha521.dynv6.net.fh4u.org/tv.txt",
|
||||
"playerType": 1
|
||||
},
|
||||
{
|
||||
"name": "蝴蝶",
|
||||
"type": 0,
|
||||
"url": "http://lisha521.dynv6.net.fh4u.org/iptv.txt",
|
||||
"epg": "http://epg.51zmt.top:8000/api/diyp/?ch={name}&date={date}",
|
||||
"logo": "https://epg.iill.top/logo/{name}.png",
|
||||
"ua": "okhttp/3.15,AptvPlayer/1.4.0",
|
||||
"timeout": 10,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"name": "一线天",
|
||||
"type": 0,
|
||||
"url": "http://lisha521.dynv6.net.fh4u.org/hlj.txt",
|
||||
"ua": "okhttp/3.15",
|
||||
"epg": "http://127.0.0.1:10079/p/0/proxy/http://epg.112114.xyz/?ch={name}&date={date}",
|
||||
"logo": "http://127.0.0.1:10079/p/0/proxy/https://epg.112114.xyz/logo/{name}.png"
|
||||
},
|
||||
{
|
||||
"name": "青龙",
|
||||
"type": 0,
|
||||
"url": "http://rihou.cc:555/gggg.nzk",
|
||||
"playerType": 1,
|
||||
"ua": "okhttp/3.15",
|
||||
"epg": "http://epg.112114.xyz/?ch={name}&date={date}",
|
||||
"logo": "https://epg.112114.eu.org/logo/{name}.png"
|
||||
},
|
||||
{
|
||||
"name": "白虎",
|
||||
"type": 0,
|
||||
"url": "http://lisha521.dynv6.net.fh4u.org/live.txt",
|
||||
"playerType": 1,
|
||||
"ua": "okhttp/3.15",
|
||||
"epg": "http://epg.112114.xyz/?ch={name}&date={date}",
|
||||
"logo": "https://epg.112114.xyz/logo/{name}.png"
|
||||
},
|
||||
{
|
||||
"name": "馒头",
|
||||
"type": 0,
|
||||
"url": "http://127.0.0.1:10079/c/3600/null/http://lisha521.dynv6.net.fh4u.org/live1.txt",
|
||||
"playerType": 2,
|
||||
"ua": "okhttp/3.15",
|
||||
"epg": "http://epg.112114.xyz/?ch={name}&date={date}",
|
||||
"logo": "https://epg.112114.xyz/logo/{name}.png"
|
||||
},
|
||||
{"name": "👓┃gshtwy直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/gshtwy/MyTv/refs/heads/main/MyTv.m3u","playerType":1}],
|
||||
{"name": "🔢┃Hotel_iptv直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/Hotel_iptv/refs/heads/main/itvlist.txt","playerType":1},
|
||||
{"name": "👓┃gshtwy直播","type":0,"url":"https://gh.tryxd.cn/https://raw.githubusercontent.com/gshtwy/MyTv/refs/heads/main/MyTv.m3u","playerType":1}],
|
||||
|
||||
"hosts": [
|
||||
"cache.ott.ystenlive.itv.cmvideo.cn=itv.dns.xuran1983.cn",
|
||||
|
|
171
app.py
|
@ -1,171 +0,0 @@
|
|||
import re
|
||||
import requests
|
||||
import os
|
||||
from collections import defaultdict
|
||||
|
||||
# ================== 配置区域 ==================
|
||||
DELETE_GROUPS = ["4K频道", "8K频道"]
|
||||
PROVINCE_GROUPS = ["北京", "安徽", "甘肃", "广东", "贵州", "海南", "河北", "河南", "黑龙江", "湖北", "湖南",
|
||||
"吉林", "江苏", "江西", "辽宁", "青海", "山东", "上海", "四川", "云南", "浙江", "重庆", "香港"]
|
||||
GROUP_REPLACEMENTS = {"央视": "央视频道", "卫视": "卫视频道", "其他": "其他频道"}
|
||||
DELETE_CHARS = ["iHOT-", "NewTV-", "SiTV-", "-HEVC", "-50-FPS", "-高码", "-4K", "-BPTV", "咪咕视频_8M1080_"]
|
||||
GROUP_ORDER = ["收藏频道", "央视频道", "卫视频道", "其他频道", "地方频道"]
|
||||
|
||||
M3U_SOURCES = [
|
||||
{"name": "电视", "url": "https://cnb.cool/junchao.tang/llive/-/git/raw/main/电视.txt", "ua": "okhttp/4.12.0"},
|
||||
{"name": "台湾", "url": "http://xn--elt51t.azip.dpdns.org:5008/?type=txt", "ua": "okhttp/4.12.0"},
|
||||
{"name": "dsy", "url": "https://gitee.com/xxy002/zhiboyuan/raw/master/dsy", "ua": "okhttp/4.12.0"},
|
||||
{"name": "小云TV", "url": "https://cnb.cool/junchao.tang/llive/-/git/raw/main/小云TV直播", "ua": "okhttp/4.12.0"},
|
||||
{"name": "mytv", "url": "http://gg.7749.org/z/0/dzh.txt", "ua": "okhttp/4.12.0"},
|
||||
{"name": "自用收藏", "url": "http://aktv.space/live.m3u", "ua": "okhttp/4.12.0"},
|
||||
{"name": "big", "url": "http://api.mytv666.top/lives/free.php?type=txt", "ua": "okhttp/4.12.0"},
|
||||
{"name": "xhztv", "url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/qingtingjjjjjjj/iptv-auto-update/main/my.txt", "ua": "okhttp/4.12.0"},
|
||||
{"name": "top", "url": "https://tv.iill.top/m3u/Gather", "ua": "okhttp/4.12.0"},
|
||||
{"name": "zbds", "url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/pxiptv/live/main/iptv.m3u", "ua": "okhttp/4.12.0"},
|
||||
{"name": "Collect", "url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/Collect-IPTV/refs/heads/main/mylive.m3u", "ua": "okhttp/4.12.0"},
|
||||
{"name": "jundie", "url": "https://codeberg.org/alfredisme/mytvsources/raw/branch/main/mylist-ipv6.m3u", "ua": "okhttp/4.12.0"},
|
||||
{"name": "MyIPTV", "url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/iptv_api/refs/heads/main/live_ipv4.m3u", "ua": "okhttp/4.12.0"}
|
||||
]
|
||||
|
||||
# ================== 核心功能 ==================
|
||||
def robust_download(url, ua, max_retries=3):
|
||||
headers = {'User-Agent': ua}
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
response = requests.get(url, headers=headers, timeout=15)
|
||||
response.raise_for_status()
|
||||
response.encoding = response.apparent_encoding
|
||||
return response.text
|
||||
except Exception as e:
|
||||
if attempt == max_retries - 1:
|
||||
print(f"❌ 无法下载: {url}. 错误: {str(e)}")
|
||||
return None
|
||||
print(f"正在重试 {url} (第 {attempt+1} 次)")
|
||||
|
||||
def process_channel(line):
|
||||
if any(f'group-title="{g}"' in line for g in DELETE_GROUPS):
|
||||
return None
|
||||
|
||||
for old, new in GROUP_REPLACEMENTS.items():
|
||||
line = line.replace(f'group-title="{old}"', f'group-title="{new}"')
|
||||
|
||||
for province in PROVINCE_GROUPS:
|
||||
if f'group-title="{province}"' in line:
|
||||
new_group = '地方频道' if "卫视" not in line else '卫视频道'
|
||||
line = line.replace(f'group-title="{province}"', f'group-title="{new_group}"')
|
||||
|
||||
if "凤凰卫视" in line:
|
||||
line = line.replace('group-title="地方频道"', 'group-title="卫视频道"')
|
||||
|
||||
for char in DELETE_CHARS:
|
||||
line = line.replace(char, "")
|
||||
|
||||
line = re.sub(r'cctv-?', 'CCTV', line, flags=re.IGNORECASE)
|
||||
|
||||
return line
|
||||
|
||||
def parse_m3u(content):
|
||||
channels = []
|
||||
current_channel = {}
|
||||
for line in content.splitlines():
|
||||
line = line.strip()
|
||||
if line.startswith("#EXTINF"):
|
||||
current_channel = {"meta": line, "url": ""}
|
||||
elif line.startswith("http"):
|
||||
current_channel["url"] = line
|
||||
channels.append(current_channel)
|
||||
current_channel = {}
|
||||
return channels
|
||||
|
||||
def generate_m3u_output(channels):
|
||||
group_dict = defaultdict(list)
|
||||
for channel in channels:
|
||||
if match := re.search(r'group-title="([^"]+)"', channel["meta"]):
|
||||
group = match.group(1)
|
||||
group_dict[group].append(channel)
|
||||
|
||||
ordered_groups = []
|
||||
for group in GROUP_ORDER:
|
||||
if group in group_dict:
|
||||
ordered_groups.append((group, group_dict.pop(group)))
|
||||
for group in sorted(group_dict.keys()):
|
||||
ordered_groups.append((group, group_dict[group]))
|
||||
|
||||
output = ["#EXTM3U"]
|
||||
for group, items in ordered_groups:
|
||||
for item in items:
|
||||
output.append(item["meta"])
|
||||
output.append(item["url"])
|
||||
return "\n".join(output)
|
||||
|
||||
def generate_txt_output(channels):
|
||||
output_lines = []
|
||||
for channel in channels:
|
||||
meta = channel["meta"]
|
||||
url = channel["url"]
|
||||
|
||||
# 提取频道名称
|
||||
name_match = re.search(r'tvg-name="([^"]+)"', meta)
|
||||
channel_name = name_match.group(1) if name_match else "Unknown Channel"
|
||||
|
||||
# 提取频道组
|
||||
group_match = re.search(r'group-title="([^"]+)"', meta)
|
||||
channel_group = group_match.group(1) if group_match else "Unknown Group"
|
||||
|
||||
# 提取电视台ID
|
||||
tvg_id_match = re.search(r'tvg-id="([^"]+)"', meta)
|
||||
tvg_id = tvg_id_match.group(1) if tvg_id_match else "Unknown ID"
|
||||
|
||||
output_lines.append(f"名称: {channel_name}, 组: {channel_group}, 电视台ID: {tvg_id}, URL: {url}")
|
||||
|
||||
return "\n".join(output_lines)
|
||||
|
||||
def save_file(content, filename):
|
||||
live_folder = 'live'
|
||||
if not os.path.exists(live_folder):
|
||||
os.makedirs(live_folder)
|
||||
file_path = os.path.join(live_folder, filename)
|
||||
try:
|
||||
with open(file_path, "w", encoding="utf-8") as f:
|
||||
f.write(content)
|
||||
print(f"✅ 成功生成 {filename} 文件")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"❌ 保存文件失败: {str(e)}")
|
||||
return False
|
||||
|
||||
def main():
|
||||
all_channels = []
|
||||
|
||||
print("开始下载和处理数据源...")
|
||||
for source in M3U_SOURCES:
|
||||
content = robust_download(source["url"], source["ua"])
|
||||
if not content:
|
||||
print(f"[×] {source['name']} 无法处理,跳过")
|
||||
continue
|
||||
|
||||
channels = parse_m3u(content)
|
||||
processed = []
|
||||
for ch in channels:
|
||||
# 修复: 检查 "meta" 键是否存在
|
||||
if "meta" in ch and (cleaned_meta := process_channel(ch["meta"])):
|
||||
processed.append({"meta": cleaned_meta, "url": ch["url"]})
|
||||
|
||||
all_channels.extend(processed)
|
||||
print(f"[✓] {source['name']} 处理完成 ({len(processed)} 频道)")
|
||||
|
||||
if not all_channels:
|
||||
print("❌ 没有可用的频道数据,终止生成文件")
|
||||
return
|
||||
|
||||
print("\n生成最终文件...")
|
||||
m3u_content = generate_m3u_output(all_channels)
|
||||
save_file(m3u_content, "live.m3u")
|
||||
|
||||
txt_content = generate_txt_output(all_channels)
|
||||
save_file(txt_content, "live.txt")
|
||||
|
||||
print(f"\n处理完成!有效频道总数: {len(all_channels)}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,131 @@
|
|||
# 配置文件,包含直播源URL、黑名单URL、公告信息、EPG URL、测速超时时间和线程池最大工作线程数
|
||||
|
||||
# 优先使用的IP版本,这里设置为ipv6
|
||||
ip_version_priority = "ipv6"
|
||||
|
||||
# 直播源URL列表
|
||||
source_urls = [
|
||||
"https://cnb.cool/junchao.tang/llive/-/git/raw/main/中国IPTV",
|
||||
"https://www.iyouhun.com/tv/myIPTV/ipv6.m3u",
|
||||
"https://www.iyouhun.com/tv/myIPTV/ipv4.m3u",
|
||||
"http://rihou.cc:555/gggg.nzk",
|
||||
"https://live.izbds.com/tv/iptv4.txt",
|
||||
"http://47.120.41.246:8899/zb.txt",
|
||||
"http://live.nctv.top/x.txt",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/iptv_api/refs/heads/main/output/live_ipv4.m3u",
|
||||
"https://live.izbds.com/tv/iptv4.txt",
|
||||
"http://47.120.41.246:8899/zb.txt",
|
||||
"http://rihou.cc:555/gggg.nzk",
|
||||
"http://晓峰.azip.dpdns.org:5008/?type=m3u",
|
||||
"http://api.mytv666.top/lives/free.php?type=txt",
|
||||
"http://1.94.31.214/live/livelite.txt",
|
||||
"https://web.banye.tech:7777/tvbus/yogurtTv.txt",
|
||||
"https://cnb.cool/junchao.tang/llive/-/git/raw/main/go.txt",
|
||||
"https://6296.kstore.vip/25.txt",
|
||||
"https://smart.pendy.dpdns.org/m3u/Smart.m3u",
|
||||
"https://cnb.cool/junchao.tang/llive/-/git/raw/main/咪咕直播",
|
||||
"http://zhibo.feylen.top/fltv/js/ku9live.php?tpye=fl.txt",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/Alan-Alana/IPTV/refs/heads/main/channl.txt",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/peterHchina/iptv/refs/heads/main/IPTV-V4.m3u",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/peterHchina/iptv/refs/heads/main/IPTV-V6.m3u",
|
||||
"http://lisha521.dynv6.net.fh4u.org/tv.txt",
|
||||
"https://web.banye.tech:7777/tv/hlj.txt",
|
||||
"https://iptv.catvod.com/tv.m3u",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/hostemail/cdn/main/live/tv.txt",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/JunTV/refs/heads/main/output/result.m3u",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/ssili126/tv/main/itvlist.m3u",
|
||||
"https://live.zbds.top/tv/iptv4.txt",
|
||||
"https://gitee.com/xxy002/zhiboyuan/raw/master/dsy",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/big-mouth-cn/tv/main/iptv-ok.m3u",
|
||||
"https://codeberg.org/alfredisme/mytvsources/raw/branch/main/mylist-ipv6.m3u",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/lalifeier/IPTV/main/m3u/IPTV.m3u",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/wwb521/live/main/tv.m3u",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/asdjkl6/tv/tv/.m3u/整套直播源/测试/整套直播源/l.txt",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/asdjkl6/tv/tv/.m3u/整套直播源/测试/整套直播源/kk.txt",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/suxuang/myIPTV/main/ipv6.m3u",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/Guovin/iptv-api/gd/output/result.m3u",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/yuanzl77/IPTV/main/live.m3u",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/YanG-1989/m3u/main/Gather.m3u",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/YueChan/Live/refs/heads/main/APTV.m3u",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/Kimentanm/aptv/master/m3u/iptv.m3u",
|
||||
"https://live.zbds.top/tv/iptv6.txt",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/Guovin/TV/gd/output/result.txt",
|
||||
"http://home.jundie.top:81/Cat/tv/live.txt",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/vbskycn/iptv/master/tv/hd.txt",
|
||||
"https://live.fanmingming.cn/tv/m3u/ipv6.m3u",
|
||||
"https://live.zhoujie218.top/tv/iptv6.txt",
|
||||
"https://cdn.jsdelivr.net/gh/YueChan/live@main/IPTV.m3u",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/cymz6/AutoIPTV-Hotel/main/lives.txt",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/PizazzGY/TVBox_warehouse/main/live.txt",
|
||||
"https://fm1077.serv00.net/SmartTV.m3u",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/joevess/IPTV/main/home.m3u8",
|
||||
"https://tv.iill.top/m3u/Gather",
|
||||
"https://m3u.ibert.me/txt/o_cn.txt",
|
||||
"https://m3u.ibert.me/txt/j_iptv.txt",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/xzw832/cmys/main/S_CCTV.txt",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/xzw832/cmys/main/S_weishi.txt",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/BurningC4/Chinese-IPTV/master/TV-IPV4.m3u",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/joevess/IPTV/main/m3u/iptv.m3u",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/Ftindy/IPTV-URL/main/IPV6.m3u",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/YanG-1989/m3u/main/Gather.m3u",
|
||||
"https://iptv.b2og.com/txt/fmml_ipv6.txt",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/kimwang1978/collect-tv-txt/main/merged_output_simple.txt",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/SPX372928/MyIPTV/master/黑龙江PLTV移动CDN版.txt",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/qingwen07/awesome-iptv/main/tvbox_live_all.txt",
|
||||
"https://gh.tryxd.cn/https://raw.githubusercontent.com/kimwang1978/collect-tv-txt/main/merged_output.m3u",
|
||||
"https://live.zhoujie218.top/tv/iptv4.txt"
|
||||
]
|
||||
|
||||
# 直播源黑名单URL列表,去除了重复项
|
||||
url_blacklist = [
|
||||
"epg.pw/stream/",
|
||||
"103.40.13.71:12390",
|
||||
"[2409:8087:1a01:df::4077]/PLTV/",
|
||||
"http://[2409:8087:1a01:df::7005]:80/ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226419/index.m3u8",
|
||||
"http://[2409:8087:5e00:24::1e]:6060/000000001000/1000000006000233001/1.m3u8",
|
||||
"8.210.140.75:68",
|
||||
"154.12.50.54",
|
||||
"yinhe.live_hls.zte.com",
|
||||
"8.137.59.151",
|
||||
"[2409:8087:7000:20:1000::22]:6060",
|
||||
"histar.zapi.us.kg",
|
||||
"www.tfiplaytv.vip",
|
||||
"dp.sxtv.top",
|
||||
"111.230.30.193",
|
||||
"148.135.93.213:81",
|
||||
"live.goodiptv.club",
|
||||
"iptv.luas.edu.cn",
|
||||
"[2409:8087:2001:20:2800:0:df6e:eb22]:80",
|
||||
"[2409:8087:2001:20:2800:0:df6e:eb23]:80",
|
||||
"[2409:8087:2001:20:2800:0:df6e:eb1d]/ott.mobaibox.com/",
|
||||
"[2409:8087:2001:20:2800:0:df6e:eb1d]:80",
|
||||
"[2409:8087:2001:20:2800:0:df6e:eb24]",
|
||||
"2409:8087:2001:20:2800:0:df6e:eb25]:80",
|
||||
"stream1.freetv.fun",
|
||||
"chinamobile",
|
||||
"gaoma",
|
||||
"[2409:8087:2001:20:2800:0:df6e:eb27]"
|
||||
]
|
||||
|
||||
# 公告信息
|
||||
announcements = [
|
||||
{
|
||||
"channel": "更新日期",
|
||||
"entries": [
|
||||
{
|
||||
"name": None,
|
||||
"url": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/X/main/Pictures/Robot.mp4",
|
||||
"logo": "https://gh.tryxd.cn/https://raw.githubusercontent.com/alantang1977/X/main/Pictures/chao-assets.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
# EPG(电子节目指南)URL列表
|
||||
epg_urls = [
|
||||
"https://epg.v1.mk/fy.xml",
|
||||
"http://epg.51zmt.top:8000/e.xml",
|
||||
"https://epg.pw/xmltv/epg_CN.xml",
|
||||
"https://epg.pw/xmltv/epg_HK.xml",
|
||||
"https://epg.pw/xmltv/epg_TW.xml"
|
||||
]
|
|
@ -0,0 +1,257 @@
|
|||
🍎┃广东频道,#genre#
|
||||
广州综合,
|
||||
广州新闻,
|
||||
广东珠江,
|
||||
广州影视频道,
|
||||
广州电视台影视频道,
|
||||
广州电视台法治频道,
|
||||
广州南国都市频道,
|
||||
4K南国都市频道,
|
||||
广州竞赛频道,
|
||||
广东体育,
|
||||
广东民生,
|
||||
广东综艺,
|
||||
广东影视,
|
||||
经济科教,
|
||||
岭南戏曲,
|
||||
现代教育,
|
||||
大湾区卫视,
|
||||
|
||||
🥝┃央视频道,#genre#
|
||||
CCTV1,
|
||||
CCTV2,
|
||||
CCTV3,
|
||||
CCTV4,
|
||||
CCTV5,
|
||||
CCTV5+,
|
||||
CCTV6,
|
||||
CCTV7,
|
||||
CCTV8,
|
||||
CCTV9,
|
||||
CCTV10,
|
||||
CCTV11,
|
||||
CCTV12,
|
||||
CCTV13,
|
||||
CCTV14,
|
||||
CCTV15,
|
||||
CCTV16,
|
||||
CCTV17,
|
||||
CCTV4K,
|
||||
CCTV8K,
|
||||
CETV1,
|
||||
CETV2,
|
||||
CETV4,
|
||||
CETV5,
|
||||
|
||||
🥭┃卫视频道,#genre#
|
||||
浙江卫视,
|
||||
湖南卫视,
|
||||
东方卫视,
|
||||
江苏卫视,
|
||||
山东卫视,
|
||||
北京卫视,
|
||||
安徽卫视,
|
||||
重庆卫视,
|
||||
四川卫视,
|
||||
东南卫视,
|
||||
深圳卫视,
|
||||
广东卫视,
|
||||
广西卫视,
|
||||
厦门卫视,
|
||||
南方卫视,
|
||||
甘肃卫视,
|
||||
贵州卫视,
|
||||
河北卫视,
|
||||
河南卫视,
|
||||
黑龙江卫视,
|
||||
湖北卫视,
|
||||
江西卫视,
|
||||
吉林卫视,
|
||||
内蒙古卫视,
|
||||
辽宁卫视,
|
||||
宁夏卫视,
|
||||
青海卫视,
|
||||
天津卫视,
|
||||
海南卫视,
|
||||
新疆卫视,
|
||||
云南卫视,
|
||||
西藏卫视,
|
||||
海峡卫视,
|
||||
兵团卫视,
|
||||
黄河卫视,
|
||||
安多卫视,
|
||||
康巴卫视,
|
||||
农林卫视,
|
||||
三沙卫视,
|
||||
延边卫视,
|
||||
山东齐鲁卫视,
|
||||
|
||||
🍓┃湾区频道,#genre#
|
||||
翡翠台,
|
||||
凤凰中文,
|
||||
凤凰资讯,
|
||||
tvN,
|
||||
PopC,
|
||||
J2,
|
||||
明珠台,
|
||||
Pearl 明珠台,
|
||||
无线明珠,
|
||||
娛樂新聞台(HK),
|
||||
娱乐新闻台,
|
||||
無線新聞台,
|
||||
无线新闻台,
|
||||
有线新闻,
|
||||
TVBS新闻,
|
||||
TVBS欢乐,
|
||||
寰宇新聞台,
|
||||
now新闻,
|
||||
133爆谷台,
|
||||
翡翠综合台(北美),
|
||||
ROCK Action,
|
||||
TVB星河,
|
||||
千禧经典台,
|
||||
712WARNERTV,
|
||||
AMC電影台,
|
||||
200TVBS台劇台,
|
||||
TVBdrama,
|
||||
Animax,
|
||||
美亚电影台,
|
||||
美亞電影台(HK),
|
||||
美亚电影粤,
|
||||
美亚电影国,
|
||||
HOYTV,
|
||||
TVB Plus,
|
||||
myTV SUPER FREE,
|
||||
MBC 대전,
|
||||
Hoy 78,
|
||||
天映频道粤,
|
||||
天映频道国,
|
||||
Viutv,
|
||||
三立台湾,
|
||||
三立新闻,
|
||||
东森综合,
|
||||
东森超视,
|
||||
东森电影,
|
||||
Now剧集,
|
||||
Now华剧,
|
||||
Now星影台,
|
||||
靖天资讯,
|
||||
靖天電影台,
|
||||
星卫娱乐,
|
||||
卫视卡式,
|
||||
SUPER Kids Channel,
|
||||
amc电影台,
|
||||
Hbo原创台,
|
||||
Hbo家庭台,
|
||||
Hbo巨献台,
|
||||
Hbo巨献备,
|
||||
AXN电影台,
|
||||
Channel 5 HD,
|
||||
Channel 8 HD,
|
||||
Channel U HD,
|
||||
RTHK 31,
|
||||
RTHK 32,
|
||||
RTHK 33,
|
||||
RTHK 34,
|
||||
RTHK 35,
|
||||
RTHK 36,
|
||||
中天亞洲台,
|
||||
中天新聞台,
|
||||
中視,
|
||||
千禧經典台,
|
||||
東森电影国,
|
||||
8-度空间国,
|
||||
日本全天新聞,
|
||||
爆谷台,
|
||||
新加坡中文,
|
||||
華視,
|
||||
龍華日韓台,
|
||||
龍華電影台,
|
||||
凤凰香港,
|
||||
凤凰卫视,
|
||||
香港卫视,
|
||||
TVBS欢乐,
|
||||
TVBS亚洲,
|
||||
TVBS新闻,
|
||||
三立台湾,
|
||||
无线新闻,
|
||||
三立新闻,
|
||||
纬来体育,
|
||||
纬来育乐,
|
||||
东森综合,
|
||||
东森超视,
|
||||
东森电影,
|
||||
Now剧集,
|
||||
Now华剧,
|
||||
靖天资讯,
|
||||
星卫娱乐,
|
||||
卫视卡式,
|
||||
|
||||
🍉┃咪咕频道,#genre#
|
||||
CCTV-01咪咕,
|
||||
CCTV-02咪咕,
|
||||
CCTV-03咪咕,
|
||||
CCTV-04咪咕,
|
||||
CCTV-05咪咕,
|
||||
CCTV-06咪咕,
|
||||
CCTV-07咪咕,
|
||||
CCTV-08咪咕,
|
||||
CCTV-09咪咕,
|
||||
CCTV-10咪咕,
|
||||
CCTV-11咪咕,
|
||||
CCTV-12咪咕,
|
||||
CCTV-13咪咕,
|
||||
CCTV-14咪咕,
|
||||
CCTV-15咪咕,
|
||||
CCTV-16咪咕,
|
||||
CCTV-17咪咕,
|
||||
CCTV4欧洲咪咕,
|
||||
CCTV4欧洲咪咕,
|
||||
CCTV4美洲咪咕,
|
||||
CCTV-4咪咕欧洲,
|
||||
CCTV-4咪咕美洲,
|
||||
CCTV-5+咪咕,
|
||||
CCTV-16咪咕,
|
||||
CGT西语咪咕,
|
||||
CGT阿语咪咕,
|
||||
CGT法语咪咕,
|
||||
家庭影院咪咕,
|
||||
动作电影咪咕,
|
||||
东方卫视咪咕,
|
||||
江苏卫视咪咕,
|
||||
陕西卫视咪咕,
|
||||
湖北卫视咪咕,
|
||||
江西卫视咪咕,
|
||||
海南卫视咪咕,
|
||||
军事大片咪咕,
|
||||
热剧联播咪咕,
|
||||
新片映厅咪咕,
|
||||
Y+剧场台咪咕,
|
||||
|
||||
|
||||
🐟┃少儿频道,#genre#
|
||||
东森幼幼,
|
||||
iFun动漫,
|
||||
momo亲子,
|
||||
黑莓动画,
|
||||
嘉佳少儿,
|
||||
卡酷少儿,
|
||||
动漫秀场,
|
||||
哈哈炫动,
|
||||
金鹰卡通,
|
||||
优漫卡通,
|
||||
靖洋卡通,
|
||||
广东少儿,
|
||||
|
||||
🐶┃影视频道,#genre#
|
||||
CHC动作电影,
|
||||
CHC高清电影,
|
||||
CHC家庭影院,
|
||||
NewTV惊悚悬疑,
|
||||
NewTV动作电影,
|
||||
黑莓电影,
|
||||
纬来电影,
|
||||
靖天映画,
|
||||
靖天戏剧,
|
||||
星卫娱乐,
|
||||
艾尔达娱乐,
|
5
jsm.json
|
@ -65,9 +65,12 @@
|
|||
}
|
||||
},
|
||||
{"key":"Local","name":"本地","type":3,"api":"csp_Local"},
|
||||
{"key":"WebDAV","name":"WebDAV[jar]","type":3,"api":"csp_WebDAV","searchable":1,"filterable":1,"changeable":1,"timeout":60,
|
||||
"playerType": 2,
|
||||
"ext":"./lib/webdav.json"},
|
||||
{"key":"AList","name":"网盘|Alist[jar]","type":3,"api":"csp_AList","searchable":1,"filterable":1,"changeable":1,"timeout":60,
|
||||
"playerType": 2,
|
||||
"ext":"./js/alistjar.json"},
|
||||
"ext":"./lib/alistjar.json"},
|
||||
{"key":"PushShare","name":"我的资源分享","type":3, "api":"csp_PushShare","searchable":1,"quickSearch":1, "changeable":1, "filterable":0, "timeout":60, "ext":"./lib/tokenm.json$$$./lib/pushshare.txt$$$db$$$1",
|
||||
"style": {
|
||||
"type": "list",
|
||||
|
|
|
@ -1 +1 @@
|
|||
c084f8b282ecc4da8b3b7933e0bd6178
|
||||
dc2ba59b747f4b62ef08f33252875f05
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"drives": [
|
||||
{
|
||||
"name": "alist.jar",
|
||||
"search": true,
|
||||
"searchable": true,
|
||||
"server": "http://192.168.1.1:5678/"
|
||||
}
|
||||
],
|
||||
"danmu":true
|
||||
}
|
|
@ -1 +1 @@
|
|||
99d206b39fd97ffa6db506e6968e9726
|
||||
ff5d8f0029bbbd7ef8bb6e9eecc345ab
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"drives": [
|
||||
{
|
||||
"name": "webdav.router",
|
||||
"search": true,
|
||||
"searchable": true,
|
||||
"server": "http://192.168.1.1:5678",
|
||||
"path": "/dav",
|
||||
"user": "guest",
|
||||
"pass": "guest_Api789"
|
||||
}
|
||||
]
|
||||
}
|
5558
live/IPTV研究所.m3u
|
@ -0,0 +1,38 @@
|
|||
2025-05-29 10:28:01,592 - ERROR - url: https://6296.kstore.vip/25.txt 失败❌, Error: 401, message='', url='https://6296.kstore.vip/25.txt'
|
||||
2025-05-29 10:28:03,770 - ERROR - url: https://tv.iill.top/m3u/Gather 失败❌, Error: 403, message='Forbidden', url='https://tv.iill.top/m3u/Gather'
|
||||
2025-05-29 10:28:03,771 - ERROR - Future exception was never retrieved
|
||||
future: <Future finished exception=ClientConnectionError('Connection lost: [SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY] application data after close notify (_ssl.c:2712)')>
|
||||
Traceback (most recent call last):
|
||||
File "/opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/asyncio/sslproto.py", line 534, in data_received
|
||||
ssldata, appdata = self._sslpipe.feed_ssldata(data)
|
||||
File "/opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/asyncio/sslproto.py", line 206, in feed_ssldata
|
||||
self._sslobj.unwrap()
|
||||
File "/opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/ssl.py", line 979, in unwrap
|
||||
return self._sslobj.shutdown()
|
||||
ssl.SSLError: [SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY] application data after close notify (_ssl.c:2712)
|
||||
|
||||
The above exception was the direct cause of the following exception:
|
||||
|
||||
aiohttp.client_exceptions.ClientConnectionError: Connection lost: [SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY] application data after close notify (_ssl.c:2712)
|
||||
2025-05-29 10:28:22,916 - ERROR - url: https://gitee.com/xxy002/zhiboyuan/raw/master/dsy 失败❌, Error: 403, message='Forbidden', url='https://gitee.com/xxy002/zhiboyuan/raw/master/dsy'
|
||||
2025-05-29 10:28:52,479 - ERROR - Future exception was never retrieved
|
||||
future: <Future finished exception=ClientConnectionError('Connection lost: [Errno 104] Connection reset by peer')>
|
||||
Traceback (most recent call last):
|
||||
File "/opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/asyncio/selector_events.py", line 862, in _read_ready__data_received
|
||||
data = self._sock.recv(self.max_size)
|
||||
ConnectionResetError: [Errno 104] Connection reset by peer
|
||||
|
||||
The above exception was the direct cause of the following exception:
|
||||
|
||||
aiohttp.client_exceptions.ClientConnectionError: Connection lost: [Errno 104] Connection reset by peer
|
||||
2025-05-29 10:32:46,693 - ERROR - Future exception was never retrieved
|
||||
future: <Future finished exception=ClientConnectionError('Connection lost: [Errno 104] Connection reset by peer')>
|
||||
Traceback (most recent call last):
|
||||
File "/opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/asyncio/selector_events.py", line 862, in _read_ready__data_received
|
||||
data = self._sock.recv(self.max_size)
|
||||
ConnectionResetError: [Errno 104] Connection reset by peer
|
||||
|
||||
The above exception was the direct cause of the following exception:
|
||||
|
||||
aiohttp.client_exceptions.ClientConnectionError: Connection lost: [Errno 104] Connection reset by peer
|
||||
2025-05-29 10:32:59,483 - ERROR - url: http://晓峰.azip.dpdns.org:5008/?type=m3u 失败❌, Error:
|
|
@ -1,93 +0,0 @@
|
|||
📺台湾全频道,#genre#
|
||||
三立iNEWS,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV01.m3u8
|
||||
寰宇新聞台,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV02.m3u8
|
||||
東森財經新聞,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV03.m3u8
|
||||
momo購物一台,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV04.m3u8
|
||||
momo購物二台,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV05.m3u8
|
||||
運通財經台,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV06.m3u8
|
||||
信大電視台,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV07.m3u8
|
||||
DW News,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV08.m3u8
|
||||
中視新聞,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV09.m3u8
|
||||
Malaimurasu Tv 24X7,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV10.m3u8
|
||||
Asianet News,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV11.m3u8
|
||||
華視戲劇頻道,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV12.m3u8
|
||||
中天亞洲台,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV13.m3u8
|
||||
Al Jazeera Arabic,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV14.m3u8
|
||||
JapaNews24,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV15.m3u8
|
||||
THE K-POP,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV16.m3u8
|
||||
民視新聞,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV17.m3u8
|
||||
東森購物台CH60,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV18.m3u8
|
||||
東森購物台CH46,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV19.m3u8
|
||||
LIVE NOW,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV20.m3u8
|
||||
Haberturk TV,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV21.m3u8
|
||||
鳳凰衛視資訊台,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV22.m3u8
|
||||
新唐人LIVE,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV23.m3u8
|
||||
ABC News,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV24.m3u8
|
||||
台視新聞台,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV25.m3u8
|
||||
華視綜藝頻道,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV26.m3u8
|
||||
Astro AWANI,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV27.m3u8
|
||||
中天電視,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV28.m3u8
|
||||
Tokyo Walk,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV29.m3u8
|
||||
大愛一臺HD,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV30.m3u8
|
||||
TVBS NEWS,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV31.m3u8
|
||||
三立新聞台,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV32.m3u8
|
||||
GB News,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV33.m3u8
|
||||
中視經典綜藝,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV34.m3u8
|
||||
Sky News,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV35.m3u8
|
||||
India Today,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV36.m3u8
|
||||
Euronews English,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV37.m3u8
|
||||
FRANCE 24 English,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV38.m3u8
|
||||
NBC News,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV39.m3u8
|
||||
News18 India,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV40.m3u8
|
||||
寰宇新聞台灣台,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV41.m3u8
|
||||
MIT台灣誌,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV42.m3u8
|
||||
鳳凰衛視資訊台,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV43.m3u8
|
||||
MediaoneTV Live,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV44.m3u8
|
||||
TBS NEWS,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV45.m3u8
|
||||
NewsTamil24x7,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV46.m3u8
|
||||
大愛二臺HD,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV47.m3u8
|
||||
東森購物台CH47,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV48.m3u8
|
||||
中天2台,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV49.m3u8
|
||||
Malayalam News,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV50.m3u8
|
||||
Arirang TV,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV51.m3u8
|
||||
CNA LIVE,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV52.m3u8
|
||||
HTB北海道ニュース,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV53.m3u8
|
||||
美好購物1台,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV54.m3u8
|
||||
美好購物2台,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV55.m3u8
|
||||
國會頻道1,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV56.m3u8
|
||||
立法院會議,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV57.m3u8
|
||||
123 GO! Live,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV58.m3u8
|
||||
Al Jazeera English,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV59.m3u8
|
||||
Muse木棉花-闔家歡,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV60.m3u8
|
||||
KBS News,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV61.m3u8
|
||||
ABCテレビニュース,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV62.m3u8
|
||||
YOYO TV,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV63.m3u8
|
||||
小猪佩奇,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV64.m3u8
|
||||
Talking Tom,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV65.m3u8
|
||||
TalkingFriendsTVMini,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV66.m3u8
|
||||
Dave and Ava,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV67.m3u8
|
||||
Tayo the Little Bus,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV68.m3u8
|
||||
Disney Junio,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV69.m3u8
|
||||
鏡新聞,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV70.m3u8
|
||||
大陸尋奇,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV71.m3u8
|
||||
CRUX,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV72.m3u8
|
||||
豬哥會社,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV73.m3u8
|
||||
TIMES NOW,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV74.m3u8
|
||||
GTV DRAMA 八大劇樂部,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV75.m3u8
|
||||
民視戲劇館,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV76.m3u8
|
||||
Lofi Girl,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV77.m3u8
|
||||
TaiwanPlus,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV78.m3u8
|
||||
earthTV,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV79.m3u8
|
||||
SBS Running Man,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV80.m3u8
|
||||
飢餓遊戲,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV81.m3u8
|
||||
TVBS NEWS,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV82.m3u8
|
||||
TVBS選新聞,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV83.m3u8
|
||||
Entertainment - Mediacorp,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV84.m3u8
|
||||
寰宇新聞財經台,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV85.m3u8
|
||||
LiveNOW from FOX,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV86.m3u8
|
||||
東森購物台CH34,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV87.m3u8
|
||||
InquizeX,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV88.m3u8
|
||||
8world,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV89.m3u8
|
||||
倪珍24小時播新聞,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV90.m3u8
|
||||
TV91,TV5 News,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV91.m3u8
|
||||
TV92,公視新聞網,https://ghp.ci/https://raw.githubusercontent.com/ChiSheng9/iptv/master/TV92.m3u8
|
44098
live/live.m3u
22047
live/live.txt
4950
live/liveGZ.m3u
|
@ -0,0 +1,451 @@
|
|||
# main.py
|
||||
import re
|
||||
import asyncio
|
||||
import logging
|
||||
import json
|
||||
import os
|
||||
from collections import OrderedDict
|
||||
from datetime import datetime, timedelta
|
||||
import difflib
|
||||
import hashlib
|
||||
|
||||
# 检查 aiohttp 是否安装
|
||||
try:
|
||||
import aiohttp
|
||||
except ImportError:
|
||||
print("错误: 缺少必要的依赖库 'aiohttp'。")
|
||||
print("请使用以下命令安装:")
|
||||
print("pip install aiohttp")
|
||||
import sys
|
||||
sys.exit(1)
|
||||
|
||||
# 检查 config 是否存在
|
||||
try:
|
||||
import config
|
||||
# 验证配置文件的基本结构
|
||||
required_attrs = ['source_urls', 'epg_urls', 'announcements', 'url_blacklist', 'ip_version_priority']
|
||||
for attr in required_attrs:
|
||||
if not hasattr(config, attr):
|
||||
raise AttributeError(f"配置文件缺少必要的属性: {attr}")
|
||||
except ImportError:
|
||||
print("错误: 找不到配置模块 'config.py'。")
|
||||
print("请确保项目目录下有 config.py 文件,内容示例如下:")
|
||||
print("""
|
||||
# config.py 示例内容
|
||||
source_urls = [
|
||||
"https://example.com/source1.m3u",
|
||||
"https://example.com/source2.m3u"
|
||||
]
|
||||
epg_urls = ["https://example.com/epg.xml"]
|
||||
announcements = [
|
||||
{
|
||||
"channel": "公告",
|
||||
"entries": [
|
||||
{
|
||||
"name": None,
|
||||
"url": "https://example.com/notice",
|
||||
"logo": "https://picsum.photos/100/100?random=1"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
url_blacklist = []
|
||||
ip_version_priority = "ipv4"
|
||||
""")
|
||||
import sys
|
||||
sys.exit(1)
|
||||
except AttributeError as e:
|
||||
print(f"配置文件错误: {e}")
|
||||
import sys
|
||||
sys.exit(1)
|
||||
|
||||
# 日志记录,只记录错误信息
|
||||
logging.basicConfig(level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s',
|
||||
handlers=[logging.FileHandler("./live/function.log", "w", encoding="utf-8"), logging.StreamHandler()])
|
||||
|
||||
# 确保 live 文件夹存在
|
||||
output_folder = "live"
|
||||
if not os.path.exists(output_folder):
|
||||
os.makedirs(output_folder)
|
||||
|
||||
# 缓存文件夹和文件
|
||||
cache_folder = "./live/cache"
|
||||
cache_file = os.path.join(cache_folder, "url_cache.json")
|
||||
cache_valid_days = 7 # 缓存有效期(天)
|
||||
|
||||
# 确保缓存文件夹存在
|
||||
if not os.path.exists(cache_folder):
|
||||
os.makedirs(cache_folder)
|
||||
|
||||
# 加载缓存
|
||||
def load_cache():
|
||||
if os.path.exists(cache_file):
|
||||
try:
|
||||
with open(cache_file, "r", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
except Exception as e:
|
||||
logging.error(f"加载缓存失败: {e}")
|
||||
return {"urls": {}, "timestamp": datetime.now().isoformat()}
|
||||
|
||||
# 保存缓存
|
||||
def save_cache(cache):
|
||||
cache["timestamp"] = datetime.now().isoformat()
|
||||
try:
|
||||
with open(cache_file, "w", encoding="utf-8") as f:
|
||||
json.dump(cache, f, ensure_ascii=False, indent=2)
|
||||
except Exception as e:
|
||||
logging.error(f"保存缓存失败: {e}")
|
||||
|
||||
# 检查缓存是否有效
|
||||
def is_cache_valid(cache):
|
||||
if not cache:
|
||||
return False
|
||||
timestamp = datetime.fromisoformat(cache.get("timestamp", datetime.now().isoformat()))
|
||||
return (datetime.now() - timestamp).days < cache_valid_days
|
||||
|
||||
# 计算URL内容的哈希值
|
||||
def calculate_hash(content):
|
||||
return hashlib.md5(content.encode('utf-8')).hexdigest()
|
||||
|
||||
def parse_template(template_file):
|
||||
template_channels = OrderedDict()
|
||||
current_category = None
|
||||
|
||||
with open(template_file, "r", encoding="utf-8") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line and not line.startswith("#"):
|
||||
if "#genre#" in line:
|
||||
current_category = line.split(",")[0].strip()
|
||||
template_channels[current_category] = []
|
||||
elif current_category:
|
||||
channel_name = line.split(",")[0].strip()
|
||||
template_channels[current_category].append(channel_name)
|
||||
|
||||
return template_channels
|
||||
|
||||
def clean_channel_name(channel_name):
|
||||
cleaned_name = re.sub(r'[$「」-]', '', channel_name)
|
||||
cleaned_name = re.sub(r'\s+', '', cleaned_name)
|
||||
cleaned_name = re.sub(r'(\D*)(\d+)', lambda m: m.group(1) + str(int(m.group(2))), cleaned_name)
|
||||
return cleaned_name.upper()
|
||||
|
||||
def is_valid_url(url):
|
||||
return bool(re.match(r'^https?://', url))
|
||||
|
||||
async def fetch_channels(session, url, cache):
|
||||
channels = OrderedDict()
|
||||
unique_urls = set()
|
||||
cache_hit = False
|
||||
|
||||
# 检查URL是否在缓存中且有效
|
||||
url_hash = calculate_hash(url)
|
||||
if url_hash in cache["urls"]:
|
||||
cached_entry = cache["urls"][url_hash]
|
||||
if datetime.now() - datetime.fromisoformat(cached_entry["timestamp"]) <= timedelta(days=cache_valid_days):
|
||||
logging.info(f"从缓存加载: {url}")
|
||||
channels = OrderedDict(cached_entry["channels"])
|
||||
unique_urls = set(cached_entry["unique_urls"])
|
||||
cache_hit = True
|
||||
|
||||
if not cache_hit:
|
||||
try:
|
||||
async with session.get(url) as response:
|
||||
response.raise_for_status()
|
||||
content = await response.text()
|
||||
response.encoding = 'utf-8'
|
||||
lines = content.split("\n")
|
||||
current_category = None
|
||||
is_m3u = any(line.startswith("#EXTINF") for line in lines[:15])
|
||||
source_type = "m3u" if is_m3u else "txt"
|
||||
|
||||
if is_m3u:
|
||||
channels.update(parse_m3u_lines(lines, unique_urls))
|
||||
else:
|
||||
channels.update(parse_txt_lines(lines, unique_urls))
|
||||
|
||||
if channels:
|
||||
# 更新缓存
|
||||
cache["urls"][url_hash] = {
|
||||
"url": url,
|
||||
"channels": dict(channels),
|
||||
"unique_urls": list(unique_urls),
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"content_hash": calculate_hash(content)
|
||||
}
|
||||
save_cache(cache)
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"url: {url} 失败❌, Error: {e}")
|
||||
|
||||
return channels
|
||||
|
||||
def parse_m3u_lines(lines, unique_urls):
|
||||
channels = OrderedDict()
|
||||
current_category = None
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if line.startswith("#EXTINF"):
|
||||
match = re.search(r'group-title="(.*?)",(.*)', line)
|
||||
if match:
|
||||
current_category = match.group(1).strip()
|
||||
channel_name = match.group(2).strip()
|
||||
if channel_name and channel_name.startswith("CCTV"):
|
||||
channel_name = clean_channel_name(channel_name)
|
||||
|
||||
if current_category not in channels:
|
||||
channels[current_category] = []
|
||||
elif line and not line.startswith("#"):
|
||||
channel_url = line.strip()
|
||||
if is_valid_url(channel_url) and channel_url not in unique_urls:
|
||||
unique_urls.add(channel_url)
|
||||
if current_category and channel_name:
|
||||
channels[current_category].append((channel_name, channel_url))
|
||||
|
||||
return channels
|
||||
|
||||
def parse_txt_lines(lines, unique_urls):
|
||||
channels = OrderedDict()
|
||||
current_category = None
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if "#genre#" in line:
|
||||
current_category = line.split(",")[0].strip()
|
||||
channels[current_category] = []
|
||||
elif current_category:
|
||||
match = re.match(r"^(.*?),(.*?)$", line)
|
||||
if match:
|
||||
channel_name = match.group(1).strip()
|
||||
if channel_name and channel_name.startswith("CCTV"):
|
||||
channel_name = clean_channel_name(channel_name)
|
||||
channel_urls = match.group(2).strip().split('#')
|
||||
|
||||
for channel_url in channel_urls:
|
||||
channel_url = channel_url.strip()
|
||||
if is_valid_url(channel_url) and channel_url not in unique_urls:
|
||||
unique_urls.add(channel_url)
|
||||
channels[current_category].append((channel_name, channel_url))
|
||||
elif line:
|
||||
channels[current_category].append((line, ''))
|
||||
|
||||
return channels
|
||||
|
||||
def find_similar_name(target_name, name_list):
|
||||
matches = difflib.get_close_matches(target_name, name_list, n=1, cutoff=0.6)
|
||||
return matches[0] if matches else None
|
||||
|
||||
async def filter_source_urls(template_file):
|
||||
template_channels = parse_template(template_file)
|
||||
source_urls = config.source_urls
|
||||
cache = load_cache()
|
||||
|
||||
all_channels = OrderedDict()
|
||||
async with aiohttp.ClientSession() as session:
|
||||
tasks = [fetch_channels(session, url, cache) for url in source_urls]
|
||||
fetched_channels_list = await asyncio.gather(*tasks)
|
||||
|
||||
for fetched_channels in fetched_channels_list:
|
||||
merge_channels(all_channels, fetched_channels)
|
||||
|
||||
matched_channels = match_channels(template_channels, all_channels)
|
||||
|
||||
return matched_channels, template_channels, cache
|
||||
|
||||
def match_channels(template_channels, all_channels):
|
||||
matched_channels = OrderedDict()
|
||||
|
||||
all_online_channel_names = []
|
||||
for online_category, online_channel_list in all_channels.items():
|
||||
for online_channel_name, _ in online_channel_list:
|
||||
all_online_channel_names.append(online_channel_name)
|
||||
|
||||
for category, channel_list in template_channels.items():
|
||||
matched_channels[category] = OrderedDict()
|
||||
for channel_name in channel_list:
|
||||
similar_name = find_similar_name(clean_channel_name(channel_name), [clean_channel_name(name) for name in all_online_channel_names])
|
||||
if similar_name:
|
||||
original_name = next((name for name in all_online_channel_names if clean_channel_name(name) == similar_name), None)
|
||||
if original_name:
|
||||
for online_category, online_channel_list in all_channels.items():
|
||||
for online_channel_name, online_channel_url in online_channel_list:
|
||||
if online_channel_name == original_name:
|
||||
matched_channels[category].setdefault(channel_name, []).append(online_channel_url)
|
||||
|
||||
return matched_channels
|
||||
|
||||
def merge_channels(target, source):
|
||||
for category, channel_list in source.items():
|
||||
if category in target:
|
||||
target[category].extend(channel_list)
|
||||
else:
|
||||
target[category] = channel_list
|
||||
|
||||
def is_ipv6(url):
|
||||
return re.match(r'^http:\/\/\[[0-9a-fA-F:]+\]', url) is not None
|
||||
|
||||
def updateChannelUrlsM3U(channels, template_channels, cache):
|
||||
written_urls_ipv4 = set()
|
||||
written_urls_ipv6 = set()
|
||||
url_changes = {"added": [], "removed": [], "modified": []}
|
||||
|
||||
# 检查缓存中的URL状态
|
||||
if is_cache_valid(cache):
|
||||
previous_urls = {}
|
||||
for url_hash, entry in cache["urls"].items():
|
||||
for category, channel_list in entry["channels"].items():
|
||||
for channel_name, url in channel_list:
|
||||
previous_urls[url] = (category, channel_name)
|
||||
|
||||
# 检测URL变化
|
||||
current_urls = {}
|
||||
for category, channel_dict in channels.items():
|
||||
for channel_name, urls in channel_dict.items():
|
||||
for url in urls:
|
||||
current_urls[url] = (category, channel_name)
|
||||
|
||||
# 新增的URL
|
||||
for url, (category, channel_name) in current_urls.items():
|
||||
if url not in previous_urls:
|
||||
url_changes["added"].append((category, channel_name, url))
|
||||
|
||||
# 移除的URL
|
||||
for url, (category, channel_name) in previous_urls.items():
|
||||
if url not in current_urls:
|
||||
url_changes["removed"].append((category, channel_name, url))
|
||||
|
||||
current_date = datetime.now().strftime("%Y-%m-%d")
|
||||
for group in config.announcements:
|
||||
for announcement in group['entries']:
|
||||
if announcement['name'] is None:
|
||||
announcement['name'] = current_date
|
||||
|
||||
ipv4_m3u_path = os.path.join(output_folder, "live_ipv4.m3u")
|
||||
ipv4_txt_path = os.path.join(output_folder, "live_ipv4.txt")
|
||||
ipv6_m3u_path = os.path.join(output_folder, "live_ipv6.m3u")
|
||||
ipv6_txt_path = os.path.join(output_folder, "live_ipv6.txt")
|
||||
|
||||
with open(ipv4_m3u_path, "w", encoding="utf-8") as f_m3u_ipv4, \
|
||||
open(ipv4_txt_path, "w", encoding="utf-8") as f_txt_ipv4, \
|
||||
open(ipv6_m3u_path, "w", encoding="utf-8") as f_m3u_ipv6, \
|
||||
open(ipv6_txt_path, "w", encoding="utf-8") as f_txt_ipv6:
|
||||
|
||||
f_m3u_ipv4.write(f"""#EXTM3U x-tvg-url={",".join(f'"{epg_url}"' for epg_url in config.epg_urls)}\n""")
|
||||
f_m3u_ipv6.write(f"""#EXTM3U x-tvg-url={",".join(f'"{epg_url}"' for epg_url in config.epg_urls)}\n""")
|
||||
|
||||
for group in config.announcements:
|
||||
f_txt_ipv4.write(f"{group['channel']},#genre#\n")
|
||||
f_txt_ipv6.write(f"{group['channel']},#genre#\n")
|
||||
for announcement in group['entries']:
|
||||
url = announcement['url']
|
||||
if is_ipv6(url):
|
||||
if url not in written_urls_ipv6 and is_valid_url(url):
|
||||
written_urls_ipv6.add(url)
|
||||
f_m3u_ipv6.write(f"""#EXTINF:-1 tvg-id="1" tvg-name="{announcement['name']}" tvg-logo="{announcement['logo']}" group-title="{group['channel']}",{announcement['name']}\n""")
|
||||
f_m3u_ipv6.write(f"{url}\n")
|
||||
f_txt_ipv6.write(f"{announcement['name']},{url}\n")
|
||||
else:
|
||||
if url not in written_urls_ipv4 and is_valid_url(url):
|
||||
written_urls_ipv4.add(url)
|
||||
f_m3u_ipv4.write(f"""#EXTINF:-1 tvg-id="1" tvg-name="{announcement['name']}" tvg-logo="{announcement['logo']}" group-title="{group['channel']}",{announcement['name']}\n""")
|
||||
f_m3u_ipv4.write(f"{url}\n")
|
||||
f_txt_ipv4.write(f"{announcement['name']},{url}\n")
|
||||
|
||||
for category, channel_list in template_channels.items():
|
||||
f_txt_ipv4.write(f"{category},#genre#\n")
|
||||
f_txt_ipv6.write(f"{category},#genre#\n")
|
||||
if category in channels:
|
||||
for channel_name in channel_list:
|
||||
if channel_name in channels[category]:
|
||||
sorted_urls_ipv4 = []
|
||||
sorted_urls_ipv6 = []
|
||||
for url in channels[category][channel_name]:
|
||||
if is_ipv6(url):
|
||||
if url not in written_urls_ipv6 and is_valid_url(url):
|
||||
sorted_urls_ipv6.append(url)
|
||||
written_urls_ipv6.add(url)
|
||||
else:
|
||||
if url not in written_urls_ipv4 and is_valid_url(url):
|
||||
sorted_urls_ipv4.append(url)
|
||||
written_urls_ipv4.add(url)
|
||||
|
||||
total_urls_ipv4 = len(sorted_urls_ipv4)
|
||||
total_urls_ipv6 = len(sorted_urls_ipv6)
|
||||
|
||||
for index, url in enumerate(sorted_urls_ipv4, start=1):
|
||||
new_url = add_url_suffix(url, index, total_urls_ipv4, "IPV4")
|
||||
write_to_files(f_m3u_ipv4, f_txt_ipv4, category, channel_name, index, new_url)
|
||||
|
||||
for index, url in enumerate(sorted_urls_ipv6, start=1):
|
||||
new_url = add_url_suffix(url, index, total_urls_ipv6, "IPV6")
|
||||
write_to_files(f_m3u_ipv6, f_txt_ipv6, category, channel_name, index, new_url)
|
||||
|
||||
f_txt_ipv4.write("\n")
|
||||
f_txt_ipv6.write("\n")
|
||||
|
||||
# 保存URL变化日志
|
||||
if url_changes["added"] or url_changes["removed"] or url_changes["modified"]:
|
||||
with open(os.path.join(output_folder, "url_changes.log"), "a", encoding="utf-8") as f:
|
||||
f.write(f"\n=== 更新时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} ===\n")
|
||||
if url_changes["added"]:
|
||||
f.write("\n新增URL:\n")
|
||||
for category, channel_name, url in url_changes["added"]:
|
||||
f.write(f"- {category} - {channel_name}: {url}\n")
|
||||
if url_changes["removed"]:
|
||||
f.write("\n移除URL:\n")
|
||||
for category, channel_name, url in url_changes["removed"]:
|
||||
f.write(f"- {category} - {channel_name}: {url}\n")
|
||||
if url_changes["modified"]:
|
||||
f.write("\n修改URL:\n")
|
||||
for category, channel_name, old_url, new_url in url_changes["modified"]:
|
||||
f.write(f"- {category} - {channel_name}: {old_url} → {new_url}\n")
|
||||
|
||||
def sort_and_filter_urls(urls, written_urls):
|
||||
filtered_urls = [
|
||||
url for url in sorted(urls, key=lambda u: not is_ipv6(u) if config.ip_version_priority == "ipv6" else is_ipv6(u))
|
||||
if url and url not in written_urls and not any(blacklist in url for blacklist in config.url_blacklist)
|
||||
]
|
||||
written_urls.update(filtered_urls)
|
||||
return filtered_urls
|
||||
|
||||
def add_url_suffix(url, index, total_urls, ip_version):
|
||||
suffix = f"${ip_version}" if total_urls == 1 else f"${ip_version}•线路{index}"
|
||||
base_url = url.split('$', 1)[0] if '$' in url else url
|
||||
return f"{base_url}{suffix}"
|
||||
|
||||
def write_to_files(f_m3u, f_txt, category, channel_name, index, new_url):
|
||||
logo_url = f"https://gitee.com/IIII-9306/PAV/raw/master/logos/{channel_name}.png"
|
||||
f_m3u.write(f"#EXTINF:-1 tvg-id=\"{index}\" tvg-name=\"{channel_name}\" tvg-logo=\"{logo_url}\" group-title=\"{category}\",{channel_name}\n")
|
||||
f_m3u.write(new_url + "\n")
|
||||
f_txt.write(f"{channel_name},{new_url}\n")
|
||||
|
||||
if __name__ == "__main__":
|
||||
template_file = "demo.txt"
|
||||
try:
|
||||
# 检查模板文件是否存在
|
||||
if not os.path.exists(template_file):
|
||||
print(f"错误: 找不到模板文件 '{template_file}'。")
|
||||
print("请确保项目目录下有 demo.txt 文件。")
|
||||
print("示例内容如下:")
|
||||
print("""
|
||||
# demo.txt 示例内容
|
||||
央视,#genre#
|
||||
CCTV-1
|
||||
CCTV-2
|
||||
卫视,#genre#
|
||||
北京卫视
|
||||
上海卫视
|
||||
广东卫视
|
||||
""")
|
||||
import sys
|
||||
sys.exit(1)
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
channels, template_channels, cache = loop.run_until_complete(filter_source_urls(template_file))
|
||||
updateChannelUrlsM3U(channels, template_channels, cache)
|
||||
loop.close()
|
||||
print("操作完成!结果已保存到live文件夹。")
|
||||
except Exception as e:
|
||||
print(f"执行过程中发生错误: {e}")
|
||||
logging.error(f"程序运行失败: {e}")
|
|
@ -1 +1 @@
|
|||
144cfea4dc7b28123349e8c990cccf22
|
||||
7840d0b61f9641a47728e3a92020f35a
|
|
@ -0,0 +1,184 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# by @嗷呜
|
||||
import json
|
||||
import sys
|
||||
import time
|
||||
import requests
|
||||
from base64 import b64decode, b64encode
|
||||
from Crypto.Hash import MD5
|
||||
from pyquery import PyQuery as pq
|
||||
sys.path.append('..')
|
||||
from base.spider import Spider
|
||||
|
||||
class Spider(Spider):
|
||||
|
||||
def init(self, extend=""):
|
||||
pass
|
||||
|
||||
def getName(self):
|
||||
pass
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
pass
|
||||
|
||||
def manualVideoCheck(self):
|
||||
pass
|
||||
|
||||
def destroy(self):
|
||||
pass
|
||||
|
||||
host='http://v.rbotv.cn'
|
||||
|
||||
headers = {
|
||||
'User-Agent': 'okhttp-okgo/jeasonlzy',
|
||||
'Accept-Language': 'zh-CN,zh;q=0.8'
|
||||
}
|
||||
|
||||
def homeContent(self, filter):
|
||||
data=requests.post(f'{self.host}/v3/type/top_type',headers=self.headers,files=self.getfiles({'': (None, '')})).json()
|
||||
result = {}
|
||||
classes = []
|
||||
filters = {}
|
||||
for k in data['data']['list']:
|
||||
classes.append({
|
||||
'type_name': k['type_name'],
|
||||
'type_id': k['type_id']
|
||||
})
|
||||
fts = []
|
||||
for i,x in k.items():
|
||||
if isinstance(x, list) and len(x)>2:
|
||||
fts.append({
|
||||
'name': i,
|
||||
'key': i,
|
||||
'value': [{'n': j, 'v': j} for j in x if j and j!= '全部']
|
||||
})
|
||||
if len(fts):filters[k['type_id']] = fts
|
||||
result['class'] = classes
|
||||
result['filters'] = filters
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
data=requests.post(f'{self.host}/v3/type/tj_vod',headers=self.headers,files=self.getfiles({'': (None, '')})).json()
|
||||
return {'list':self.getv(data['data']['cai']+data['data']['loop'])}
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
files = {
|
||||
'type_id': (None, tid),
|
||||
'limit': (None, '12'),
|
||||
'page': (None, pg)
|
||||
}
|
||||
for k,v in extend.items():
|
||||
if k=='extend':k='class'
|
||||
files[k] = (None, v)
|
||||
data=requests.post(f'{self.host}/v3/home/type_search',headers=self.headers,files=self.getfiles(files)).json()
|
||||
result = {}
|
||||
result['list'] = self.getv(data['data']['list'])
|
||||
result['page'] = pg
|
||||
result['pagecount'] = 9999
|
||||
result['limit'] = 90
|
||||
result['total'] = 999999
|
||||
return result
|
||||
|
||||
def detailContent(self, ids):
|
||||
data=requests.post(f'{self.host}/v3/home/vod_details',headers=self.headers,files=self.getfiles({'vod_id': (None, ids[0])})).json()
|
||||
v=data['data']
|
||||
vod = {
|
||||
'vod_name': v.get('vod_name'),
|
||||
'type_name': v.get('type_name'),
|
||||
'vod_year': v.get('vod_year'),
|
||||
'vod_area': v.get('vod_area'),
|
||||
'vod_remarks': v.get('vod_remarks'),
|
||||
'vod_actor': v.get('vod_actor'),
|
||||
'vod_director': v.get('vod_director'),
|
||||
'vod_content': pq(pq(v.get('vod_content','无') or '无').text()).text()
|
||||
}
|
||||
n,p=[],[]
|
||||
for o,i in enumerate(v['vod_play_list']):
|
||||
n.append(f"线路{o+1}({i.get('flag')})")
|
||||
c=[]
|
||||
for j in i.get('urls'):
|
||||
d={'url':j.get('url'),'p':i.get('parse_urls'),'r':i.get('referer'),'u':i.get('ua')}
|
||||
c.append(f"{j.get('name')}${self.e64(json.dumps(d))}")
|
||||
p.append('#'.join(c))
|
||||
vod.update({'vod_play_from':'$$$'.join(n),'vod_play_url':'$$$'.join(p)})
|
||||
return {'list':[vod]}
|
||||
|
||||
def searchContent(self, key, quick, pg="1"):
|
||||
files = {
|
||||
'limit': (None, '12'),
|
||||
'page': (None, pg),
|
||||
'keyword': (None, key),
|
||||
}
|
||||
data=requests.post(f'{self.host}/v3/home/search',headers=self.headers,files=self.getfiles(files)).json()
|
||||
return {'list':self.getv(data['data']['list']),'page':pg}
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
ids=json.loads(self.d64(id))
|
||||
url=ids['url']
|
||||
if isinstance(ids['p'],list) and len(ids['p']):
|
||||
url=[]
|
||||
for i,x in enumerate(ids['p']):
|
||||
up={'url':ids['url'],'p':x,'r':ids['r'],'u':ids['u']}
|
||||
url.extend([f"解析{i+1}",f"{self.getProxyUrl()}&data={self.e64(json.dumps(up))}"])
|
||||
h={}
|
||||
if ids.get('r'):
|
||||
h['Referer'] = ids['r']
|
||||
if ids.get('u'):
|
||||
h['User-Agent'] = ids['u']
|
||||
return {'parse': 0, 'url': url, 'header': h}
|
||||
|
||||
def localProxy(self, param):
|
||||
data=json.loads(self.d64(param['data']))
|
||||
h = {}
|
||||
if data.get('r'):
|
||||
h['Referer'] = data['r']
|
||||
if data.get('u'):
|
||||
h['User-Agent'] = data['u']
|
||||
res=self.fetch(f"{data['p']}{data['url']}",headers=h).json()
|
||||
url=res.get('url') or res['data'].get('url')
|
||||
return [302,'video/MP2T',None,{'Location':url}]
|
||||
|
||||
def liveContent(self, url):
|
||||
pass
|
||||
|
||||
def getfiles(self, p=None):
|
||||
if p is None:p = {}
|
||||
t=str(int(time.time()))
|
||||
h = MD5.new()
|
||||
h.update(f"7gp0bnd2sr85ydii2j32pcypscoc4w6c7g5spl{t}".encode('utf-8'))
|
||||
s = h.hexdigest()
|
||||
files = {
|
||||
'sign': (None, s),
|
||||
'timestamp': (None, t)
|
||||
}
|
||||
p.update(files)
|
||||
return p
|
||||
|
||||
def getv(self,data):
|
||||
videos = []
|
||||
for i in data:
|
||||
if i.get('vod_id') and str(i['vod_id']) != '0':
|
||||
videos.append({
|
||||
'vod_id': i['vod_id'],
|
||||
'vod_name': i.get('vod_name'),
|
||||
'vod_pic': i.get('vod_pic') or i.get('vod_pic_thumb'),
|
||||
'vod_year': i.get('tag'),
|
||||
'vod_remarks': i.get('vod_remarks')
|
||||
})
|
||||
return videos
|
||||
|
||||
def e64(self, text):
|
||||
try:
|
||||
text_bytes = text.encode('utf-8')
|
||||
encoded_bytes = b64encode(text_bytes)
|
||||
return encoded_bytes.decode('utf-8')
|
||||
except Exception as e:
|
||||
return ""
|
||||
|
||||
def d64(self,encoded_text):
|
||||
try:
|
||||
encoded_bytes = encoded_text.encode('utf-8')
|
||||
decoded_bytes = b64decode(encoded_bytes)
|
||||
return decoded_bytes.decode('utf-8')
|
||||
except Exception as e:
|
||||
return ""
|
|
@ -0,0 +1,76 @@
|
|||
"""
|
||||
解析工具模块
|
||||
包含模板解析、输入源解析等功能
|
||||
"""
|
||||
import re
|
||||
from config import URL_BLACKLIST, IP_VERSION_PRIORITY
|
||||
|
||||
def parse_template(template_path):
|
||||
"""
|
||||
解析频道模板文件
|
||||
返回结构化的频道分类和名称列表
|
||||
"""
|
||||
with open(template_path, "r", encoding="utf-8") as f:
|
||||
lines = [line.strip() for line in f if line.strip() and not line.startswith("#")]
|
||||
|
||||
categories = {}
|
||||
current_category = None
|
||||
|
||||
for line in lines:
|
||||
if line.startswith("[") and line.endswith("]"):
|
||||
current_category = line[1:-1].strip()
|
||||
categories[current_category] = []
|
||||
else:
|
||||
if current_category:
|
||||
categories[current_category].append(line.strip())
|
||||
|
||||
return categories
|
||||
|
||||
def parse_source_content(content, source_type):
|
||||
"""
|
||||
解析不同格式的数据源内容(M3U/TXT)
|
||||
返回频道名称到URL列表的映射
|
||||
"""
|
||||
channels = {}
|
||||
if source_type == "m3u":
|
||||
return _parse_m3u(content)
|
||||
elif source_type == "txt":
|
||||
return _parse_txt(content)
|
||||
return channels
|
||||
|
||||
def _parse_m3u(content):
|
||||
"""解析M3U格式内容"""
|
||||
entries = content.split("#EXTINF:-1,")
|
||||
for entry in entries[1:]: # 跳过第一个空元素
|
||||
parts = entry.split("\n", 1)
|
||||
channel_name = parts[0].strip()
|
||||
url = parts[1].strip()
|
||||
if not _is_blacklisted(url) and _has_valid_ip(url):
|
||||
_add_channel(channels, channel_name, url)
|
||||
return channels
|
||||
|
||||
def _parse_txt(content):
|
||||
"""解析TXT格式内容(每行格式:频道名,URL)"""
|
||||
for line in content.splitlines():
|
||||
if "," in line:
|
||||
channel_name, url = line.split(",", 1)
|
||||
channel_name = channel_name.strip()
|
||||
url = url.strip()
|
||||
if not _is_blacklisted(url) and _has_valid_ip(url):
|
||||
_add_channel(channels, channel_name, url)
|
||||
return channels
|
||||
|
||||
def _add_channel(channels, name, url):
|
||||
"""添加频道到映射,按IP版本分类"""
|
||||
ip_version = "IPV6" if "[" in url else "IPV4" # 判断IPv6格式
|
||||
if name not in channels:
|
||||
channels[name] = {"IPV4": [], "IPV6": []}
|
||||
channels[name][ip_version].append(url)
|
||||
|
||||
def _is_blacklisted(url):
|
||||
"""检查URL是否在黑名单中"""
|
||||
return any(bl in url for bl in URL_BLACKLIST)
|
||||
|
||||
def _has_valid_ip(url):
|
||||
"""检查URL是否包含有效IP地址"""
|
||||
return re.search(r"\b(?:\d{1,3}\.){3}\d{1,3}\b|\[([0-9a-fA-F:]+)\]", url) is not None
|
|
@ -0,0 +1,211 @@
|
|||
import asyncio
|
||||
import aiohttp
|
||||
import time
|
||||
import logging
|
||||
import os
|
||||
from dataclasses import dataclass, asdict
|
||||
from typing import List, Dict, Tuple, Optional
|
||||
|
||||
# 配置类
|
||||
class Config:
|
||||
CONCURRENT_LIMIT = 10 # 并发限制
|
||||
TIMEOUT = 10 # 超时时间(秒)
|
||||
RETRY_TIMES = 3 # 重试次数
|
||||
OUTPUT_DIR = "output" # 输出目录
|
||||
LOG_FILE = "speed_test.log" # 日志文件
|
||||
|
||||
config = Config()
|
||||
|
||||
# 日志配置
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||
handlers=[
|
||||
logging.FileHandler(config.LOG_FILE),
|
||||
logging.StreamHandler()
|
||||
]
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 数据类
|
||||
@dataclass
|
||||
class SpeedTestResult:
|
||||
url: str
|
||||
latency: Optional[float] = None # 延迟(毫秒)
|
||||
resolution: Optional[str] = None # 分辨率
|
||||
success: bool = False # 是否成功
|
||||
error: Optional[str] = None # 错误信息
|
||||
test_time: float = 0 # 测试时间戳
|
||||
|
||||
# 速度测试工具类
|
||||
class SpeedTester:
|
||||
def __init__(self):
|
||||
self.session = None
|
||||
|
||||
async def __aenter__(self):
|
||||
self.session = aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=config.TIMEOUT))
|
||||
return self
|
||||
|
||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
||||
if self.session:
|
||||
await self.session.close()
|
||||
|
||||
async def measure_latency(self, url: str, retry_times: int = 3) -> SpeedTestResult:
|
||||
"""测量单个URL的延迟和分辨率"""
|
||||
result = SpeedTestResult(url=url, test_time=time.time())
|
||||
|
||||
for attempt in range(retry_times):
|
||||
try:
|
||||
start_time = time.time()
|
||||
async with self.session.get(url, headers={"User-Agent": "Mozilla/5.0"}) as response:
|
||||
if response.status == 200:
|
||||
# 简单测量响应时间作为延迟
|
||||
latency = (time.time() - start_time) * 1000 # 转换为毫秒
|
||||
|
||||
# 尝试从响应头或内容中提取分辨率信息(简化处理)
|
||||
resolution = None
|
||||
content_type = response.headers.get("Content-Type", "")
|
||||
if "video" in content_type or "application/vnd.apple.mpegurl" in content_type:
|
||||
# 实际应用中可能需要解析m3u8内容获取分辨率
|
||||
resolution = "unknown"
|
||||
|
||||
result.latency = latency
|
||||
result.resolution = resolution
|
||||
result.success = True
|
||||
logger.info(f"URL: {url} 测试成功,延迟: {latency:.2f}ms")
|
||||
break
|
||||
else:
|
||||
result.error = f"HTTP状态码: {response.status}"
|
||||
except Exception as e:
|
||||
result.error = str(e)
|
||||
logger.warning(f"URL: {url} 尝试 {attempt+1}/{retry_times} 失败: {e}")
|
||||
await asyncio.sleep(1) # 重试前等待1秒
|
||||
|
||||
return result
|
||||
|
||||
async def batch_speed_test(self, urls: List[str]) -> List[SpeedTestResult]:
|
||||
"""批量测速(带并发控制)"""
|
||||
results = []
|
||||
semaphore = asyncio.Semaphore(config.CONCURRENT_LIMIT)
|
||||
|
||||
async def worker(url):
|
||||
nonlocal results
|
||||
async with semaphore:
|
||||
result = await self.measure_latency(url, config.RETRY_TIMES)
|
||||
results.append(result)
|
||||
|
||||
tasks = [worker(url) for url in urls]
|
||||
await asyncio.gather(*tasks)
|
||||
|
||||
# 按延迟排序结果(升序)
|
||||
return sorted(results, key=lambda x: x.latency if x.latency is not None else float('inf'))
|
||||
|
||||
# M3U文件处理类
|
||||
class M3UProcessor:
|
||||
@staticmethod
|
||||
def parse_m3u(file_path: str) -> List[Tuple[str, str]]:
|
||||
"""解析M3U文件,返回[(名称, URL), ...]"""
|
||||
try:
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
live_sources = []
|
||||
current_name = None
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if line.startswith('#EXTINF:'):
|
||||
# 提取名称
|
||||
name_start = line.find(',') + 1
|
||||
current_name = line[name_start:] if name_start > 0 else "未知频道"
|
||||
elif line.startswith('http') and current_name:
|
||||
# 添加到源列表
|
||||
live_sources.append((current_name, line))
|
||||
current_name = None
|
||||
|
||||
return live_sources
|
||||
except Exception as e:
|
||||
logger.error(f"解析M3U文件失败: {e}")
|
||||
return []
|
||||
|
||||
@staticmethod
|
||||
def generate_m3u(live_sources: List[Tuple[str, str]], output_path: str) -> None:
|
||||
"""生成M3U文件"""
|
||||
try:
|
||||
os.makedirs(os.path.dirname(output_path), exist_ok=True)
|
||||
|
||||
with open(output_path, 'w', encoding='utf-8') as f:
|
||||
f.write('#EXTM3U\n')
|
||||
for name, url in live_sources:
|
||||
f.write(f'#EXTINF:-1,{name}\n')
|
||||
f.write(f'{url}\n')
|
||||
|
||||
logger.info(f"已生成M3U文件: {output_path}")
|
||||
except Exception as e:
|
||||
logger.error(f"生成M3U文件失败: {e}")
|
||||
|
||||
# 主程序
|
||||
async def main():
|
||||
# 输入输出文件路径
|
||||
input_file = "input/live_sources.m3u"
|
||||
output_file = f"{config.OUTPUT_DIR}/live_sources_sorted_{int(time.time())}.m3u"
|
||||
|
||||
# 解析M3U文件
|
||||
logger.info(f"开始解析M3U文件: {input_file}")
|
||||
m3u_processor = M3UProcessor()
|
||||
live_sources = m3u_processor.parse_m3u(input_file)
|
||||
|
||||
if not live_sources:
|
||||
logger.error("未找到有效的直播源")
|
||||
return
|
||||
|
||||
logger.info(f"找到 {len(live_sources)} 个直播源")
|
||||
|
||||
# 执行速度测试
|
||||
logger.info("开始速度测试...")
|
||||
async with SpeedTester() as tester:
|
||||
urls = [source[1] for source in live_sources]
|
||||
results = await tester.batch_speed_test(urls)
|
||||
|
||||
# 根据测试结果排序直播源
|
||||
url_to_result = {result.url: result for result in results}
|
||||
sorted_live_sources = sorted(
|
||||
live_sources,
|
||||
key=lambda x: url_to_result[x[1]].latency if url_to_result[x[1]].latency is not None else float('inf')
|
||||
)
|
||||
|
||||
# 生成报告
|
||||
success_count = sum(1 for r in results if r.success)
|
||||
total_count = len(results)
|
||||
|
||||
logger.info(f"速度测试完成: 成功 {success_count}/{total_count}")
|
||||
logger.info("前5个最快的直播源:")
|
||||
for i, (name, url) in enumerate(sorted_live_sources[:5], 1):
|
||||
latency = url_to_result[url].latency
|
||||
logger.info(f"{i}. {name} - 延迟: {latency:.2f}ms")
|
||||
|
||||
# 生成排序后的M3U文件
|
||||
m3u_processor.generate_m3u(sorted_live_sources, output_file)
|
||||
|
||||
# 生成速度测试报告
|
||||
report_file = f"{config.OUTPUT_DIR}/speed_test_report_{int(time.time())}.txt"
|
||||
try:
|
||||
with open(report_file, 'w', encoding='utf-8') as f:
|
||||
f.write("IPTV直播源速度测试报告\n")
|
||||
f.write(f"测试时间: {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
|
||||
f.write(f"总测试数量: {total_count}\n")
|
||||
f.write(f"成功数量: {success_count}\n\n")
|
||||
|
||||
f.write("排序后的直播源列表:\n")
|
||||
for i, (name, url) in enumerate(sorted_live_sources, 1):
|
||||
result = url_to_result[url]
|
||||
latency = result.latency if result.latency is not None else "N/A"
|
||||
status = "成功" if result.success else f"失败 ({result.error})"
|
||||
f.write(f"{i}. {name} - 延迟: {latency}ms - 状态: {status}\n")
|
||||
|
||||
logger.info(f"已生成测试报告: {report_file}")
|
||||
except Exception as e:
|
||||
logger.error(f"生成测试报告失败: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|