This commit is contained in:
macbook_max
2026-10-15 20:36:59 +08:00
commit 6bf949949c
7923 changed files with 1369582 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
/// 全局配置常量(域名发现、公共请求头、版本号,对应《01-开发文档》5.5/5.6/5.7)
class AppConfig {
AppConfig._();
/// App 版本(对应 pubspec version 的 name 部分;version_code 对应 build 号)
static const String appVersion = '1.0.0';
static const int appVersionCode = 1;
/// 平台标识(运行时按 iOS/Android 判定,见 platformName)
static const String platformNameIOS = 'ios';
static const String platformNameAndroid = 'android';
/// 域名发现:DNS TXT 记录域名与兜底域名后缀
static const String dnsTxtHost = 'txt.256kb.top';
static const String fallbackDomainSuffix = '_jsnbhh.vip';
/// DoH 服务(阿里 / 腾讯),TXT 解析走 JSON API
static const List<String> dohServers = [
'https://223.5.5.5/resolve',
'https://119.29.29.29/dns-query',
];
/// 缓存域名连续失败达到该阈值后,重新走完整发现流程
static const int domainFailureThreshold = 3;
/// 开发调试:--dart-define=API_BASE=http://localhost:8000 可直接指定本地服务,
/// 跳过域名发现(生产构建不传即走 TXT/兜底逻辑)
static const String devApiBase = String.fromEnvironment('API_BASE');
/// 微信支付 iOS 回跳 Universal Link:
/// --dart-define=WECHAT_UNIVERSAL_LINK=https://app.256kb.top/wechat
/// 须与 pubspec.yaml 中 fluwx.ios.universal_link 保持一致;未传时 iOS 端无法回跳
static const String wechatUniversalLink =
String.fromEnvironment('WECHAT_UNIVERSAL_LINK');
/// 请求超时
static const Duration connectTimeout = Duration(seconds: 10);
static const Duration receiveTimeout = Duration(seconds: 20);
}
+20
View File
@@ -0,0 +1,20 @@
import '../../models/video_item.dart';
/// 开发期播放地址钩子:
/// 服务端 /hls 转码产物未就绪前,用 --dart-define=TEST_VIDEO_URL=xxx 注入公网
/// 测试 m3u8,把 video_url 为空或相对路径的条目替换为测试流以验证播放器。
/// 生产构建不传该 define,零开销;服务端 /hls 就绪后此钩子可保留作降级兜底。
const String _testStreamUrl = String.fromEnvironment('TEST_VIDEO_URL');
/// 解析实际播放地址。
/// - 注入了测试流且原始地址不可用(空/非 http 绝对地址)→ 返回测试流
/// - 否则返回原始 video_url
///
/// [testUrl] 可选参数便于单元测试(fromEnvironment 在测试中恒为空)。
String resolvePlayUrl(VideoItem item, {String? testUrl}) {
final injected = testUrl ?? _testStreamUrl;
final raw = item.videoUrl.trim();
final playable = raw.startsWith('http://') || raw.startsWith('https://');
if (!playable && injected.isNotEmpty) return injected;
return raw;
}