简介:TVBox开源版是一款面向安卓平台的轻量级电视直播与点播应用,专为追求个性化影音体验的普通用户及开发者设计,解决传统电视内容单一、配置复杂、本地资源难接入等痛点。资源包共28个文件,含13个JSON接口配置文件(如tv.json、alist.json等)、3个properties参数配置、2个XML规则定义、2个M3U/M3U8直播源列表、1个JAR工具库及LICENSE开源协议等,总大小仅940KB,结构精简便于快速部署与二次开发。已有2650人学习下载,体现其在开源影视客户端领域的实用热度。用户可直接安装APK运行,亦可基于tv-master主代码仓深入研究内核移植逻辑(如猫影视V6接口对接机制)、定制本地视频规则、扩展IPTV源或优化播放策略;预览中丰富的JSON与M3U类文件,表明资源已预置多套可用频道源与解析配置,开箱即用的同时保留高度可调性。
1. TVBox 开源版不是“APK下载站”,而是一套可编译、可调试、可定制的安卓视频聚合框架
你手里的tv-master.zip不是成品安装包,而是 TVBox 开源版的完整工程源码仓——它包含从构建脚本、资源配置、接口适配到 UI 模块的全部可编辑文件。这意味着:你无法直接双击安装,但可以精准控制每一个直播源加载逻辑、彻底绕过某类广告跳转、替换掉默认的解析器链路,甚至把本地 NAS 的 SMB 视频目录挂载为一级频道。它面向的不是“点开即用”的普通用户,而是熟悉 Gradle 构建流程、能读懂 Kotlin/Java 混合代码、愿意为播放稳定性牺牲部分 UI 美观度的实践者。如果你曾因某款 TV 盒子 App 突然下架、接口失效或强制升级而丢失全部自定义频道,TVBox 开源版就是你重建播放体系的最小可信基线:所有行为由你本地编译决定,所有资源由你配置文件定义,所有网络请求路径在api1.json、yy2.xml等文件中清晰可见、可审计、可拦截。它不承诺“一键全网资源”,但保证“每一行代码都可追溯”。
2. 从源码仓到可安装 APK:Gradle 构建全流程与关键参数解析
TVBox 开源版的构建本质是标准 Android Studio 工程,但其依赖链和签名配置有明确约束。tv-master目录结构中,app/是主模块,build.gradle(Module: app)定义了核心编译逻辑,而根目录下的gradle.properties和android.properties则控制着签名与环境变量。构建失败的常见原因并非代码错误,而是签名配置缺失或 Gradle 版本不匹配。
2.1 环境准备:JDK、SDK 与 Gradle 的版本锁定
TVBox 开源版主流分支(如基于catv6内核的版本)要求 JDK 17+、Android SDK Build-Tools 34.0.0、Gradle 插件 8.2+。若使用 Android Studio Flamingo 或更高版本,需在gradle/wrapper/gradle-wrapper.properties中确认:
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip提示:不要使用 Android Studio 自动推荐的最新 Gradle 版本。TVBox 源码中
build.gradle使用的compileSdkVersion 34与targetSdkVersion 34严格绑定 Gradle 8.2,高版本 Gradle 会触发AGP 8.3+ requires Java 17类型错误,低版本则报Could not resolve androidx.core:core-ktx:1.12.0。实测 JDK 17.0.10 + Gradle 8.2 + AGP 8.2.2 组合最稳定。
2.2 签名配置:android.properties是构建成功的前提
android.properties文件(位于项目根目录)必须存在且内容完整,否则assembleRelease任务会因找不到 keystore 而中断。典型配置如下:
KEYSTORE_PATH=../my-release-key.jks KEY_ALIAS=my-key-alias KEY_PASSWORD=your_key_password STORE_FILE=../my-release-key.jks STORE_PASSWORD=your_store_password注意:
KEYSTORE_PATH和STORE_FILE必须指向绝对路径或相对于项目根目录的有效路径;KEY_ALIAS必须与生成 keystore 时指定的 alias 一致;密码区分大小写。若无现成 keystore,可用以下命令生成:keytool -genkeypair -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-key-alias执行后按提示输入密钥库密码、密钥别名密码及证书信息,生成的
my-release-key.jks放入项目根目录同级文件夹(如../),再更新android.properties中的路径。
2.3 构建命令与输出定位
在项目根目录执行以下命令启动 Release 构建:
./gradlew assembleRelease --no-daemon--no-daemon参数避免 Gradle 守护进程缓存导致的配置未生效问题。成功后,APK 输出路径为:
app/build/outputs/apk/release/app-release.apk若需调试版(Debug APK),运行:
./gradlew assembleDebug输出路径为app/build/outputs/apk/debug/app-debug.apk。该版本默认启用android:debuggable="true",可连接 Android Studio 进行断点调试,但无法上架应用市场。
| 构建类型 | 命令 | 输出路径 | 是否可上架 | 关键特性 |
|---|---|---|---|---|
| Release | ./gradlew assembleRelease | app/build/outputs/apk/release/app-release.apk | ✅ 是 | 启用 ProGuard 混淆、签名验证、minifyEnabled=true |
| Debug | ./gradlew assembleDebug | app/build/outputs/apk/debug/app-debug.apk | ❌ 否 | 保留调试符号、禁用混淆、可 USB 调试 |
| Bundle | ./gradlew bundleRelease | app/build/outputs/bundle/release/app-release.aab | ✅ 是(Google Play) | 符合 Android App Bundle 标准,支持动态交付 |
2.4 构建失败高频排查点
Failed to find target with hash string 'android-34':说明 SDK Platform 34 未安装。打开 Android Studio → SDK Manager → SDK Platforms → 勾选Android 14 (API 34)→ Apply。Could not get unknown property 'android' for project ':app':build.gradle(Project)中缺少plugins { id 'com.android.application' version '8.2.2' apply false }声明,或settings.gradle未正确 include':app'。Execution failed for task ':app:mergeReleaseResources':res/目录下存在非法命名资源(如icon@2x.png),或strings.xml中有未闭合标签。建议用 Android Studio 的Analyze → Inspect Code全局扫描。
3. 资源配置体系:json、xml、m3u8三类文件的加载优先级与解析规则
TVBox 开源版的资源加载非静态硬编码,而是通过多层配置文件动态注入。tv-master中的api1.json、yy2.xml、fxz.m3u8等文件构成一个可插拔的资源发现网络,其加载顺序、字段含义、容错机制直接决定频道列表是否完整、播放是否卡顿。
3.1 JSON 配置:api1.json与duoduob.json的接口协议解析
api1.json是 TVBox 默认加载的主接口配置,采用标准 JSON 格式,核心字段如下:
{ "name": "主接口", "type": "1", "url": "https://xxx.com/api.php", "ext": "https://xxx.com/player.php?id=", "ua": "Mozilla/5.0 (Linux; Android 11; M2012K11AC) AppleWebKit/537.36" }type:"1"表示 HTTP 接口,"2"表示 M3U8 直链,"3"表示 XMLTV 格式;url: 接口地址,返回 JSON 格式频道列表(含list数组);ext: 解析地址前缀,拼接id后构成真实播放地址;ua: 请求头 User-Agent,用于绕过部分站点的 UA 拦截。
duoduob.json是典型的二级扩展接口,结构相同但type常为"2",直接提供.m3u8地址数组。TVBox 加载时按文件名 ASCII 排序(api1.json<duoduob.json<ym.json),先加载api1.json,失败后自动 fallback 到下一个。
提示:修改
url后需清除 App 数据(设置 → 应用管理 → TVBox → 存储 → 清除数据),否则旧缓存会覆盖新配置。ext字段若为空,TVBox 会尝试从url返回的play_url字段直接取值。
3.2 XML 配置:yy2.xml与tvhz.properties的频道映射逻辑
yy2.xml是 XMLTV 格式文件,用于定义 EPG(电子节目指南)与频道 ID 的绑定关系。其关键节点为<channel>和<programme>:
<channel id="cctv1"> <display-name>CCTV-1 综合</display-name> </channel> <programme start="20240501080000 +0800" stop="20240501090000 +0800" channel="cctv1"> <title>新闻联播</title> </programme>TVBox 在加载yy2.xml时,会将<channel id>与api1.json中返回的id字段匹配,从而为每个频道注入实时节目单。若tvhz.properties存在,则作为属性覆盖文件,例如:
# tvhz.properties player.ua=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 player.timeout=15000该文件中的player.*键值对会全局覆盖播放器行为,timeout单位为毫秒,低于 10000 易导致 HLS 流加载超时。
3.3 M3U8 文件:fxz.m3u8与iptv.m3u的直链加载机制
fxz.m3u8是标准 M3U8 播放列表,格式为:
#EXTM3U #EXTINF:-1,湖南卫视 https://hunantv.live/hunantv/1000k/index.m3u8 #EXTINF:-1,浙江卫视 https://zjtv.live/zjtv/800k/index.m3u8TVBox 对此类文件的处理逻辑是:逐行读取,跳过注释行(#开头),提取#EXTINF后的频道名与下一行的 URL,构造成内存频道列表。其优势在于无需后端接口,但缺点是无法动态更新。iptv.m3u同理,但常被用于批量导入 IPTV 运营商提供的原始流地址。
注意:M3U8 文件必须以 UTF-8 编码保存,BOM 头会导致解析失败;URL 必须为完整 HTTPS 地址,相对路径不被支持;
#EXTINF行末尾的逗号后必须紧跟频道名,空格会被视为名称一部分。
3.4 配置文件加载优先级与冲突解决
TVBox 按以下顺序加载资源文件(同类型内按文件名排序):
- JSON 类:
api*.json>duoduo*.json>ym.json>kj.json - XML 类:
yy*.xml>tv*.xml - M3U 类:
*.m3u8>*.m3u
当多个 JSON 文件返回相同id的频道时,后加载的文件覆盖先加载的。例如api1.json返回{"id":"cctv1","name":"CCTV-1"},duoduob.json返回{"id":"cctv1","name":"央视一套"},则最终显示“央视一套”。此机制可用于热修复失效频道,无需重新编译 APK。
4. 本地资源接入:android.properties与xs.json的存储权限配置与路径映射
TVBox 开源版对本地视频的支持并非简单“浏览文件夹”,而是通过android.properties定义根路径、xs.json定义规则引擎,实现结构化索引与智能分类。这使得 NAS、SMB 共享、USB 设备等外部存储能以“频道”形式无缝融入主界面。
4.1 存储权限声明与运行时授权
android.properties中的local.path字段定义本地扫描根目录:
local.path=/storage/emulated/0/Android/data/com.tvbox.app/files/该路径必须满足两个条件:一是 App 有读写权限(Android 11+ 需声明MANAGE_EXTERNAL_STORAGE并引导用户开启“所有文件访问权限”),二是路径下存在xs.json文件。TVBox 启动时会检查该路径是否存在且可读,失败则禁用本地频道入口。
提示:Android 11 及以上系统,
/sdcard/路径已被沙盒化。若需扫描根目录,必须在AndroidManifest.xml中添加:<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />并在首次启动时调用
ActivityCompat.requestPermissions()获取媒体权限。
4.2xs.json规则引擎:正则匹配与目录映射
xs.json是本地资源的核心配置,采用 JSON Schema 定义扫描规则:
[ { "name": "电影库", "path": "/Movies/", "regex": "(?i)(20\\d{2}|\\d{4})\\s*[年\\.\\-]\\s*.*\\.(mp4|mkv|avi)", "type": "movie" }, { "name": "剧集库", "path": "/TVShows/", "regex": "(?i)[Ss]\\d{2}[Ee]\\d{2}.*\\.(mp4|mkv)", "type": "tv" } ]path: 相对于local.path的子路径,如local.path=/sdcard/+path=/Movies/=/sdcard/Movies/;regex: Java 正则表达式,用于匹配文件名,(?i)表示忽略大小写;type: 分类标识,影响 UI 展示样式(电影显示海报墙,剧集显示季集列表)。
TVBox 扫描时,会递归遍历path下所有文件,对文件名执行regex匹配,成功则加入对应频道。匹配失败的文件被忽略,不占用内存。
4.3 本地播放优化:player.cache与player.buffer参数调优
本地视频播放卡顿常源于缓冲策略不当。android.properties中可配置:
player.cache=true player.buffer=5000000 player.maxbuffer=10000000player.cache=true: 启用本地磁盘缓存,避免重复读取大文件;player.buffer: 初始缓冲区大小(字节),5MB 适合 1080p,10MB 适合 4K;player.maxbuffer: 最大缓冲区上限,超过此值自动丢弃旧数据。
实测表明,对 20GB 以上的蓝光原盘.mkv文件,buffer=8388608(8MB)可显著减少 seek 延迟;而对手机录制的.mp4小文件,buffer=1048576(1MB)即可平衡内存占用与流畅度。
5. 接口调试与播放链路追踪:ADB 日志过滤与Yoursmile.jar的逆向分析技巧
当频道加载失败或播放黑屏时,TVBox 开源版不提供图形化日志面板,必须依赖 ADB 命令抓取底层网络与解码日志。Yoursmile.jar作为独立解析器组件,其调用链路可通过反编译定位关键 Hook 点。
5.1 ADB 日志过滤:聚焦TVBox与ExoPlayer关键事件
连接设备后,执行以下命令实时捕获 TVBox 日志:
adb logcat -s TVBox:V ExoPlayerImpl:V EventLogger:V | grep -E "(load|error|prepared|duration)"关键日志模式解读:
TVBox: load url=https://xxx.m3u8:表示开始加载播放地址;ExoPlayerImpl: state=READY:播放器就绪,可开始渲染;EventLogger: durationMs=3600000:视频总时长(毫秒),用于验证元数据获取;TVBox: error code=403:HTTP 错误码,指示接口鉴权失败;ExoPlayerImpl: error: com.google.android.exoplayer2.upstream.HttpDataSource$InvalidResponseCodeException: Response code: 404:地址返回 404,需检查ext拼接逻辑。
提示:若日志刷屏过快,可重定向到文件并用
less查看:adb logcat -s TVBox:V ExoPlayerImpl:V > tvbox.log less tvbox.log
5.2Yoursmile.jar逆向分析:定位解析器入口与 UA 注入点
Yoursmile.jar是 TVBox 集成的第三方解析器,通常位于app/src/main/assets/目录。使用jadx-gui打开后,搜索关键词parse或getPlayUrl,可找到核心解析类:
public class SmileParser { public static String parse(String url) { // 此处为实际解析逻辑 String ua = System.getProperty("http.agent", "Mozilla/5.0"); HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); conn.setRequestProperty("User-Agent", ua); // ... 省略请求与响应处理 return playUrl; } }关键发现:System.getProperty("http.agent")读取的是 JVM 系统属性,而 TVBox 在Application.onCreate()中通过System.setProperty("http.agent", "Custom-UA")注入 UA。因此,若需修改解析器 UA,必须在SmileParser.parse()调用前设置系统属性,而非仅改android.properties。
5.3 播放失败三步定位法
- 查网络层:ADB 日志中搜索
load url=,复制该 URL 在 Chrome 中访问,确认是否返回 200 且内容为 M3U8; - 查解析层:若 URL 可访问但黑屏,在
SmileParser中断点,检查conn.getResponseCode()是否为 200,conn.getInputStream()是否有数据; - 查解码层:若解析返回有效 URL,但 ExoPlayer 报
DecoderInitializationException,说明视频编码格式(如 AV1)超出设备解码能力,需在player.codec中禁用硬件加速:player.codec=software
此方法可将 90% 的播放问题定位到具体环节,避免盲目更换源或重装 App。
本文还有配套的精品资源,点击获取