前言
最近买了个新电视,打开以后里面自带的视频基本都要收费,那些免费的就恨不得给你上120秒的广告,非常恶心。而且还没直播,这叫啥电视机么。
试过一些看电视的软件,比如曾经的电视家,后来不知道怎么了,停更了。也下了一些box,试用过后,要么是广告一堆,要么是收月租。
后来才知道,各种box都是基于开源TVBox的自制版本。所以我就把原版找到下载安装了,但是原版没有任何资源,就是一个空壳,要想办法弄一些视频源。
文章分两部分:
- 第一部分是直播源的搜集整理
- 第二部分是如何使用
- 如仅需要看电视,可以直接跳转至使用方法章节。
直播源获取方法
通常来说一个直播源是这样的,m3u8格式:
http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226016/index.m3u8
没办法直接打开,requests的话返回的是ts地址,可安装vlc或者浏览器插件来播放,当然这只是一个频道
通常网上会找到一些直播列表,比如像是这样,会有很多频道,而且分好组
#EXTM3U x-tvg-url="https://epg.v1.mk/fy.xml"
#EXTINF:-1,tvg-id="NOWSPORTS4K616" tvg-name="NOWSPORTS4K616" tvg-logo="https://epg.v1.mk/logo/NOWSPORTS4K616.png" group-title="其他",4K60PSDR-H264-AAC测试
https://cdn.jsdelivr.net/gh/feiyangdigital/testvideo/sdr4kvideo/index.m3u8
#EXTINF:-1,tvg-id="NOWSPORTS4K616" tvg-name="NOWSPORTS4K616" tvg-logo="https://epg.v1.mk/logo/NOWSPORTS4K616.png" group-title="其他",4K60PHLG-HEVC-EAC3测试
https://cdn.jsdelivr.net/gh/feiyangdigital/testvideo/hlg4kvideo/index.m3u8
#EXTINF:-1,tvg-id="CCTV1" tvg-name="CCTV1" tvg-logo="https://epg.v1.mk/logo/CCTV1.png" group-title="央视",CCTV1
http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226016/index.m3u8
碰巧搜到了一个收集家,收集了各种m3u
但是源多也不是好事,要一个一个验证,不然导入到电视,很多都打不开,也很影响心情。
Python批量验证直播源
源的验证其实不难,只要requests就好,但是数量太大,要用到协程。
以下代码会将当前目录下的所有m3u文件合并,并且用50并发进行异步请求,扔掉无法访问的或者太慢的。
import os
import glob
import asyncio
import aiohttp
from urllib.parse import urlparse
def is_url(string):
try:
result = urlparse(string)
return all([result.scheme, result.netloc])
except ValueError:
return False
async def verify_url(session, url, semaphore):
async with semaphore:
try:
async with session.head(url, timeout=10) as response:
return response.status < 400
except Exception:
return False
def process_file(file):
channels = []
with open(file, 'r', encoding='utf-8') as f:
lines = f.readlines()
i = 0
while i < len(lines):
line = lines[i].strip()
if line.startswith('#EXTINF'):
title = line
i += 1
while i < len(lines) and not is_url(lines[i].strip()):
i += 1
if i < len(lines):
url = lines[i].strip()
if is_url(url):
channels.append((title, url))
i += 1
return channels
async def main():
m3u_files = glob.glob('*.m3u')
all_channels = {}
for file in m3u_files:
channels = process_file(file)
for title, url in channels:
if title not in all_channels:
all_channels[title] = set() # 使用集合存储不同的 URL
all_channels[title].add(url) # 添加 URL 到集合中
print(f"Total unique channels found: {len(all_channels)}")
valid_channels = []
semaphore = asyncio.Semaphore(50) # 限制并发数为50
async with aiohttp.ClientSession() as session:
tasks = []
for title, urls in all_channels.items():
for url in urls:
task = asyncio.ensure_future(verify_url(session, url, semaphore))
tasks.append((task, url, title))
for i, (task, url, title) in enumerate(tasks, 1):
result = await task
if result:
valid_channels.append((title, url))
print(f"URL {i}/{len(tasks)} is valid: {url}")
else:
print(f"URL {i}/{len(tasks)} is not accessible: {url}")
print(f"Total valid channels: {len(valid_channels)}")
with open('merged_verified.m3u', 'w', encoding='utf-8') as f:
f.write('#EXTM3U x-tvg-url="https://epg.v1.mk/fy.xml"\n')
for title, url in valid_channels:
f.write(f"{title}\n{url}\n")
print("Merged and verified .m3u file has been created: merged_verified.m3u")
if __name__ == "__main__":
asyncio.run(main())
合并完成后上机测试,发现还是有些不能打开,因为毕竟仅仅是验证有无返回,返回的具体内容没做验证,其实可以加一下,比如返回中包含ts的才保留。不过也精简了很多,就不想改了,再写一个单个删除的,把一些不喜欢的删掉。
input_file = 'merged_verified.m3u' # 输入文件名
output_file = 'output.m3u' # 输出文件名
# 要删除的 group-title
remove_groups = {"zonghe", "原创IP", "原创", "科技", "我的世界", "一起看", "4K频道", "少儿动画1",'IPTV少儿动画','韩国娱乐KMTV'}
# 要删除的 IP 地址
remove_ip = "2409:8087:74F1:0021::0008"
with open(input_file, 'r', encoding='utf-8') as infile, open(output_file, 'w', encoding='utf-8') as outfile:
lines = infile.readlines()
skip_next = False
for line in lines:
if line.startswith('#EXTINF'):
# 检查 group-title 是否在要删除的列表中
if any(group in line for group in remove_groups):
skip_next = True # 标记下一个链接行需要跳过
continue
# 检查下一行是否包含要删除的 IP 地址
next_line_index = lines.index(line) + 1
if next_line_index < len(lines) and remove_ip in lines[next_line_index]:
skip_next = True # 标记下一个链接行需要跳过
continue
if skip_next:
skip_next = False # 重置标记
continue
outfile.write(line) # 写入保留的行
print("处理完成,结果保存在", output_file)
代码里自己可以按需增删,删除指定ip或者包含某些关键词的。
如果想要自建组,可以按照这样简单的格式放到m3u最前面。
下面这个就是新建了一个“我的”组,里面有一个天元围棋频道。我从他小程序里抓来的,找了好久,各种源里都没有,只能自己动手了。
#EXTINF:-1,tvg-id="天元围棋" tvg-name="天元围棋" group-title="我的",天元围棋
https://lv.weiqi.com.cn/live/5.m3u8
使用方法
- 下载并安装TVBOX官方软件
- https://github.com/o0HalfLife0o/TVBoxOSC/releases
-
注意某些电视不允许直接安装apk,但是一般有隐藏解锁方案,比如海信电视就是在文件夹页面。。。下面按6次设置。
- 进入tvbox设置页按照如图进行配置,第一行是影视源,第二行是直播源,是我自己整理的。
放两张实际效果图,注意高峰期会卡,所以且用且珍惜
后续发文计划
#AI应用
- 录音识别文字后的校对(已发布)
- 免费的AI图片生成接口
- 最逼真的文字转语音模型
- 论文/网页总结速览及问答
- 自建知识库问答
- 微信bot的应用
#智能家居生活
- 空调30度开一夜,到底会怎样?卧室数据展示(已发布)
- 自制温湿度监控记录报警器
- 语音开关控制方案
- 低成本智能音箱
- 简易自动喂食器
- 酸奶机改造成恒温孵化箱
#免费资源工具分享
- ZLibrary免费图书资源
- 免费电视直播软件(已发布)
- 免费电影站
- 稳定翻墙工具
- B站等视频下载方法
- 免费高品质音乐下载