Appearance
常见问题 FAQ
本文档整理了 TV Box 源开发和使用过程中的常见问题及解决方案。
源开发类问题
Q1: 为什么我的源代码执行失败?
可能原因:
使用了 ES6+ 语法
- ❌ 箭头函数
() => {} - ❌ 模板字符串
`${var}` - ❌
const/let - ✅ 使用
var和字符串拼接
- ❌ 箭头函数
函数参数缺少默认值处理
javascript// ❌ 错误 function search(keyword, page = 1) {} // ✅ 正确 function search(keyword, page) { if (typeof page === "undefined") { page = 1; } }JSON 解析错误
- 确保返回的是有效的 JSON 字符串
- 使用
JSON.parse()解析前检查字符串是否为空
解决方案:
- 检查代码是否使用 ES5 语法
- 在函数中手动处理默认参数
- 添加 try-catch 错误处理
- 使用
log记录调试信息
Q2: 如何调试源代码?
方法:
使用日志函数
javascriptlog.i("Tag", "信息: " + value); log.e("Tag", "错误: " + error.message);检查返回值
- 确保函数返回正确的数据结构
- 检查返回值的字段是否完整
验证 API 响应
javascriptvar response = http.get(url, headers); log.i("Debug", "响应: " + response); var data = JSON.parse(response); log.i("Debug", "解析后: " + JSON.stringify(data));
Q3: 如何处理 API 响应加密?
示例:
javascript
function request(apiPath, params) {
var response = http.get(url, headers);
var data = JSON.parse(response);
// 如果响应数据是加密的
if (data.encrypted) {
var encrypted = crypto.base64Decode(data.data);
var decrypted = crypto.aesDecrypt(
encrypted,
SOURCE.crypto.key,
SOURCE.crypto.iv
);
data = JSON.parse(decrypted);
}
return data;
}Q4: 如何实现签名验证?
MD5 + SHA1 双重签名示例:
javascript
function generateSign(params) {
var timestamp = new Date().getTime();
var signString = params + "&key=" + SOURCE.sign.key + "&t=" + timestamp;
// 先 MD5,再 SHA1
var md5Hash = crypto.md5(signString);
var sign = crypto.sha1(md5Hash);
return {
sign: sign,
timestamp: timestamp,
};
}Q5: 如何实现多域名自动切换?
示例:
javascript
function init() {
if (SOURCE.host) {
return; // 已初始化
}
// 从缓存读取
var cachedHost = storage.get("source_host");
if (cachedHost) {
SOURCE.host = cachedHost;
return;
}
// 遍历检测可用域名
for (var i = 0; i < SOURCE.hosts.length; i++) {
var host = SOURCE.hosts[i];
try {
var testUrl = host + SOURCE.api.home;
http.get(testUrl, SOURCE.headers);
SOURCE.host = host;
storage.set("source_host", host);
return;
} catch (e) {
// 继续尝试下一个
}
}
// 默认使用第一个
SOURCE.host = SOURCE.hosts[0];
}Q6: 如何设置源类型(type)
源类型说明:
源类型用于区分不同类型的视频源,在 SOURCE 配置对象中设置 type 字段:
javascript
var SOURCE = {
name: "我的视频源",
type: "video", // 可选值:video(电影/影视) | drama(短剧) | live(直播,待支持)
// ...
};类型说明:
"video"- 电影/影视源(默认值),用于常规的电影、电视剧、综艺等内容"drama"- 短剧源,用于短视频剧集内容"live"- 直播源(待支持),用于直播流内容
注意事项:
- 如果不设置
type,默认为"video" - 不同类型的源在应用界面中可能会有不同的展示方式
- 确保
type值与源的实际内容类型匹配
Q7: 搜索返回空结果怎么办?
检查清单:
检查 API 响应
javascriptvar response = request(SOURCE.api.search, params); log.i("Search", "响应: " + response); var data = JSON.parse(response); log.i("Search", "响应 code: " + data.code);检查数据格式
- 确认 API 返回的数据结构
- 检查字段名是否正确(如
vodIdvsid)
检查请求参数
javascriptvar params = "keyword=" + keyword + "&page=" + page; log.i("Search", "请求参数: " + params);检查关键词编码
- 某些 API 需要原始关键词(不编码)
- 某些 API 需要 URL 编码
Q8: 获取播放地址失败怎么办?
常见问题:
剧集 ID 格式错误
javascript// 确保 episodeId 格式正确 var parts = episodeId.split("/"); if (parts.length !== 3) { throw new Error("剧集ID格式错误"); }请求参数错误
- 检查 API 需要的参数格式
- 确认是否需要签名或特殊请求头
播放地址为空
javascriptif (!playData.url || playData.url === "") { throw new Error("播放地址为空"); }
Q9: 如何实现多清晰度播放?
使用 getPlayUrlWithQualities 函数:
javascript
function getPlayUrlWithQualities(episodeId) {
var response = request(SOURCE.api.play, params);
var data = JSON.parse(response);
var playList = data.data.list || [];
var qualities = [];
for (var i = 0; i < playList.length; i++) {
qualities.push({
quality: playList[i].resolutionName || "默认",
url: playList[i].url,
});
}
return {
qualities: qualities,
defaultQuality: qualities[0],
headers: {
Referer: SOURCE.host,
"User-Agent": SOURCE.headers["User-Agent"],
},
};
}订阅管理类问题
Q9: 如何添加新源到订阅列表?
步骤:
在
source.json中添加新源配置:json{ "name": "新源名称", "sourceKey": "new_source_key", "version": "1.0.0", "description": "源描述", "jsSourceUrl": "https://example.com/source.js" }确保
sourceKey唯一确保
jsSourceUrl可访问更新远程订阅文件(如果使用远程订阅)
Q10: 源文件加载失败怎么办?
排查步骤:
检查 URL 是否可访问
bashcurl https://example.com/source.js检查 JavaScript 语法
- 确保使用 ES5 语法
- 检查是否有语法错误
检查网络连接
- 确保设备可以访问互联网
- 检查是否有防火墙限制
检查文件大小
- 建议文件小于 100KB
- 过大文件可能导致加载超时
Q11: 如何更新源版本?
步骤:
- 更新 JavaScript 源文件
- 更新
source.json中的version字段 - 如果使用远程订阅,更新远程文件
- 应用会自动检测并加载新版本
Q12: 如何创建自己的订阅服务?
方法一:使用 GitHub Pages
- 创建 GitHub 仓库
- 上传
source.json文件 - 启用 GitHub Pages
- 订阅 URL:
https://username.github.io/repo/source.json
方法二:使用阿里云 OSS
- 创建 OSS 存储桶
- 上传
source.json文件 - 设置文件为公共读
- 订阅 URL:
https://bucket.oss-region.aliyuncs.com/source.json
方法三:使用 Nginx
- 配置 Nginx 服务器
- 将文件放到网站目录
- 确保返回正确的 Content-Type
Q13: 订阅列表更新失败怎么办?
可能原因:
订阅 URL 不可访问
- 检查 URL 是否正确
- 检查服务器是否正常运行
JSON 格式错误
- 使用 JSON 验证工具检查格式
- 确保所有必需字段都存在
网络问题
- 检查网络连接
- 检查是否有代理设置
解决方案:
- 使用本地
source.json作为备用 - 检查应用日志查看详细错误信息
- 尝试手动刷新订阅列表
功能使用类问题
Q14: 如何切换源?
方法:
- 打开应用设置页面
- 找到"源管理"或"订阅源"选项
- 选择要使用的源
- 应用会自动加载新源
Q15: 搜索功能不工作?
检查:
确认源是否支持搜索
javascript// 在 SOURCE 配置中 searchable: true;检查是否实现了
search函数检查 API 是否正常响应
查看日志中的错误信息
Q16: 视频无法播放?
排查步骤:
检查播放地址获取
javascriptvar playInfo = getPlayUrl(episodeId); log.i("Play", "播放地址: " + playInfo.url);检查请求头
- 某些视频源需要特定的 Referer
- 某些需要 User-Agent
检查视频格式
- 确认播放器支持该格式(m3u8, mp4, flv 等)
检查网络连接
- 确保设备可以访问视频服务器
Q17: 如何查看分类内容?
前提:
- 源实现了
getCategories()函数 - 源实现了
getCategoryContent()函数
检查:
javascript
// 获取分类列表
var categories = getCategories();
log.i("Categories", "分类数量: " + categories.categories.length);
// 获取分类内容
var content = getCategoryContent("1", null, 1);
log.i("Category", "内容数量: " + content.list.length);技术问题
Q18: 如何处理 HTTP 请求超时?
当前实现:
- HTTP 请求默认超时时间为 10 秒
- 可以通过请求头中的
timeout字段设置(如果支持)
建议:
- 在请求函数中添加超时处理
- 使用 try-catch 捕获超时错误
Q19: 如何存储临时数据?
使用 storage API:
javascript
// 保存数据
storage.set("key", "value");
// 读取数据
var value = storage.get("key");用途:
- 缓存域名
- 存储用户配置
- 临时数据存储
Q20: 如何处理大数据量?
建议:
分页加载
javascriptfunction getCategoryContent(categoryId, filters, page) { page = page || 1; var params = "page=" + page + "&pageSize=30"; // ... }延迟加载
- 只加载当前需要的数据
- 使用分页机制
数据过滤
- 在服务器端过滤数据
- 减少返回的数据量
Q21: 如何优化源性能?
优化建议:
减少 HTTP 请求
- 合并多个请求
- 使用缓存机制
优化数据结构
- 只返回必要字段
- 避免深层嵌套
使用存储缓存
javascriptvar cached = storage.get("cache_key"); if (cached) { return JSON.parse(cached); } // 获取新数据并缓存
Q22: 如何处理特殊字符?
URL 编码:
javascript
// 使用 encodeURIComponent
var encoded = encodeURIComponent("特殊字符");
var url = "http://example.com?q=" + encoded;
// 或者使用 crypto.urlEncode
var encoded = crypto.urlEncode("特殊字符");字符串处理:
javascript
// 替换特殊字符
var cleaned = str.replace(/[<>]/g, "");
// 转义 HTML
// 注意:ES5 中没有内置方法,需要手动实现Q23: 如何调试网络请求?
日志记录:
javascript
function request(apiPath, params) {
var url = SOURCE.host + apiPath + "?" + params;
log.i("Request", "URL: " + url);
log.i("Request", "参数: " + params);
var headers = objectAssign({}, SOURCE.headers);
log.i("Request", "请求头: " + JSON.stringify(headers));
var response = http.get(url, headers);
log.i("Request", "响应长度: " + response.length);
log.i("Request", "响应预览: " + response.substring(0, 200));
return response;
}Q24: 如何处理 API 变更?
版本管理:
- 在 SOURCE 配置中设置版本号
- 根据版本号使用不同的 API 路径
- 提供向后兼容
示例:
javascript
var SOURCE = {
version: "2.0.0",
api: {
// 根据版本选择不同的 API
search:
SOURCE.version.indexOf("2") === 0 ? "/api/v2/search" : "/api/v1/search",
},
};错误排查
Q25: 常见错误代码含义
错误信息:
函数 'xxx' 不存在或不是函数- 原因:函数未定义或名称拼写错误
- 解决:检查函数名称和定义
JavaScript 执行错误: missing )- 原因:语法错误
- 解决:检查代码语法,确保使用 ES5
Cleartext HTTP traffic not permitted- 原因:Android 9+ 禁止 HTTP 流量
- 解决:配置网络安全策略或使用 HTTPS
获取详情失败: 没有返回数据- 原因:API 响应格式不符合预期
- 解决:检查 API 响应结构和数据格式
Q26: 如何获取详细的错误信息?
方法:
使用日志
javascripttry { // 代码 } catch (e) { log.e("Error", "错误: " + e.message); log.e("Error", "堆栈: " + e.stack); }检查应用日志
- Android:使用
adb logcat查看日志 - 查找
JsBridge标签的日志
- Android:使用
添加调试信息
javascriptlog.i("Debug", "变量值: " + JSON.stringify(variable));
最佳实践
Q27: 源开发的最佳实践有哪些?
建议:
代码结构
- 使用统一的请求方法
- 实现错误处理
- 添加日志记录
性能优化
- 使用缓存机制
- 实现分页加载
- 减少 HTTP 请求
兼容性
- 支持多域名切换
- 处理 API 版本差异
- 提供降级方案
用户体验
- 提供清晰的错误提示
- 优化加载速度
- 支持多种清晰度
Q28: 如何测试源功能?
测试步骤:
本地测试
- 将源文件放到
assets/目录 - 在
source.json中配置本地路径
- 将源文件放到
功能测试
- 测试搜索功能
- 测试详情获取
- 测试播放地址获取
错误测试
- 测试网络错误
- 测试数据格式错误
- 测试边界情况
性能测试
- 测试加载速度
- 测试大数据量处理
- 测试并发请求
获取帮助
如果以上问题无法解决,可以: