Compare commits

..

664 Commits

Author SHA1 Message Date
hunlongyu
26bcdd4101 🗃 修复download为空时下载出错 2020-11-14 12:46:44 +08:00
buvta
5104f9a85d v2.6.4.1 2020-11-14 11:47:36 +08:00
hunlongyu
d61ee76e58 Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player 2020-11-13 21:33:13 +08:00
hunlongyu
b1a683a8db 🗑 修复 developer 报错 2020-11-13 21:33:07 +08:00
buvta
5d0dc1bed7 补上落下的async 2020-11-13 21:26:03 +08:00
buvta
3481a5346e 取消时等待数据库更新再刷新代理 2020-11-13 21:05:49 +08:00
buvta
c957fe33e2 取消时更新代理 2020-11-13 21:00:57 +08:00
buvta
51aa21e551 稍微调整 2020-11-13 20:55:11 +08:00
buvta
a887968458 设置增加代理,功能实现 2020-11-13 20:36:33 +08:00
Hunlongyu
380d31c0d3 🌿 新增代理设置界面 ( 功能未完成 ) 2020-11-13 16:28:11 +08:00
Hunlongyu
46b5f82348 Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player into master 2020-11-13 13:52:45 +08:00
Hunlongyu
675622e9ee npm yarn 2020-11-13 13:52:36 +08:00
haiyangcui
9a67821984 移除无用log 2020-11-12 23:35:21 +01:00
haiyangcui
e457574755 开启airplay选项 2020-11-12 22:58:45 +01:00
haiyangcui
50f5154628 Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player 2020-11-12 17:35:43 +01:00
haiyangcui
9da7ffc451 Revert "移除"搜索所有资源"开关,搜索变总是搜索所有资源", 解决推荐排序不工作的问题 2020-11-12 17:35:31 +01:00
buvta
35adae51cc 调整"正在直播"样式 2020-11-12 23:52:47 +08:00
haiyangcui
fe75edd738 v2.6.4 2020-11-12 10:51:29 +01:00
haiyangcui
362dccb167 固定"备注"宽度,"最近更新"列宽度自适应 2020-11-12 10:45:54 +01:00
buvta
08e95611ea 修复频道当前源被包含的bug 2020-11-12 12:09:58 +08:00
buvta
739b3fe30f 调整iptvList加载时机,清除残余代码 2020-11-12 11:37:50 +08:00
buvta
3ba2dc9993 表格列样式调整 2020-11-12 11:26:18 +08:00
buvta
6543d8baf0 推荐页相应调整 2020-11-12 08:34:40 +08:00
buvta
a1c9c657e3 film搜索框样式优化终结版,弹框样式统一为popper 2020-11-12 08:27:19 +08:00
haiyangcui
9306adb60e '全部'改名为'全站' 2020-11-11 21:42:40 +01:00
haiyangcui
682c706618 Revert "film页面el-table引入电影追剧模式" 2020-11-11 21:40:51 +01:00
haiyangcui
02c04c3d46 再次改进搜索框的样式 2020-11-11 17:09:17 +01:00
haiyangcui
17c78522bb 播放页面出现的列表页面,都实现v-on-clickaway 2020-11-11 16:30:22 +01:00
hunlongyu
7af6c73084 ⏱ 修改下拉菜单三角箭头的样式 2020-11-11 22:46:26 +08:00
hunlongyu
d31e0daca9 Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player 2020-11-11 21:41:46 +08:00
hunlongyu
9a7534ba57 ⏲ 移除 child_process 依赖, 使用 node 自带模块 2020-11-11 21:41:39 +08:00
buvta
a73e679b72 Revert "改进搜索框的样式"
This reverts commit b72886fbe6.
2020-11-11 21:36:31 +08:00
buvta
4f6c248345 Revert "引入需要的bootstrap-vue依赖"
This reverts commit 59a89e280b.
2020-11-11 21:36:28 +08:00
hunlongyu
68a0226759 🕰 修改 Film 表格模式样式 2020-11-11 21:26:55 +08:00
haiyangcui
e72af95c75 更新源列表,把检测后不可用的放到最下部 2020-11-11 12:54:04 +01:00
buvta
559e85785f film页面el-table引入电影追剧模式 2020-11-11 13:04:55 +08:00
Hunlongyu
2bf69fb0b9 修复 Play 组件无法弹出侧边栏的BUG 2020-11-11 11:10:48 +08:00
buvta
c082986e09 精简模式引入mode 2020-11-11 08:29:56 +08:00
buvta
05d71a62aa 搜索结果过滤器重置时只给选定列添加 2020-11-11 08:29:12 +08:00
buvta
bb537d789d 解决菜单更新bug 2020-11-11 07:11:30 +08:00
buvta
11baacc778 直播支持精简模式 2020-11-11 07:11:30 +08:00
buvta
9dbc0e00dc 支持频道换源 2020-11-11 07:11:30 +08:00
buvta
23e5c569b1 调整Play直播时播放器下方菜单,支持使用第三方播放器 2020-11-11 07:11:30 +08:00
haiyangcui
59a89e280b 引入需要的bootstrap-vue依赖 2020-11-10 20:39:33 +01:00
haiyangcui
b72886fbe6 改进搜索框的样式 2020-11-10 20:16:06 +01:00
haiyangcui
75bac6582c 简化el-select样式定义 2020-11-10 15:20:48 +01:00
Hunlongyu
7cc7e4e0e6 移除赞助, 移除多余排序文字 2020-11-10 17:15:30 +08:00
buvta
b1707f88d6 Merge pull request #345 from Hunlongyu/buvta
分组搜索
2020-11-10 16:56:39 +08:00
buvta
9ca946eb66 搜索默认设置调整为全部 2020-11-10 15:48:14 +08:00
buvta
76ed091c78 取消IPTV检测时的播放限制 2020-11-10 14:34:14 +08:00
buvta
5965c55773 搜索结果过滤器遵守限制 2020-11-10 14:33:04 +08:00
buvta
6631b8f568 避免后台还在运行的搜索被添加到新搜索中 2020-11-10 13:30:18 +08:00
buvta
b7bb5f85a3 搜索结果不能同时用多个过滤器 2020-11-10 13:03:48 +08:00
buvta
c8795e2aa9 优化分组搜索 2020-11-10 12:21:32 +08:00
buvta
2d7f012180 加搜索按钮 2020-11-10 12:21:32 +08:00
buvta
95ae729df8 Play页面换源由“所有”替换为同组资源站 2020-11-10 12:21:32 +08:00
buvta
40218521ac Film重构搜索以支持分组搜索 2020-11-10 12:21:28 +08:00
buvta
f4396cb69f 调整搜索配置 2020-11-10 12:15:30 +08:00
buvta
2dfbc8a8a2 调整搜索框样式 2020-11-10 12:12:58 +08:00
buvta
f94e8f0bec 改写Film.vue搜索框,预备支持分组搜索 2020-11-10 12:12:55 +08:00
haiyangcui
a9011abdf0 加入Waterfall元素的null check 2020-11-09 18:31:19 +01:00
haiyangcui
843a8dd1fc 移除"搜索所有资源"开关,搜索变总是搜索所有资源 2020-11-09 18:26:07 +01:00
haiyangcui
9b5aae095e Revert "搜索结果加过滤器", 搜索后默认按源站排序 2020-11-09 14:59:49 +01:00
buvta
24e890d1ab 统一操作列风格 2020-11-09 08:19:40 +08:00
buvta
959f515f55 iptv初始化数据加isActive 2020-11-09 08:06:16 +08:00
haiyangcui
f97d63cf68 更新animationEffect为fadein 2020-11-08 22:27:57 +01:00
buvta
c2f3a60198 搜索结果加过滤器 2020-11-09 00:17:08 +08:00
haiyangcui
9128f407ce 获取豆瓣评分时,移除空格 2020-11-08 12:31:00 +01:00
haiyangcui
c5c6e5e34f 修复推荐数据 2020-11-08 12:29:15 +01:00
haiyangcui
b12cdf25d5 改进排序 2020-11-08 12:28:12 +01:00
haiyangcui
7c08627e6f 支持搜索结果排序 2020-11-08 12:18:42 +01:00
haiyangcui
68c3687da3 getSites时无需再设置isActive 2020-11-08 11:35:58 +01:00
haiyangcui
00d6f2d218 更新默认源站数据 2020-11-08 11:33:23 +01:00
buvta
a918713bf7 Merge pull request #343 from Hunlongyu/buvta
增加代理及直播源检测功能
2020-11-08 18:03:52 +08:00
buvta
ae7aaec623 统一editSites状态开关数据类型为Boolean 2020-11-08 18:02:08 +08:00
buvta
81476e0f20 Merge remote-tracking branch 'co/master' 2020-11-08 17:56:48 +08:00
haiyangcui
4136b0f3ce 代理功能,作者:buvta 2020-11-08 00:13:08 +01:00
haiyangcui
c3a4cf5cc5 IPTV检测功能,作者:buvta 2020-11-07 23:55:44 +01:00
haiyangcui
d2263f3f76 添加推荐 2020-11-07 23:18:04 +01:00
haiyangcui
71df73fbd3 推荐页面排序功能 2020-11-07 23:16:00 +01:00
haiyangcui
ba6f3df9b1 升级依赖 2020-11-07 19:56:38 +01:00
haiyangcui
35c205fd86 刷新历史页面瀑布流,改进自适应 2020-11-07 19:29:40 +01:00
haiyangcui
30796af5f8 收藏页面,海报添加观看进度信息 2020-11-07 19:25:49 +01:00
haiyangcui
fde5dbb89d 改进历史视图 2020-11-07 19:14:06 +01:00
buvta
df3b43d8ac 进一步完善shift多选 2020-11-08 01:07:09 +08:00
buvta
8f94a5604d 批处理多选时支持shift快捷键 2020-11-08 00:35:05 +08:00
buvta
c6a39591d5 批量检测时增加进度提示 2020-11-08 00:28:07 +08:00
buvta
051d6b7701 修复导入直播源时的错误 2020-11-08 00:28:02 +08:00
buvta
51ba1d87ad 批量检测时继续限制删除功能 2020-11-08 00:26:45 +08:00
buvta
9af55df310 支持导入同名频道 2020-11-07 21:39:10 +08:00
buvta
d82251fb02 批量删除时重置ID及过滤器 2020-11-07 21:39:10 +08:00
buvta
4d192a4c3a 调整源状态开关列 2020-11-07 21:39:10 +08:00
buvta
1f25219cdc 批量检测时未检查过的优先 2020-11-07 21:39:10 +08:00
buvta
25d65866ae 改动syncTableData以便删除可用 2020-11-07 21:39:10 +08:00
buvta
11559ca164 资源站及直播源编辑页面"清空"替换为批量删除 2020-11-07 21:39:10 +08:00
buvta
6c82178604 完善直播源批量检测时的功能限制 2020-11-07 21:39:10 +08:00
buvta
029d1d9b49 完善源批量检测的功能限制 2020-11-07 21:39:10 +08:00
buvta
c10f7b98d9 去除多余的editSites属性 2020-11-07 21:39:10 +08:00
buvta
48d4b369a8 修正直播源检测出错时返回结果 2020-11-07 21:39:10 +08:00
buvta
42d2b5c20f 添加直播源检测功能 2020-11-07 21:39:09 +08:00
buvta
ccbafaae39 增加代理功能,默认使用系统代理设置 2020-11-07 21:39:09 +08:00
haiyangcui
fb3b908fe8 继续播放时,隐藏进度条,无需检查是否全屏 2020-11-07 21:39:09 +08:00
haiyangcui
4c4cc6d81b 当全屏暂停再继续播放时,隐藏进度条 2020-11-07 21:39:09 +08:00
haiyangcui
9ccfefaafb 历史页面,改进进度展示 2020-11-07 21:39:09 +08:00
haiyangcui
15a38f1b9c 支持历史视图模式 2020-11-07 21:39:09 +08:00
haiyangcui
967657e0ac 修正拼写 2020-11-07 21:39:09 +08:00
Hunlongyu
cd08e9e14b 🥀 新增任务栏显示播放进度 2020-11-07 21:39:09 +08:00
Hunlongyu
7e5bd534ef 🌿 修改样式 2020-11-07 21:39:09 +08:00
Hunlongyu
dce2e36ef0 🍀 修复瀑布流不自动自适应 2020-11-07 21:39:09 +08:00
haiyangcui
8a72b30f79 切换源的时候无需隐藏再显示类型列表 2020-11-07 21:39:09 +08:00
haiyangcui
bbe0d157f4 改进代码 2020-11-07 21:39:09 +08:00
haiyangcui
f44f8ea6cf 统一样式,el-select选择或划过的背景色也用背景色之一 2020-11-07 21:39:09 +08:00
haiyangcui
cd6f9f1f53 删除zy-checkbox的css样式定义 2020-11-07 21:39:09 +08:00
haiyangcui
74d084cb7b zy-table已经被el-table取代,删除无用的样式 2020-11-07 21:39:09 +08:00
haiyangcui
e60962a0f5 删除无用的console输出 2020-11-07 21:39:09 +08:00
haiyangcui
459a54382f el-select实现源站列表和分类列表 2020-11-07 21:39:09 +08:00
haiyangcui
e08a90d87a 修正Recommendation的拼写 2020-11-07 21:39:09 +08:00
haiyangcui
c676159cc7 继续播放时,隐藏进度条,无需检查是否全屏 2020-11-07 12:39:12 +01:00
haiyangcui
0fc8e54d26 当全屏暂停再继续播放时,隐藏进度条 2020-11-07 12:35:35 +01:00
haiyangcui
fe858a0cd9 历史页面,改进进度展示 2020-11-07 12:29:34 +01:00
haiyangcui
2238ddd109 支持历史视图模式 2020-11-07 11:29:03 +01:00
Hunlongyu
cc1c100075 Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player into master 2020-11-06 17:38:48 +08:00
Hunlongyu
81ba6de6cb 🥀 新增任务栏显示播放进度 2020-11-06 17:38:42 +08:00
haiyangcui
28baca56c4 修正拼写 2020-11-06 10:29:50 +01:00
Hunlongyu
3493831729 🌿 修改样式 2020-11-06 10:09:25 +08:00
Hunlongyu
42fce7d137 🍀 修复瀑布流不自动自适应 2020-11-06 10:02:01 +08:00
haiyangcui
c7a4b389e1 切换源的时候无需隐藏再显示类型列表 2020-11-05 23:47:57 +01:00
haiyangcui
5f47789a1a 改进代码 2020-11-05 22:57:29 +01:00
haiyangcui
7591c30b59 统一样式,el-select选择或划过的背景色也用背景色之一 2020-11-05 22:40:53 +01:00
haiyangcui
dd43c18491 删除zy-checkbox的css样式定义 2020-11-05 22:23:07 +01:00
haiyangcui
6949eb16d6 zy-table已经被el-table取代,删除无用的样式 2020-11-05 22:20:53 +01:00
haiyangcui
4a369a755e 删除无用的console输出 2020-11-05 22:15:05 +01:00
haiyangcui
e1b1742424 el-select实现源站列表和分类列表 2020-11-05 22:14:42 +01:00
haiyangcui
de31c4c0bb 修正Recommendation的拼写 2020-11-05 21:28:21 +01:00
cuiocean
c85910edd0 Merge pull request #342 from buvta/forPR
部分功能优化
2020-11-05 21:06:51 +01:00
buvta
b8d78bab10 改动film源站列表加载方式 2020-11-06 00:45:46 +08:00
buvta
9eed5ce0b7 源检测并发执行 2020-11-05 22:08:49 +08:00
buvta
4b11cab4bf axios增加配置 2020-11-05 22:07:38 +08:00
buvta
6ffbc2a63c 优化Film加载提示 2020-11-05 21:19:14 +08:00
haiyangcui
c6f4917cdc 改进瀑布流的样式及鼠标划过的效果 2020-11-05 12:44:30 +01:00
haiyangcui
fe37b32a0f 鼠标移动到卡片上时,添加上移动画效果 2020-11-05 12:38:38 +01:00
Hunlongyu
7fb295d34c 升级依赖 2020-11-05 18:03:31 +08:00
haiyangcui
e8c5c0ec72 改进瀑布流设置,更好的适应宽度 2020-11-04 14:52:47 +01:00
haiyangcui
64dc9c98d2 v2.6.3 2020-11-04 12:13:05 +01:00
haiyangcui
ca36841f5d 打开换源页面时,记录当前时间,换源时使用该时间。否则,如果换源失败,this.xg.currentTime 会被重置为0 2020-11-04 12:11:49 +01:00
haiyangcui
59d33d201c 如果时间进度已经设定,无需读取历史数据 2020-11-04 09:43:20 +01:00
haiyangcui
bf3b6d4088 再次解决换源时间进度问题 2020-11-04 09:06:48 +01:00
haiyangcui
bf2567bfde 修复推荐里豆瓣评分2 2020-11-03 22:56:55 +01:00
haiyangcui
3499fb5937 修复推荐里错误的评分 2020-11-03 22:49:13 +01:00
haiyangcui
dec12c77d0 添加两个新源,牛牛和百度云 2020-11-03 22:11:58 +01:00
haiyangcui
17be5d45f1 v2.6.2 2020-11-03 17:16:51 +01:00
haiyangcui
f493fcd24e 屏蔽福利片checkbox可以直接关联setting.excludeR18Films 2020-11-03 17:06:05 +01:00
haiyangcui
d040bc01fc 更新收藏导出时的提示 2020-11-03 16:45:38 +01:00
haiyangcui
6644c97811 导入收藏时,deep copy当前的list,否则列表会在没有排序好之前就被展示 2020-11-03 16:39:00 +01:00
haiyangcui
68960ab5bb 改进star的导入导出时的排序问题 2020-11-03 16:34:12 +01:00
haiyangcui
46de044214 统一海报视图 2020-11-03 15:46:48 +01:00
haiyangcui
0cbf9ca7fb 改进推荐页面排序问题 2020-11-03 15:41:15 +01:00
haiyangcui
6fa40af9bd 更新推荐 2020-11-03 15:23:38 +01:00
haiyangcui
7343f1824a 集中豆瓣评分和豆瓣链接获取功能到tools中 2020-11-03 14:57:07 +01:00
haiyangcui
3df0665950 改进过滤关键词 2020-11-03 14:13:26 +01:00
haiyangcui
022b1b28ad 改进Film页面刷新的逻辑,避免不必要的刷新 2020-11-03 13:56:41 +01:00
haiyangcui
55d1740354 移动"屏蔽福利片"到源编辑页面 2020-11-03 12:58:34 +01:00
haiyangcui
9d71991103 如果开启屏蔽福利片选项,也过滤搜索结果 2020-11-02 22:08:38 +01:00
haiyangcui
361e24ecad 引入vue-clickaway 2020-11-02 21:28:29 +01:00
haiyangcui
53f80d2cce 点击换源后,不需要关闭换源窗口.用户可以等待新源确定工作后自行关闭 2020-11-02 21:09:53 +01:00
haiyangcui
880dd9ff35 重新解决换源时间进度问题,发现记录this.video.info.time的话,视频会卡一下 2020-11-02 18:03:47 +01:00
haiyangcui
42c89120da 如果没有任何收藏有更新时,发消息提醒用户'未查询到任何更新' 2020-11-02 17:54:43 +01:00
haiyangcui
d990aa92b0 记录当前播放时间this.video.info.time, 解决换源时时间进度定位问题 2020-11-02 16:23:05 +01:00
haiyangcui
e117564ecb 在style.css里统一定义el-select的样式 2020-11-02 12:11:45 +01:00
haiyangcui
99592e3fcb 改进el-select样式,设置不同主题下的背景色等 2020-11-02 11:21:33 +01:00
Hunlongyu
adc8fd4329 🍁 修复因为分类异常, 导致资源加载不出来. 2020-11-02 13:44:10 +08:00
haiyangcui
579caddaeb 更新推荐 2020-11-01 23:29:49 +01:00
haiyangcui
1d5344f292 更新推荐 2020-11-01 23:19:32 +01:00
haiyangcui
22dc74ea3a 更新推荐 2020-11-01 23:15:39 +01:00
haiyangcui
72d7c91540 更新推荐 2020-11-01 22:38:46 +01:00
haiyangcui
ef874d1831 v2.6.1 2020-11-01 18:36:08 +01:00
haiyangcui
bb9a8ca65d 获取其他源时,排除当前源 2020-11-01 18:03:33 +01:00
haiyangcui
747abf3b26 设置密码对话框的宽度 2020-11-01 17:41:20 +01:00
haiyangcui
1078cf3c63 修复自动更新功能 2020-11-01 17:29:57 +01:00
haiyangcui
22b877b0fb 定义不同的waterfall的ref 2020-11-01 17:24:29 +01:00
haiyangcui
34e6b8bd08 更新推荐 2020-11-01 14:02:11 +01:00
haiyangcui
4d039e9a63 更新推荐后刷新分类过滤数据 2020-11-01 14:01:48 +01:00
haiyangcui
16f3954959 删除无用的style 2020-11-01 12:17:20 +01:00
haiyangcui
17845e6ab4 改进换源功能,在新源中打开当前剧集和时间进度 2020-11-01 12:07:54 +01:00
hunlongyu
292f932130 Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player 2020-11-01 15:29:24 +08:00
hunlongyu
127ef9ad43 ⛸ 设置界面样式微调 2020-11-01 15:26:31 +08:00
cuiocean
11f0ae27fd v2.6.0 2020-11-01 08:22:24 +01:00
hunlongyu
2599343943 样式优化, 修复film table 错误提示 2020-11-01 14:57:49 +08:00
haiyangcui
0fb5903416 v2.5.9 2020-10-31 22:56:40 +01:00
haiyangcui
ce89720c55 调换收藏页面'源站'列的位置 2020-10-31 22:51:37 +01:00
haiyangcui
8ff7fa588a 恢复el-table滚动条 2020-10-31 22:45:19 +01:00
haiyangcui
8d5bbedfd8 解决el-table刷新自动跳到顶端的问题 2020-10-31 22:40:52 +01:00
haiyangcui
713e0affae 更新推荐 2020-10-31 22:31:25 +01:00
haiyangcui
0f55f3b2ea 显示推荐视频总数 2020-10-31 22:12:58 +01:00
haiyangcui
c98e41201d 不显示导演信息,有时导演名字字符太多 2020-10-31 22:12:45 +01:00
haiyangcui
2cfd31806d 修复搜索后打开详情页错误的问题 2020-10-31 22:06:33 +01:00
haiyangcui
d54dab4e90 改进豆瓣评分样式 2020-10-31 22:04:25 +01:00
haiyangcui
2af85fbfd1 Film页面,列表视图用el-table实现,感谢buvta贡献 2020-10-31 21:44:05 +01:00
haiyangcui
15c542db82 Film页面搜索用el-table实现 2020-10-31 21:34:32 +01:00
haiyangcui
1a3ccaa3ba 统一editsite页面的格式 2020-10-31 21:23:55 +01:00
haiyangcui
3d01fd045f 统一优化listpage格式 2020-10-31 12:28:36 +01:00
haiyangcui
f6636a7864 重置软件也受密码保护 2020-10-30 23:06:24 +01:00
haiyangcui
dd108d3b09 避免不必要的刷新 2020-10-30 18:27:04 +01:00
haiyangcui
0b24ded61f 同步时,如果没有更新,不再提示 2020-10-30 18:17:13 +01:00
haiyangcui
d21494cf86 集中在style中定义pictureView的格式 2020-10-30 18:13:12 +01:00
haiyangcui
76add8f87a "编辑源"可以设置密码 2020-10-30 17:48:10 +01:00
haiyangcui
5a115700e3 收藏视图添加有更新提示,优化格式 2020-10-30 15:16:05 +01:00
haiyangcui
16e8ef2c4a 收藏页面播放,无需再查看历史记录,收藏数据已包含 2020-10-30 13:52:09 +01:00
haiyangcui
483449aad8 v2.5.8 2020-10-30 11:52:31 +01:00
haiyangcui
2b7a425f6f 影视推荐位置上移,更靠近Film页面 2020-10-30 11:50:17 +01:00
haiyangcui
a06c9e9d32 缩小地区和类型的按钮大小 2020-10-30 11:28:35 +01:00
haiyangcui
32a21952a2 推荐页面,视图添加地区信息 2020-10-30 11:25:47 +01:00
haiyangcui
ff01abe88c 改进推荐页面的过滤功能 2020-10-30 11:22:09 +01:00
haiyangcui
962f6b46c3 推荐页面,支持地区,类型的过滤 2020-10-30 10:58:31 +01:00
haiyangcui
b16604add6 更新推荐列表 2020-10-30 10:03:47 +01:00
haiyangcui
3028939ed9 改进豆瓣评分获取的算法 2020-10-30 09:43:04 +01:00
haiyangcui
1ffcb38b4b 优化'豆瓣评分'样式 2020-10-30 09:11:12 +01:00
Hunlongyu
2ec05b6ab5 🎳 移除request, 使用已有同样功能的axios重写.优化豆瓣评分样式 2020-10-30 10:05:45 +08:00
Hunlongyu
9cbd37d143 Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player into master 2020-10-30 09:30:59 +08:00
Hunlongyu
b9ab1b11f4 🎱 关闭有可能导致安全软件报警的代码 2020-10-30 09:30:53 +08:00
haiyangcui
428f49a2e8 更新推荐电影 2020-10-29 23:50:29 +01:00
haiyangcui
2e8941c6cc 记录推荐页的视图模式 2020-10-29 23:12:40 +01:00
haiyangcui
91e2fc56b7 添加recommandation数据库,支持更新推荐 2020-10-29 22:55:14 +01:00
haiyangcui
e2b124e4ac 添加“影视推荐”页面 2020-10-29 21:51:34 +01:00
haiyangcui
6b37e3ebd5 定义pictureView样式并复用 2020-10-29 21:36:12 +01:00
haiyangcui
5dcdb6a410 记录sartViewMode 2020-10-29 18:29:23 +01:00
haiyangcui
5d41f783bc 统一海报视图的格式 2020-10-29 15:47:12 +01:00
haiyangcui
28ad8f3313 详情页面收藏的话,如果收藏已存在,更新收藏信息 2020-10-29 12:49:30 +01:00
haiyangcui
c475fbdf46 收藏视图页面添加豆瓣评分信息 2020-10-29 12:46:06 +01:00
Hunlongyu
ee622f88da 🏉 收藏新增海报模式. 2020-10-29 18:12:54 +08:00
haiyangcui
1b2461c423 Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player 2020-10-29 10:10:37 +01:00
Hunlongyu
3044bfcbc4 🏈 mini 界面优化 2020-10-29 16:59:25 +08:00
haiyangcui
4038e5e6be Merge branch 'dev_improveStar' 2020-10-29 09:32:28 +01:00
haiyangcui
bea1ef4c73 收藏页面添加视图开关 2020-10-29 09:12:33 +01:00
Hunlongyu
7af9a6d76d 🏐 编辑源增加状态排序, 修复换源功能里源的标识问题. 优化搜索结果样式变形 2020-10-29 15:32:56 +08:00
Hunlongyu
2140d90a87 🏀 源编辑,加入单个源检测功能. 2020-10-29 14:45:46 +08:00
Hunlongyu
e86eef1b05 添加快捷键指南, 修复换源功能阻塞问题 2020-10-29 14:35:58 +08:00
haiyangcui
42dd8fe5e4 star添加豆瓣评分记录 2020-10-29 00:09:29 +01:00
haiyangcui
9fd8c60dd5 "获取豆瓣评分"功能到tools.js 2020-10-28 23:29:39 +01:00
haiyangcui
49c480061b 收藏数据里记录detail所有内容 2020-10-28 18:09:10 +01:00
hunlongyu
022b1f4090 紧急修复视频源检测bug, 以及增加手动更新提示。 2020-10-28 22:44:53 +08:00
hunlongyu
9c08a64524 💎 手动更新提示 2020-10-28 22:11:41 +08:00
hunlongyu
90ec848c11 v2.5.6 2020-10-28 21:45:48 +08:00
hunlongyu
82270a702f v2.5.5 2020-10-28 21:39:29 +08:00
Hunlongyu
61dcb1ec49 💍 优化视频源分组功能 2020-10-28 18:22:18 +08:00
Hunlongyu
40b853361e 💄 新增或编辑源的时候, 校验key值的唯一性 2020-10-28 18:00:59 +08:00
Hunlongyu
57ff3325f0 💋 优化图标显示逻辑 2020-10-28 17:38:02 +08:00
Hunlongyu
c4283e2da0 🎓 优化播放页图标, 优化视频停止播放后不显示历史记录提示. 修复报错 2020-10-28 17:30:46 +08:00
Hunlongyu
7052bd7e05 🎩 新增播放视频时换源功能. 2020-10-28 17:04:44 +08:00
Hunlongyu
64a12a06c4 👒 移除百度统计, 主要是记录缺失, 并且不准确 2020-10-28 15:38:02 +08:00
Hunlongyu
3df3b385ce ⛑ 新增分类过滤器, 主要针对豆瓣资源网分类出错问题 2020-10-28 15:34:33 +08:00
Hunlongyu
e77db4711e 🧢 优化视频源检测功能 2020-10-28 15:33:30 +08:00
Hunlongyu
fb3fd26870 Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player into master 2020-10-28 12:00:14 +08:00
Hunlongyu
72790f5f3e 👑 添加了视频源检测功能. 2020-10-28 11:59:55 +08:00
haiyangcui
ea2815969d 把IPTV的初始数据放入单独的Json文件中 2020-10-27 23:12:30 +01:00
Hunlongyu
e330cff7d4 🧦 electron 优化, 忽略证书错误, 关闭沙盒. 2020-10-27 11:43:11 +08:00
haiyangcui
da5b91535e 搜索后获取详细信息并展示 2020-10-26 23:53:12 +01:00
haiyangcui
00c8f0c1e2 v2.5.4 2020-10-26 17:26:49 +01:00
haiyangcui
924fd439d9 更新导入收藏,支持一次导入多个文件 2020-10-26 16:37:44 +01:00
haiyangcui
ed039894c8 导入时无需调用upgradeFavorites 2020-10-26 16:20:08 +01:00
haiyangcui
005bdf7ea6 监听并更新收藏及源列表 2020-10-26 16:19:48 +01:00
haiyangcui
19071faf70 更新福利片关键词 2020-10-26 15:13:18 +01:00
hunlongyu
176d9f6b5a Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player 2020-10-26 20:57:31 +08:00
hunlongyu
31a8dd0f32 🧤 升级 xgplayer 依赖 2020-10-26 20:57:25 +08:00
haiyangcui
336ea08c69 Film页面只获取active的源站 2020-10-26 13:47:47 +01:00
haiyangcui
8e4a0870a1 播放电视频道时,更新播放页面的左上角标题 2020-10-26 13:42:44 +01:00
hunlongyu
86130e6c53 🧣 修复第一次加载资源失败的bug 2020-10-26 20:24:35 +08:00
Hunlongyu
e984d0a349 🩳 修复修改数据库,导致无法播放的bug 2020-10-26 18:18:07 +08:00
Hunlongyu
506991f3b1 👖 优化 history 和 star 数据库的搜索.后台不再提示warning.需要重置数据库. 2020-10-26 18:06:01 +08:00
Hunlongyu
04c35ba7a9 👔 开发所有系统的更新功能 2020-10-26 16:46:41 +08:00
Hunlongyu
275b6757bf 👕 实现手动更新功能 2020-10-26 16:33:00 +08:00
Hunlongyu
612930cc8b 🥼 修复停止播放后,再次播放有2个声音的问题 2020-10-26 11:19:15 +08:00
haiyangcui
80e36fa99c 源站排序总是有问题, 先移除掉 2020-10-25 15:40:18 +01:00
haiyangcui
f069044f28 简单重构 2020-10-25 16:23:31 +01:00
haiyangcui
c77ac7ea7f 重构一下EditSites页面的代码 2020-10-25 15:33:39 +01:00
haiyangcui
803181b4f7 修复源页面编辑后Film页面不更新的bug 2020-10-25 13:49:58 +01:00
haiyangcui
ac2474903d 恢复滚动条 2020-10-24 23:38:02 +02:00
haiyangcui
04b7e139da 更新内置电视频道 2020-10-24 23:00:58 +02:00
haiyangcui
b49e1b82bf 支持自选源列排序 2020-10-24 23:00:40 +02:00
haiyangcui
dc00c690e7 重新排序后更新数据库 2020-10-24 22:58:15 +02:00
haiyangcui
44ba552435 改进IPTV页面逻辑 2020-10-24 16:20:49 +02:00
haiyangcui
8d84d1bf22 统一字体大小 2020-10-24 14:29:30 +02:00
haiyangcui
c78368dac9 新增源时,支持输入源标识 2020-10-24 14:24:18 +02:00
haiyangcui
11af5a7ecd 导入收藏时,更新收藏项的源站信息 2020-10-24 14:14:44 +02:00
haiyangcui
ecfeecf45f 为表头按钮添加图标 2020-10-24 14:06:25 +02:00
haiyangcui
455f5dae84 统一star数据格式的定义 2020-10-24 13:19:47 +02:00
Hunlongyu
ffbffde74f Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player into master 2020-10-24 13:52:29 +08:00
Hunlongyu
0be0433355 🥼 移除master 分支下的更新功能 2020-10-24 13:52:20 +08:00
haiyangcui
cc2dc19e39 Revert "统一star数据格式的定义"
This reverts commit aa4583898a.
2020-10-23 23:31:44 +02:00
haiyangcui
aa4583898a 统一star数据格式的定义 2020-10-23 23:31:01 +02:00
haiyangcui
2e96812a1f 最后一列的表头向右对齐 2020-10-23 23:23:25 +02:00
haiyangcui
6f52d73d52 鼠标划过的行添加少许放大效果 2020-10-23 22:45:04 +02:00
haiyangcui
a3ebba641f 源站编辑,支持编辑分组 2020-10-23 22:29:52 +02:00
haiyangcui
8ceffab2fe 搜索结果里添加“源站”列 2020-10-23 16:43:33 +02:00
haiyangcui
454d192141 更好支持中文排序 2020-10-23 15:53:21 +02:00
haiyangcui
a1423993c8 固定表头 2020-10-23 15:14:12 +02:00
haiyangcui
1c9a84dbc6 开关批处理,无需返回页面顶部 2020-10-23 13:37:41 +02:00
haiyangcui
304b0d10b4 Fix typo 2020-10-23 13:32:46 +02:00
cuiocean
aff97f6d46 Merge pull request #307 from buvta/patch-1
IPTV小调整
2020-10-23 12:27:23 +02:00
haiyangcui
650c882f58 移除自选源列的排序 2020-10-23 12:20:17 +02:00
Hunlongyu
32fa465cf2 🦺 关闭自动更新, 手动更新软件. (未完成) 2020-10-23 14:40:40 +08:00
Hunlongyu
1fdfada14f Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player into master 2020-10-23 11:21:52 +08:00
Hunlongyu
5ed8b6e49a 👓 补上忘记写的自动更新功能 😂 2020-10-23 11:20:36 +08:00
haiyangcui
c2e2f1c490 支持自选源列排序 2020-10-22 18:34:00 +02:00
haiyangcui
7ad40ba375 历史记录的导入导出 2020-10-22 18:22:41 +02:00
buvta
c708292051 IPTV变更分租状态开关时表格回到顶部 2020-10-23 00:02:18 +08:00
buvta
79932a74bc 固定IPTV和源编辑表头 2020-10-22 23:48:19 +08:00
buvta
3f79f31550 IPTV转移总频道数到表头
这PR也太好混了吧
2020-10-22 23:40:28 +08:00
haiyangcui
1d33db0143 IPTV支持从JSON文件导入 2020-10-22 17:07:05 +02:00
haiyangcui
1dc7b38160 批处理开启关闭源是否为自选源 2020-10-22 16:53:57 +02:00
haiyangcui
db7cdab787 批处理视频源的分组 2020-10-22 16:37:54 +02:00
haiyangcui
d1e6ac1ae6 支持源分组 2020-10-22 16:18:24 +02:00
haiyangcui
d63710afe6 统一字体大小 2020-10-22 14:07:14 +02:00
haiyangcui
8abe4b7ef8 IPTV批处理分组 2020-10-22 14:04:45 +02:00
haiyangcui
98b4f5bc1d 改进star页面的排序 2020-10-22 12:27:45 +02:00
haiyangcui
248c0994c9 统一页面字体大小,更新操作栏使其自适应宽度 2020-10-22 12:22:19 +02:00
Hunlongyu
2eba0523bc 🛒 优化分享图片 2020-10-22 14:23:38 +08:00
Hunlongyu
49589102d9 🧶 添加百度统计 2020-10-22 14:22:59 +08:00
Hunlongyu
79b02df628 🧵 优化初次加载请求多次的问题 2020-10-22 13:41:47 +08:00
Hunlongyu
0f456fe7a8 🧵 优化样式 2020-10-22 11:33:30 +08:00
Hunlongyu
850c8d5423 🎨 视频源异常状态处理, 自动重置源 2020-10-22 10:59:29 +08:00
haiyangcui
63cf367f52 自适应列宽 2020-10-21 18:42:50 +02:00
haiyangcui
bd43f06e7d 可以打开或关闭源是否为自选源 2020-10-21 17:34:11 +02:00
haiyangcui
2ed47e64c3 解决Film页面的warning 2020-10-21 17:11:54 +02:00
haiyangcui
8817d39d49 IPTV搜索移到表头位置 2020-10-21 16:25:15 +02:00
haiyangcui
b68525213a 引入需要的element-ui的组件 2020-10-21 16:07:37 +02:00
haiyangcui
0efbc38137 Merge branch 'release_2.5.3' 2020-10-21 13:51:16 +02:00
haiyangcui
cd2cb684a5 v2.5.3 2020-10-21 12:35:07 +02:00
Hunlongyu
500dbfa1ee 🖼 测试代码 2020-10-21 18:23:45 +08:00
Hunlongyu
e970074266 Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player into master 2020-10-21 15:33:58 +08:00
Hunlongyu
9dc7ab4d1e 🎪 升级最新依赖 2020-10-21 09:13:53 +08:00
haiyangcui
ffe821d107 IPTV函数名更新 2020-10-20 21:57:52 +02:00
Hunlongyu
0f015b26e2 🎢 优化 IPTV 的搜索框样式 2020-10-20 09:27:13 +08:00
haiyangcui
f031f9e7fd 修复确定分组的逻辑 2020-10-19 23:40:50 +02:00
haiyangcui
b38de7f393 IPTV分组 2020-10-19 22:57:53 +02:00
haiyangcui
8b5e8fd072 IPTV添加group 2020-10-19 22:15:50 +02:00
haiyangcui
58e556554e IPTV搜索功能 2020-10-19 21:21:59 +02:00
haiyangcui
cceed30d35 IPTV拖曳功能 2020-10-19 13:46:59 +02:00
haiyangcui
980b0a6e50 el-table实现IPTV页面 2020-10-19 13:46:59 +02:00
Hunlongyu
c98236222d 🎡 修复 Film table 模式下, 不加载的 BUG 2020-10-19 18:37:48 +08:00
Hunlongyu
6a7c2afb2d 🎠 代码优化 2020-10-19 18:31:46 +08:00
Hunlongyu
af482a450a 🎟 新增右键菜单 2020-10-19 18:14:42 +08:00
Hunlongyu
42b81b98cf 🎞 修复 Film 视图报错 BUG 2020-10-19 17:42:00 +08:00
Hunlongyu
da7dfed5ba 🎁 修复视频停止播放后, 下次点击按钮失效的问题 2020-10-19 17:28:17 +08:00
Hunlongyu
7d6c5482af 🎀 新增窗口最小化, 暂停视频. 从最小化恢复窗口, 视频播放 2020-10-19 16:57:32 +08:00
Hunlongyu
11e7ffc554 🎑 新增视频停止播放按钮 2020-10-19 16:31:02 +08:00
Hunlongyu
4974d57fbf 🎑 mini 模式修复 2020-10-19 13:41:50 +08:00
Hunlongyu
037bb1a2ff 🎐 升级electron依赖到最新版 2020-10-19 13:40:12 +08:00
Hunlongyu
b19870d228 🎏 优化 table 滚动条 2020-10-19 11:52:28 +08:00
Hunlongyu
de0161c560 🎎 升级依赖, 修复element 2020-10-19 11:28:52 +08:00
Hunlongyu
623a10bd13 🎎 按需引入 element button 2020-10-19 11:09:14 +08:00
Hunlongyu
c69eadbe3e 🎍 新增清理视频缓存功能 2020-10-19 11:00:11 +08:00
Hunlongyu
5f48f46cbc 🎋 table style 2020-10-19 09:35:50 +08:00
haiyangcui
694986d6c5 用el-button实现header部分的按钮 2020-10-18 22:54:21 +02:00
haiyangcui
d4ad68e030 监听EditSites页面sites数据变化 2020-10-18 21:57:39 +02:00
haiyangcui
72089bf53f Code cleanup 2020-10-18 18:05:48 +02:00
haiyangcui
0401ce6d7e Revert "记录窗口大小及位置"
This reverts commit 381b0a8735.
2020-10-18 10:11:26 +02:00
haiyangcui
09e27d4f40 添加overflow-y: auto;到el-table格式定义中 2020-10-18 09:38:06 +02:00
haiyangcui
45de6650bf 统一EditSites页面格式 2020-10-17 23:59:58 +02:00
haiyangcui
4e0fa4d980 支持sites页面拖曳排序 2020-10-17 23:35:01 +02:00
haiyangcui
7a0f8f9644 支持star页面的拖曳排序 2020-10-17 21:19:05 +02:00
haiyangcui
e43ef98ce7 支持历史页面的拖曳排序 2020-10-17 21:11:50 +02:00
haiyangcui
2abbf41ed1 header上的按钮,鼠标划过更改指针模式 2020-10-17 18:37:49 +02:00
haiyangcui
02139d3d24 header部分加入padding 2020-10-17 18:34:27 +02:00
haiyangcui
d86a10d753 el-table实现EditSites页面 2020-10-17 18:09:17 +02:00
haiyangcui
dc8bdb29dc 解决有更新行高亮的问题 2020-10-17 14:12:24 +02:00
haiyangcui
98b019be5f 更新listpage样式 2020-10-17 13:55:04 +02:00
haiyangcui
e6d1698d62 删除star页面无用格式定义 2020-10-17 13:43:37 +02:00
haiyangcui
6c1e6c511f 删除无用的样式 2020-10-17 12:13:52 +02:00
haiyangcui
1a1393615c 套用listpage样式 2020-10-17 12:08:30 +02:00
cuiocean
5930690144 Merge pull request #292 from buvta/patch-3
el重写Star.vue,用排序替代拖拽
2020-10-17 12:07:09 +02:00
haiyangcui
091493fa77 定义listpage样式 2020-10-17 11:23:53 +02:00
buvta
cd1c4eaffe el重写Star.vue,用排序替代拖拽 2020-10-17 13:03:34 +08:00
cuiocean
1bb217d84f Merge pull request #289 from buvta/patch-4
去掉表格底部横线
2020-10-16 18:02:26 +02:00
buvta
92eac6d2dd 去掉表格底部横线 2020-10-16 23:49:12 +08:00
haiyangcui
b067cfa143 解决History页面自适应问题 2020-10-16 16:16:21 +02:00
haiyangcui
99d21fd7fe 设置不显示table的border,无需响应header-click打开关闭border 2020-10-16 14:46:24 +02:00
Hunlongyu
b167f711d0 🎄 修改历史界面样式 2020-10-16 18:03:20 +08:00
Hunlongyu
7d4ffeed87 🎃 移除 element 全局导入, 修改 star 样式 2020-10-16 18:00:13 +08:00
haiyangcui
7e94ef8025 更新el-table背景色 2020-10-15 22:30:54 +02:00
haiyangcui
1a36bc85b9 更新el-table背景色 2020-10-15 22:21:54 +02:00
haiyangcui
f7ed0e1c29 更新el-button的样式 2020-10-15 21:25:14 +02:00
cuiocean
970a359aba Merge pull request #280 from buvta/forPR1
改写History.vue
2020-10-15 21:15:31 +02:00
haiyangcui
be0441d042 设置不同主题下el-table的css样式 2020-10-15 21:12:42 +02:00
buvta
3fc350e6d6 el改写History.vue 2020-10-16 01:07:08 +08:00
buvta
b26a4d4f27 全局引入elementUI 2020-10-16 01:00:28 +08:00
haiyangcui
454ea48891 格式化Detail.vue 2020-10-14 23:02:02 +02:00
haiyangcui
d564d0928b 播放直播源时VideoTitle显示直播频道的名字 2020-10-13 22:08:40 +02:00
haiyangcui
2562119bad 支持导入源时multiSelections 2020-10-13 21:47:22 +02:00
haiyangcui
1a7aaa8dff 导入源时不删除原有源,但会检查源是否有重复,不添加重复的源 2020-10-13 21:44:24 +02:00
haiyangcui
583a768068 改进函数名 2020-10-12 18:26:27 +02:00
haiyangcui
6216ad96d6 源编辑页面添加清空功能 2020-10-12 18:25:24 +02:00
haiyangcui
766b1d458f IPTV添加置顶功能 2020-10-11 14:46:52 +02:00
haiyangcui
6a0699ec20 添加源置顶功能 2020-10-11 14:46:13 +02:00
haiyangcui
a6fd748e09 统一按钮名称和对话框名称 2020-10-11 13:47:18 +02:00
cuiocean
064ff38650 Merge pull request #271 from buvta/master
使用对话框新增或修改源
2020-10-11 13:39:25 +02:00
buvta
1c74174a3a 使用对话框新增或编辑源
bug已解决
2020-10-11 14:11:30 +08:00
haiyangcui
0625c4945f 支持'极品''喜欢看' 2020-10-11 00:05:49 +02:00
Hunlongyu
e1d0643c68 🍔 电视直播位置移动考上 2020-10-10 17:01:41 +08:00
Hunlongyu
bce10b906c 🍛 移除二维码 2020-10-10 16:54:18 +08:00
haiyangcui
d485a5733e 支持'喜欢看' 2020-10-10 10:15:09 +02:00
haiyangcui
5ab5cee6dc 支持'极品' 2020-10-09 21:06:11 +02:00
haiyangcui
235e894f66 修复IPTV页面高度问题 2020-10-09 17:34:04 +02:00
haiyangcui
ee62ae0c8f Revert "格式化vue文件"
This reverts commit 8b78aafda4.

# Conflicts:
#	src/components/IPTV.vue
2020-10-09 17:29:53 +02:00
haiyangcui
f8b95fe430 v2.5.2-1 2020-10-09 17:23:36 +02:00
haiyangcui
a3fc5dba79 v2.5.2.1 2020-10-09 16:56:09 +02:00
haiyangcui
e1cee12222 加入占位按钮,以免不小心点到重置 2020-10-09 16:43:53 +02:00
haiyangcui
6d2b1720b7 恢复m3u8限制 2020-10-09 16:27:14 +02:00
haiyangcui
1c7024a68a 删除多余空白按钮 2020-10-09 16:21:39 +02:00
haiyangcui
8729184ba9 修复列表主题的问题 2020-10-09 16:16:58 +02:00
haiyangcui
618fdf03d9 移除m3u8的限制 2020-10-09 16:10:20 +02:00
haiyangcui
ac573b0de4 v2.5.2 2020-10-09 14:30:54 +02:00
haiyangcui
6b225d5076 添加605资源 2020-10-09 13:35:15 +02:00
haiyangcui
cb2ce525ae 修复设置更新问题 2020-10-09 13:04:23 +02:00
haiyangcui
8b78aafda4 格式化vue文件 2020-10-08 23:35:22 +02:00
haiyangcui
3a02a5d1cf 统一收藏页面和IPTV页面的样式 2020-10-08 23:19:08 +02:00
haiyangcui
4212cc681a 更新setting数据 2020-10-08 23:01:33 +02:00
haiyangcui
015595eb0a 支持IPTV搜索 2020-10-08 21:00:43 +02:00
haiyangcui
4ea00a9d8f 更新内置频道 2020-10-08 13:24:27 +02:00
haiyangcui
6e19a08186 更多IPTV资源 2020-10-08 12:58:09 +02:00
haiyangcui
940dbe3d17 内置更多频道 2020-10-08 12:57:24 +02:00
haiyangcui
222e89c24d 支持导入m3u8文件 2020-10-08 12:57:06 +02:00
haiyangcui
24af7c3084 支持导出为json文件 2020-10-07 23:13:05 +02:00
haiyangcui
34d981c6a6 支持一次导入多个m3u文件 2020-10-07 23:04:08 +02:00
haiyangcui
2e5f5a8d6d 支持快捷键播放上一频道下一频道 2020-10-07 22:36:54 +02:00
haiyangcui
1565d39ba7 支持点击列表里的频道播放 2020-10-07 22:16:11 +02:00
haiyangcui
24b84e4b12 播放电视直播时,列表为频道列表 2020-10-07 22:10:11 +02:00
haiyangcui
c138f1beb5 Merge branch 'master' into dev 2020-10-07 20:51:16 +02:00
haiyangcui
4589856721 屏蔽主分类设置 2020-10-07 18:20:57 +02:00
haiyangcui
f2fbf96a04 错开重置和搜索 2020-10-07 18:09:04 +02:00
cuiocean
8a0bb9a3f1 Merge pull request #254 from Hunlongyu/dependabot/npm_and_yarn/electron-9.3.1
Bump electron from 9.1.0 to 9.3.1
2020-10-07 16:27:47 +02:00
haiyangcui
8cf2a92673 显示总频道数目 2020-10-07 13:17:22 +02:00
haiyangcui
40c32a9085 导入列表时,合并到当前列表,并删除重复的url项 2020-10-07 13:08:12 +02:00
haiyangcui
7ef5283562 Merge branch 'dev' of https://github.com/Hunlongyu/ZY-Player into dev 2020-10-06 23:34:58 +02:00
haiyangcui
454287ede5 删除添加新频道功能 2020-10-06 23:34:41 +02:00
haiyangcui
77792f0ca4 IPTV支持导出为m3u文件 2020-10-06 21:14:35 +02:00
dependabot[bot]
d793605367 Bump electron from 9.1.0 to 9.3.1
Bumps [electron](https://github.com/electron/electron) from 9.1.0 to 9.3.1.
- [Release notes](https://github.com/electron/electron/releases)
- [Changelog](https://github.com/electron/electron/blob/master/docs/breaking-changes.md)
- [Commits](https://github.com/electron/electron/compare/v9.1.0...v9.3.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-06 18:46:36 +00:00
haiyangcui
0a13bac9e6 不再占用固定端口 2020-10-06 16:59:03 +02:00
haiyangcui
5b54279e9a 修复源导出问题 2020-10-05 16:22:12 +02:00
haiyangcui
e1e115643e 修复某些设置无法保存的问题 2020-10-05 15:12:53 +02:00
haiyangcui
826375c233 更新页面title 2020-10-05 12:32:47 +02:00
haiyangcui
ae33d47186 转移源相关操作到源编辑页面 2020-10-05 12:05:39 +02:00
haiyangcui
a7d07ed964 IPTV添加搜索功能 2020-10-04 23:11:06 +02:00
haiyangcui
95db790529 添加'电视频道_2_高清.m3u' 2020-10-04 22:54:01 +02:00
haiyangcui
2d406c0c24 v2.5.1 2020-10-04 16:59:17 +02:00
haiyangcui
7b39be271f 添加额外在线直播源文件 2020-10-04 16:55:50 +02:00
haiyangcui
d8367414a2 修复无法正确导入直播源的问题 2020-10-04 16:53:11 +02:00
haiyangcui
d647d2ecec v2.5.0 2020-10-04 12:49:21 +02:00
haiyangcui
7f9f847d73 内置腾讯云直播源 2020-10-04 12:29:10 +02:00
haiyangcui
36e0b140cd 解决中文乱码问题 2020-10-04 12:20:24 +02:00
haiyangcui
99948770ff 读取m3u文件 2020-10-04 11:08:21 +02:00
haiyangcui
5300d777ce 移除无用链接 2020-10-04 10:30:49 +02:00
haiyangcui
64da42524d 添加赞赏码 2020-10-04 10:30:29 +02:00
haiyangcui
1ebdfee7bc 支持播放器内播放直播 2020-10-03 23:17:19 +02:00
haiyangcui
17ba319157 添加"导入" "导出" "重置" 2020-10-01 23:33:24 +02:00
haiyangcui
27bdc3559d 添加新频道页面 2020-10-01 23:33:21 +02:00
haiyangcui
ca53a22598 添加删除功能 2020-10-01 23:33:18 +02:00
haiyangcui
6632318cf6 添加简单的IPTV页面 2020-10-01 23:33:15 +02:00
haiyangcui
cb7a4af7ae 2.4.10.1 国庆版 2020-10-01 13:34:21 +02:00
haiyangcui
25340b79aa v2.4.9 2020-09-30 21:33:08 +02:00
haiyangcui
381b0a8735 记录窗口大小及位置 2020-09-30 21:11:54 +02:00
haiyangcui
c7b99244bb 更新style 2020-09-29 23:08:23 +02:00
haiyangcui
5b5826e9a6 改进checkbox的点击效果 2020-09-29 17:43:14 +02:00
haiyangcui
03e2f2673b 更新style 2020-09-29 17:37:47 +02:00
haiyangcui
503a90d8da 转移收藏相关操作到收藏页面 2020-09-29 15:23:09 +02:00
haiyangcui
afb92d59ff 可设置快进快退的步长 2020-09-28 23:30:24 +02:00
haiyangcui
d26f1cbdf7 简影 2020-09-28 21:11:48 +02:00
haiyangcui
7f821b05ad 哆咪动漫 2020-09-28 20:53:48 +02:00
haiyangcui
746c93c9d2 樱花动漫 2020-09-28 20:53:15 +02:00
haiyangcui
9fb51ed8fc 点击'播放在线高清视频'也可以控制check box的开关 2020-09-28 17:51:56 +02:00
haiyangcui
6a1c045e0b 解析网站的代码放到onlineVideo里 2020-09-28 16:38:31 +02:00
haiyangcui
756b8ecc33 添加"素白白"的支持 2020-09-27 17:59:13 +02:00
haiyangcui
b4946a6c99 比较在线搜索结果时,忽略空格 2020-09-27 15:11:56 +02:00
haiyangcui
cbde4180ab 2.4.8 2020-09-27 15:02:24 +02:00
haiyangcui
00dab782e8 搜索的时候设置timeout,解决全局搜索结果无法打开的问题 2020-09-27 14:55:56 +02:00
haiyangcui
89d6183841 支持播放在线高清视频 2020-09-27 13:44:38 +02:00
haiyangcui
efd2095261 v2.4.7 2020-09-18 19:09:51 +02:00
haiyangcui
cbedb859c3 电影列表页面屏蔽福利片 2020-09-17 16:08:12 +02:00
haiyangcui
65aedc84cf 有最新版本时,在设置页面有提示 2020-09-16 22:17:04 +02:00
haiyangcui
95c58095ee 屏蔽福利片选项 2020-09-16 20:00:22 +02:00
haiyangcui
b5da3c7f81 屏蔽主分类 2020-09-13 15:05:54 +02:00
haiyangcui
5b0211b2ed 如果编辑源页面没有打开,无需更新 2020-09-13 14:51:22 +02:00
haiyangcui
0bb6409687 只有EditSites的资源列表变化时才更新Film页面 2020-09-13 08:19:57 +02:00
haiyangcui
7078e05668 修复编辑第三方播放器地址的bug 2020-09-12 22:35:54 +02:00
haiyangcui
0172a204b1 2.4.6 2020-09-12 08:28:30 +02:00
haiyangcui
c6b0781a02 添加源后清空输入框 2020-09-11 17:33:53 +02:00
haiyangcui
b3e67bcc7d Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player 2020-09-10 23:53:51 +02:00
haiyangcui
cbca6db97e 改进EditSites页面 2020-09-10 21:20:30 +02:00
haiyangcui
814ecaf25b 添加时检查name和api不能为空 2020-09-10 21:14:32 +02:00
haiyangcui
4a07520336 源更新时更新Film页面的源列表 2020-09-10 21:13:42 +02:00
haiyangcui
2e121a901c ChangeView的时候关闭EditSites页面 2020-09-10 20:59:28 +02:00
haiyangcui
3a2a16a168 增加"添加新源"页面 2020-09-10 17:59:36 +02:00
Hunlongyu
881ab6cfa5 更换蓝奏云链接 2020-09-10 23:14:35 +08:00
haiyangcui
3151b33a23 支持源页面可拖曳 2020-09-09 17:34:23 +02:00
haiyangcui
f154f44772 添加编辑源页面 2020-09-09 17:12:18 +02:00
haiyangcui
a1458cf8bf 收藏页面添加观看至第几集的信息 2020-09-07 23:37:11 +02:00
haiyangcui
595136c799 支持收藏列表的拖曳排序 2020-09-07 20:48:33 +02:00
haiyangcui
b7e497e2d9 历史记录和收藏页面,添加表头 2020-09-07 13:35:04 +02:00
haiyangcui
dce8ad2ef2 支持直接编辑第三方播放器路径 2020-09-07 12:16:28 +02:00
haiyangcui
79ba45b63a 新播放的历史记录置顶 2020-09-05 23:39:16 +02:00
haiyangcui
b6fcbcb934 Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player 2020-09-04 22:08:47 +02:00
haiyangcui
54c4409311 同步的时候不清除有更新标记 2020-09-02 23:05:40 +02:00
Hunlongyu
5e9c273048 更新详情截图 2020-09-02 19:57:49 +08:00
Hunlongyu
197df4e830 Update README.md 2020-09-02 19:44:39 +08:00
Hunlongyu
5271dfa490 Update README.md 2020-09-02 19:43:05 +08:00
Hunlongyu
7efde45aed Update README.md 2020-09-02 19:42:39 +08:00
Hunlongyu
4c92918dc3 Update README.md 2020-09-02 19:28:34 +08:00
haiyangcui
6c0bd5125b 美化精简模式的按钮 2020-09-02 13:16:39 +02:00
haiyangcui
785f9b20e7 用m3u文件替代dpl文件 2020-09-01 23:03:24 +02:00
haiyangcui
8d052d2904 无搜索结果时,不需要提醒 2020-09-01 21:57:28 +02:00
haiyangcui
69a397e24e Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player 2020-08-30 13:48:01 +02:00
haiyangcui
c216352268 改进详情页面宽度 2020-08-30 13:47:39 +02:00
haiyangcui
89448d390f Install cheerio 2020-08-30 13:32:07 +02:00
haiyangcui
a853b02aa0 v2.4.5 2020-08-30 13:23:00 +02:00
haiyangcui
0443ce248f 重置源放最后 2020-08-30 13:03:51 +02:00
haiyangcui
8009c3197e 比较头两个搜索结果 2020-08-30 12:09:23 +02:00
haiyangcui
978d4e7181 2.4.5 2020-08-30 11:35:20 +02:00
haiyangcui
138b70263a 添加豆瓣评分 2020-08-30 11:34:22 +02:00
haiyangcui
7f48c91f97 如果没有选择本地播放器,选择在线播放 2020-08-30 10:49:08 +02:00
haiyangcui
7a494a54c0 详情页添加"豆瓣" 2020-08-30 10:28:57 +02:00
haiyangcui
97812af0fd v2.4.4 2020-08-28 15:00:56 +02:00
haiyangcui
490d7c963e 支持导入所有剧集到PotPlayer 2020-08-28 14:53:09 +02:00
haiyangcui
ed1afa2026 添加“重置源”功能 2020-08-28 12:58:16 +02:00
haiyangcui
7ef114d0e3 Change View的时候关闭Detail 2020-08-28 12:43:09 +02:00
haiyangcui
7f9b7fc2c8 Detail页面左边留出60px,侧边栏的宽度 2020-08-28 12:40:26 +02:00
haiyangcui
511820f873 修复历史记录里的下载功能 2020-08-27 17:01:22 +02:00
haiyangcui
af6dcb11bf 修复剧集的分享功能 2020-08-27 16:53:46 +02:00
haiyangcui
7ecad1ad8e 同步历史和收藏的operate buttons 2020-08-27 16:45:29 +02:00
haiyangcui
4d169f9d51 删除无用代码 2020-08-27 16:36:04 +02:00
haiyangcui
f3862e8385 格式化快捷键数据 2020-08-27 16:20:03 +02:00
haiyangcui
490d4839b7 没有更新的收藏跳过clearHasUpdateFlag 2020-08-27 16:06:46 +02:00
haiyangcui
033bcb3df7 修复下载功能 2020-08-27 15:52:56 +02:00
haiyangcui
df22efa980 导入收藏时不清空 2020-08-27 15:26:47 +02:00
haiyangcui
5428891297 删除多余信息 2020-08-27 15:14:03 +02:00
haiyangcui
bb3502774b 同步时更新收藏信息 2020-08-27 15:05:57 +02:00
haiyangcui
fa67ad03d2 恢复播放页面的收藏逻辑 2020-08-27 15:03:28 +02:00
haiyangcui
8a196ae52a 解决收藏项无法直接播放的bug 2020-08-27 14:48:11 +02:00
haiyangcui
ebfb681205 导出时先更新数据 2020-08-27 14:32:29 +02:00
haiyangcui
ba9f3246d2 Fix typo bug 2020-08-27 14:25:22 +02:00
haiyangcui
51cb181acd 改进播放页面的收藏功能 2020-08-27 13:58:05 +02:00
haiyangcui
33537638b0 更新version到2.4.3 2020-08-27 13:39:50 +02:00
haiyangcui
fa9f85a177 使用star.key 2020-08-27 13:33:21 +02:00
haiyangcui
3e1ecaac74 Fix bug in checkStar 2020-08-27 13:24:55 +02:00
haiyangcui
5cc9849e8a 导入收藏时升级数据格式 2020-08-27 13:13:45 +02:00
haiyangcui
e353b629c5 添加"更新收藏" 2020-08-27 13:08:41 +02:00
haiyangcui
4d20d5bc68 No need to record site info in star 2020-08-27 13:08:22 +02:00
haiyangcui
a921ce7adf 添加“清空所有收藏” 2020-08-27 12:39:54 +02:00
haiyangcui
1dd8d0dd24 在视图和列表里添加备注 2020-08-26 18:15:02 +02:00
haiyangcui
b90c359670 Reverse the list return by zy.list, to get video list from new to old 2020-08-26 16:24:57 +02:00
haiyangcui
27eb8c06ff 添加“最新”到class列表 2020-08-26 11:42:15 +02:00
haiyangcui
add2bedb61 v2.4.2 2020-08-25 16:59:59 +02:00
haiyangcui
3dc970e198 更新已存在的收藏 2020-08-25 15:54:07 +02:00
haiyangcui
3f2def4455 添加第三方播放器路径设置 2020-08-25 14:38:46 +02:00
haiyangcui
5b8d883af4 Format JSON string 2020-08-25 13:48:33 +02:00
haiyangcui
7113567475 可以使用PotPlayer打开视频 2020-08-25 00:31:34 +02:00
haiyangcui
e30da35e72 Import sites from file 2020-08-24 13:10:30 +02:00
haiyangcui
55b7396a2e Export sites to file 2020-08-24 12:54:31 +02:00
haiyangcui
83568fa499 No need to copy to clipboard 2020-08-24 12:32:51 +02:00
haiyangcui
838d3a64cd v2.4.1 2020-08-23 17:48:10 +02:00
haiyangcui
506be03e3e 从文件中导入收藏 2020-08-23 17:45:19 +02:00
haiyangcui
cfdb561473 加入取消操作识别 2020-08-23 15:03:47 +02:00
haiyangcui
ab2f45189f 导出收藏到文件 2020-08-23 14:33:59 +02:00
haiyangcui
f4b9a73b18 Simple favorites export import 2020-08-22 17:55:10 +02:00
haiyangcui
6f99d789f4 2.4.0 2020-08-22 16:08:38 +02:00
haiyangcui
e71090dad2 Wrap the items in Settings theme-box 2020-08-22 15:54:39 +02:00
haiyangcui
afe3351837 Add left margin to name 2020-08-22 15:35:28 +02:00
haiyangcui
5dc0613aeb 列表自适应 2020-08-22 15:06:10 +02:00
haiyangcui
1c6385ae6c 使用v-show显示隐藏class element,这样可以保持其占位 2020-08-22 10:58:47 +02:00
haiyangcui
88a95a8bfb 保存搜索选项设置 2020-08-22 00:20:18 +02:00
haiyangcui
951e6ffa37 更好的修复bug#183 2020-08-21 23:49:00 +02:00
haiyangcui
b83aed0a97 解决bug #183 2020-08-21 23:36:17 +02:00
haiyangcui
67ce537039 Add search style 2020-08-21 23:00:21 +02:00
haiyangcui
975562a66b Fix a bug in Detail.vue 2020-08-19 23:31:20 +02:00
haiyangcui
8e7015c9d6 调整"搜索所有资源"位置 2020-08-19 23:09:42 +02:00
haiyangcui
b841552dc7 转移"搜索所有资源"到设置页面 2020-08-19 18:07:37 +02:00
haiyangcui
0a9b939dc3 v2.3.8 2020-08-19 11:36:08 +02:00
haiyangcui
14ff252cce 定义--highlight-color 2020-08-19 08:30:18 +02:00
haiyangcui
afd016be93 取消“搜索所有资源”的边框 2020-08-18 23:00:05 +02:00
haiyangcui
9cd7f7d267 高亮有更新的收藏项 2020-08-18 22:51:03 +02:00
haiyangcui
8a76ec4e87 Null check on site 2020-08-18 17:39:39 +02:00
haiyangcui
a00d965ce9 v2.3.7 2020-08-18 16:00:05 +02:00
Hunlongyu
c9eb0c3e22 Merge pull request #178 from cuiocean/master
添加搜索所有资源功能
2020-08-18 16:13:08 +08:00
haiyangcui
c80c0bd948 Video中添加site信息 2020-08-16 23:02:18 +02:00
haiyangcui
65dcfa04ae 在star中添加key信息 2020-08-16 22:58:12 +02:00
haiyangcui
4e4ab82ea2 添加site信息在Detail里 2020-08-16 22:30:54 +02:00
haiyangcui
dd2adf4f99 更新格式 2020-08-15 16:44:43 +02:00
haiyangcui
777fbde528 在历史界面显示资源网站名,而不是资源标识 2020-08-15 16:30:09 +02:00
haiyangcui
472898f978 Fix downloadEvent 2020-08-15 12:27:44 +02:00
haiyangcui
7f41d415f1 删除searchSingleSiteEvent 2020-08-15 12:18:40 +02:00
haiyangcui
5d37a36c21 添加简单的style 2020-08-15 11:23:19 +02:00
haiyangcui
3a499766af playEvent starEvent shareEvent downloadEvent all take site as the input argument 2020-08-15 10:56:48 +02:00
haiyangcui
cea797b6d0 Save whole site data to res.site 2020-08-14 21:55:41 +02:00
haiyangcui
37b41b0e20 无搜索结果时,提示资源网站名字 2020-08-14 19:41:00 +02:00
haiyangcui
1105c46f08 添加“搜索所有资源”checkbox 2020-08-14 19:29:39 +02:00
haiyangcui
1df7b41edd 搜索结果显示资源网名字 2020-08-13 22:04:50 +02:00
haiyangcui
f76c71c950 Merge searchClickEvent and searchEvent 2020-08-13 21:46:23 +02:00
Hunlongyu
cd77384bd9 😄 v2.3.6 😆 2020-08-12 15:47:33 +08:00
Hunlongyu
64adc9d6c1 Merge pull request #170 from cuiocean/master
添加"备注"到搜索结果
2020-08-12 15:46:16 +08:00
haiyangcui
e9095e50a6 添加"备注"到搜索结果 2020-08-06 08:51:39 +02:00
Hunlongyu
acfa742b4f 👮‍♂️ v2.3.5 👨‍🚀 2020-08-06 10:15:34 +08:00
Hunlongyu
a79c48cba0 👨‍🚒👩‍🚒 v2.3.4 👨‍🚀👩‍🚀 2020-08-06 10:13:51 +08:00
Hunlongyu
904ef5ccea modify css 2020-08-06 09:58:39 +08:00
Hunlongyu
3db281c87f Merge pull request #168 from cuiocean/master
添加"备注"列到收藏试图
2020-08-06 09:57:29 +08:00
haiyangcui
076e6e99e4 当有更新时,刷新list列表 2020-08-05 17:06:17 +02:00
haiyangcui
32f6ac0310 添加"备注"列到收藏试图 2020-08-05 16:39:46 +02:00
haiyangcui
b8706ea432 添加播放视频点击事件到历史记录里的片名 2020-08-05 16:27:11 +02:00
haiyangcui
509d6c7900 添加"备注"列到收藏试图 2020-08-05 16:25:45 +02:00
Hunlongyu
51454d828c 🐱💻 v2.3.3 🐱🐉 2020-08-05 11:37:37 +08:00
Hunlongyu
59449886f5 🐱👤 新增一键同步所有收藏, 优化样式 🐱‍🏍 2020-08-05 11:35:39 +08:00
Hunlongyu
601e9895cc Merge pull request #166 from cuiocean/master
添加"同步所有收藏"按钮
2020-08-05 11:03:21 +08:00
haiyangcui
1ba8b46990 Fix typo in the function name 2020-08-04 19:06:17 +02:00
haiyangcui
7ed34caa56 Add UpdateAll button 2020-08-04 17:53:07 +02:00
Hunlongyu
fc40521420 🐱💻🐱🐉 发版 2.2.0 🐱👓🐱🚀 2020-08-04 10:17:19 +08:00
Hunlongyu
cfdd836e01 showHistory change to history 2020-08-04 10:14:11 +08:00
Hunlongyu
083e00ddbf Merge pull request #163 from cuiocean/master
添加“历史记录”到侧边栏
2020-08-04 10:10:07 +08:00
Hunlongyu
c41c7c4857 ✌ 修改为字符串 👌 2020-08-04 10:09:22 +08:00
Hunlongyu
4bde51dc38 Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player 2020-08-04 10:03:38 +08:00
Hunlongyu
38c7540145 删除 console 2020-08-04 10:03:33 +08:00
Hunlongyu
a44579d4a1 Merge pull request #160 from hectorqin/master
修复m3u8链接获取问题,修复跨域问题
2020-08-04 10:00:10 +08:00
Hunlongyu
7f2d6f12c0 删除备注, 以及console 2020-08-04 09:51:48 +08:00
haiyangcui
daf1c4ddb6 Add ShowHistory to Aside 2020-08-03 21:13:50 +02:00
hectorqin
c1372c5589 新增复制调试信息功能和上次播放提示 2020-08-02 11:57:36 +08:00
hectorqin
c623533271 修复m3u8链接获取问题,修复跨域问题 2020-08-01 22:04:14 +08:00
Hunlongyu
069e7e16d6 ✌ 大佬优化了播放器 🤞 2020-07-29 10:31:55 +08:00
Hunlongyu
cabe4240f4 Merge pull request #150 from hectorqin/master
完善播放器功能,完善右上角窗口管理icon
2020-07-29 10:27:57 +08:00
hectorqin
5448e86109 更新播放库 2020-07-29 09:54:45 +08:00
hectorqin
536f6dad7d 新增导出播放列表功能,修复mini同步进度,优化mini视频加载 2020-07-28 22:53:54 +08:00
hectorqin
bf2796779f 优化播放器 2020-07-28 21:18:21 +08:00
hectorqin
3a29147fd6 完善右上角按钮,完善播放器标题 2020-07-28 17:33:45 +08:00
hectorqin
e987ecc446 完善播放器功能 2020-07-28 10:21:14 +08:00
Hunlongyu
9aee6d8527 Merge pull request #143 from godvmxi/master
add yarn guide for dev and build
2020-07-24 20:39:35 +08:00
Bright Jiang
4d438fcdd3 add yarn usage guide for dev and build 2020-07-24 15:23:34 +08:00
hunlongyu
36e40f4778 🚀 x86 🚁 2020-07-22 10:51:38 +08:00
hunlongyu
422def0702 🎨🖼 x86 打包 🎭🎪 2020-07-22 09:44:25 +08:00
hunlongyu
fc52d79d88 🎉 V2.0.0 正式版发布 🎇🎊 2020-07-22 09:38:26 +08:00
dandan
cc09d0aca0 Merge pull request #1 from Hunlongyu/master
merge to latest
2020-07-17 14:36:52 +08:00
hunlongyu
b514f1c04e v1.2.6 2020-07-16 00:03:34 +08:00
hunlongyu
189e67eb22 🦺 1.2.5 🥼 2020-07-15 23:55:34 +08:00
hunlongyu
e5c3adf1c5 🎍 1.2.4 🎋 2020-07-15 23:53:53 +08:00
hunlongyu
299367f0b8 修复收藏夹播放多集视频的BUG 🎉 2020-07-15 23:51:27 +08:00
hunlongyu
0d67474459 🎟 版本号 🎫 2020-07-15 17:38:21 +08:00
hunlongyu
15a188aa85 🎍 优化 MINI 模式 🎋 2020-07-15 17:38:00 +08:00
hunlongyu
0555badcfa 🍚 修复列表模式下, 下载BUG 🍜 2020-07-14 16:35:51 +08:00
hunlongyu
6f8f700dfc 🍟 修复BUG 🌭 2020-07-14 15:26:01 +08:00
hunlongyu
001772d75c 🎉 优化搜索 🎊 2020-07-14 00:17:26 +08:00
hunlongyu
a2d2215646 🎆 修复详情页无法播放的BUG 🎇 2020-07-14 00:16:55 +08:00
hunlongyu
053853f036 🍖 首页新增文档入口 🍗 2020-07-13 17:58:39 +08:00
hunlongyu
d4ea77b961 modify base 2020-07-13 17:52:59 +08:00
hunlongyu
1cd91aada2 🌮 切换端口号, 添加文档 🥪 2020-07-13 17:49:45 +08:00
hunlongyu
f3aa8c1f51 🥗 新增多个下载入口 🥙 2020-07-13 15:25:47 +08:00
hunlongyu
ce73a9a095 🎋 优化搜索 🎄 2020-07-12 02:44:32 +08:00
hunlongyu
504fc7fc47 🧶 版本号升级 2020-07-11 00:34:37 +08:00
hunlongyu
ac56980317 🎗 修复无法软件重置 bug 🎨 2020-07-11 00:32:50 +08:00
hunlongyu
c1043d9197 🎭 修复窗口尺寸 🦺 2020-07-11 00:14:51 +08:00
hunlongyu
8902282fe2 🎉 新版本内测 🎊🎏 2020-07-10 23:24:28 +08:00
Hunlongyu
e0ae32027a Merge pull request #116 from jingsong-liu/patch-1
fix typo
2020-06-25 17:05:09 +08:00
Song
f5ffca0c52 fix typo 2020-06-24 20:11:30 +08:00
Hunlongyu
a95f915328 Merge pull request #114 from godvmxi/master
Fix build command
2020-06-24 16:19:34 +08:00
Bright Jiang
1badcea9f3 Fix build command 2020-06-24 16:16:45 +08:00
Hunlongyu
a448825ed2 Merge pull request #113 from godvmxi/master
add toc and develop guild
2020-06-24 16:01:52 +08:00
Bright Jiang
708b6bbd3a add toc and develop guild 2020-06-24 15:56:22 +08:00
Hunlongyu
7ded9a8485 Update README.md 2020-06-24 14:16:52 +08:00
Hunlongyu
57d60e9400 感谢异次元软件世界的推广
🥰😘😍
2020-06-22 23:33:10 +08:00
Hunlongyu
e01254c1c4 Update README.md 2020-06-22 23:10:42 +08:00
92 changed files with 40958 additions and 4175 deletions

View File

@@ -1,26 +0,0 @@
name: release-build
on:
push:
branches: [ master ]
jobs:
release:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-latest, macos-latest, ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 12
- run: |
yarn
yarn release
shell: pwsh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -3,7 +3,7 @@ name: release-build
on:
push:
tags:
- x86 *
- x86-v*
jobs:
release:

1
.gitignore vendored
View File

@@ -10,6 +10,7 @@ node_modules
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea

121
README.md
View File

@@ -22,83 +22,66 @@
<p>
## ZY Player 资源播放器
1. 全平台支持. Windows, Mac, Linux
2. 12个视频源. 未来更新更多的视频源
3. 新增历史播放记录, 并记录播放进度
4. 新增分享功能. 一键分享海报图片
5. 新增精简模式. 支持修改透明度
6. 收藏夹同步更新视频追剧
7. 支持演员名称搜索
8. 更详细的视频分类
9. 后台自动更新
10. 全新布局配色
11. 新增多语言
12. 全局快捷键
13. 下载功能
14. ...
觉得软件不错的, 点击右上角 star 收藏关注一波呀~
> Tips: 资源加载不出来时, 点击列表下方链接, 浏览器打开一下网站. 原理是需要通过网站的人机检测.
<!-- ### 全新版本,从心出发
新版本开发计划已写好, 由于功能很多,且还有其他平台, 个人精力终归有限, 所以招募小伙伴, 一起完成这个项目.
主要招募: 移动端(IOS, Android), 以及TV端(Android)
我会提供接口, 接口文档, 桌面端与移动端交互说明
欢迎各路大神参与开发维护项目. 也欢迎吃瓜群众入群尝鲜测试, 提出建议.
微信群:
<p>
<img width="256" src="https://i.loli.net/2020/06/17/uhYeHUVOrkB8fxL.jpg" >
</p> -->
<h1 align="center">ZY Player 资源播放器</h1>
#### 全局快捷键:
| 快捷键 | 说明 | 主界面 | 小窗口 |
| :----------------------: | ---------- | :----: | :----: |
| `⌘ + →``Ctrl + →` | 下一集 | √ | √ |
| `⌘ + ←``Ctrl + ←` | 上一集 | √ | √ |
| `⌘ + ↑``Ctrl + ↑` | 减少透明度 | | √ |
| `⌘ + ↓``Ctrl + ↓` | 增加透明度 | | √ |
| `Shift + ↑` | 增加倍速 + 0.25 | √ | √ |
| `Shift + ↓` | 减少倍速 - 0.25 | √ | √ |
### ✨特性
#### 下载:
- 🍕 全平台支持. Windows, Mac, Linux
- 🍥 支持 IPTV, 卫视直播
- 🍔 视频源支持自定义, 支持导入, 导出
- 🍟 支持海报模式和列表模式浏览资源
- 🌭 播放历史, 自动跳转历史进度
- 🍿 收藏夹支持导入,导出, 支持同步追剧
- 🥙 支持精简模式, 摸鱼划水
- 🥪 一键搜索所有资源, 支持历史搜索记录
- 🌮 导出资源下载链接
- 🍣 支持第三方播放器播放
- 🍤 显示豆瓣评分
1. [Github -- 官方下载(最新版)](https://github.com/Hunlongyu/ZY-Player/releases)
### 🌴 下载
2. [蓝奏云 -- 快速下载(老版本)](https://www.lanzous.com/b04s6a3re) 密码:95px
- 🍓 [Github -- 官方下载](https://github.com/Hunlongyu/ZY-Player/releases)
- 🍉 [蓝奏云 -- 快速下载](https://www.lanzoux.com/b04s6a3re) 密码:95px
- 🍒 适用于32位操作系统的x86软件,在蓝奏云网盘里, 后缀名: ZY Player * 32位.exe
3. 适用于32位操作系统的x86软件,在蓝奏云网盘里, 后缀名: ZY Player * 32位.exe
### 🚀 快捷键
#### 截图:
播放窗口 和 Mini窗口
0. 分享 ⇣ ↓
![share.gif](https://i.loli.net/2020/06/05/hbJwBXlx194umcO.gif)
| 快捷键 | 说明 | 快捷键 | 说明 |
| :-----------: | ---------------------------- | :-------: | ----------------- |
| `Alt + Space` | 聚焦或取消聚焦(全局快捷键) | | |
| `→` | 快进 5 秒 | `←` | 快退 5 秒 |
| `↑` | 音量调高 | `↓` | 音量调低 |
| `m` | 静音 | `t` | 置顶或退出置顶 |
| `f` | 进入或退出全屏 | `esc` | 退出全屏 |
| `Alt + →` | 下一集 | `Alt + ←` | 上一集 |
| `Alt + ↑` | 透明度调高 | `Alt + ↓` | 透明度调低 |
| `home` | 跳到视频开始位置 | `end` | 跳到视频结束位置 |
| `pgUp` | 播放倍速加快 0.25 | `pgDown` | 播放倍速减慢 0.25 |
| `Alt + m` | 进入或退出 Mini 模式 | `space` | 播放或暂停 |
1. 浏览 ⇣ ↓
![01浏览.png](https://i.loli.net/2020/05/18/MshDLnXq2CTpoBy.png)
2. 搜索 ⇣ ↓
![02搜索.png](https://i.loli.net/2020/05/20/QgJqDkcjpeiRvBb.png)
3. 详情 ⇣ ↓
![03详情.png](https://i.loli.net/2020/05/18/s7gUj6unEfyYb4Z.png)
4. 播放 ⇣ ↓
![04播放.png](https://i.loli.net/2020/05/18/WqgnOw3mHd6e5uU.png)
5. 收藏 ⇣ ↓
![05收藏.png](https://i.loli.net/2020/05/18/bhIgeGMTPWmrdYi.png)
6. 白色主题皮肤 ⇣ ↓
![06白色.png](https://i.loli.net/2020/05/18/UgiVZ89dhkuxDBI.png)
7. 绿色主题皮肤 ⇣ ↓
![07绿色.png](https://i.loli.net/2020/05/18/4d2UnFRECm7vyJQ.png)
8. 粉色色主题皮肤 ⇣ ↓
![08粉色.png](https://i.loli.net/2020/05/18/PLlEfzd8mSC9vMW.png)
### 🎨 截图
### 重要:
所有资源来自网上, 该软件不参与任何制作, 上传, 储存, 下载等内容. 该软件仅供学习参考, 请于安装后24小时内删除.
| 🥼 浏览 (海报模式) | 🧥 浏览 (列表模式) |
| :----------------------------------------------------------: | :----------------------------------------------------------: |
| ![海报.png](https://i.loli.net/2020/09/02/ZAfGjcqLxoslpWQ.png) | ![列表.png](https://i.loli.net/2020/09/02/jrEkX3yiOGPFazs.png) |
| 👔 搜索 | 👕 详情 |
| ![搜索.png](https://i.loli.net/2020/09/02/HdMos8gent4kTmW.png) | ![详情.png](https://i.loli.net/2020/09/02/S2Np4GAmBz8Rj6P.png) |
| 👖 播放 (普通模式) | 🩳 播放 (精简模式) |
| ![播放.png](https://i.loli.net/2020/09/02/RLBoaZyuS2DCkJ3.png) | ![精简.png](https://i.loli.net/2020/09/02/f21SNdiVFHmeh6b.png) |
| 🧣 历史记录 | 🧤 收藏夹 |
| ![历史.png](https://i.loli.net/2020/09/02/ZhNXatyJi9Dvr3d.png) | ![收藏.png](https://i.loli.net/2020/09/02/wy4H76m2sQ8YdKi.png) |
| 👗 白色主题 | 🥻 黑色主题 |
| ![白色.png](https://i.loli.net/2020/09/02/gslBIYvTaSZRwfU.png) | ![黑色.png](https://i.loli.net/2020/09/02/dMmETUq1ACuGsI6.png) |
| 👘 绿色主题 | 👚 粉色主题 |
| ![绿色.png](https://i.loli.net/2020/09/02/nxJF71b3qusUclZ.png) | ![粉色.png](https://i.loli.net/2020/09/02/8rGL45p6kSqRCOz.png) |
### 🍭 开发者
| [Hunlongyu](https://github.com/Hunlongyu) | [cuiocean](https://github.com/cuiocean) |
| :----------------------------------------------------------: | :----------------------------------------------------------: |
| <img width="120" src="https://avatars2.githubusercontent.com/u/15273630?s=460&u=48cf3299e2a842c0252233d8be42ef4c5d792138&v=4"/> | <img width="120" src="https://avatars0.githubusercontent.com/u/5760235?s=460&u=9d969dd8d83f069ce7ebd60516770c93ac07a330&v=4" /> |
| 💻 🎨 🐛 | 💻 🐛 |

19
docs/doc/404.html Normal file
View File

@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>ZY PLAYER</title>
<meta name="generator" content="VuePress 1.5.2">
<meta name="description" content="ZY PLAYER 文档">
<link rel="preload" href="/doc/assets/css/0.styles.7cdd3ee2.css" as="style"><link rel="preload" href="/doc/assets/js/app.441507e8.js" as="script"><link rel="preload" href="/doc/assets/js/4.023f7c55.js" as="script"><link rel="prefetch" href="/doc/assets/js/2.b7bb5685.js"><link rel="prefetch" href="/doc/assets/js/3.0958b336.js"><link rel="prefetch" href="/doc/assets/js/5.445cad31.js"><link rel="prefetch" href="/doc/assets/js/6.32cb0422.js"><link rel="prefetch" href="/doc/assets/js/7.e50f21bc.js"><link rel="prefetch" href="/doc/assets/js/8.d2479dad.js">
<link rel="stylesheet" href="/doc/assets/css/0.styles.7cdd3ee2.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><div class="theme-default-content"><h1>404</h1> <blockquote>Looks like we've got some broken links.</blockquote> <a href="/doc/" class="router-link-active">
Take me home.
</a></div></div><div class="global-ui"></div></div>
<script src="/doc/assets/js/app.441507e8.js" defer></script><script src="/doc/assets/js/4.023f7c55.js" defer></script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13"><g stroke-width="2" stroke="#aaa" fill="none"><path d="M11.29 11.71l-4-4"/><circle cx="5" cy="5" r="4"/></g></svg>

After

Width:  |  Height:  |  Size: 216 B

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[3],{317:function(t,e,n){},348:function(t,e,n){"use strict";var i=n(317);n.n(i).a},355:function(t,e,n){"use strict";n.r(e);var i={functional:!0,props:{type:{type:String,default:"tip"},text:String,vertical:{type:String,default:"top"}},render:function(t,e){var n=e.props,i=e.slots;return t("span",{class:["badge",n.type],style:{verticalAlign:n.vertical}},n.text||i().default)}},r=(n(348),n(42)),a=Object(r.a)(i,void 0,void 0,!1,null,"50e657c5",null);e.default=a.exports}}]);

View File

@@ -0,0 +1 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[3],{317:function(t,e,n){},348:function(t,e,n){"use strict";var i=n(317);n.n(i).a},356:function(t,e,n){"use strict";n.r(e);var i={functional:!0,props:{type:{type:String,default:"tip"},text:String,vertical:{type:String,default:"top"}},render:function(t,e){var n=e.props,i=e.slots;return t("span",{class:["badge",n.type],style:{verticalAlign:n.vertical}},n.text||i().default)}},r=(n(348),n(42)),a=Object(r.a)(i,void 0,void 0,!1,null,"50e657c5",null);e.default=a.exports}}]);

View File

@@ -0,0 +1 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[4],{350:function(t,e,s){"use strict";s.r(e);var n=["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."],o={methods:{getMsg:function(){return n[Math.floor(Math.random()*n.length)]}}},i=s(42),h=Object(i.a)(o,(function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"theme-container"},[e("div",{staticClass:"theme-default-content"},[e("h1",[this._v("404")]),this._v(" "),e("blockquote",[this._v(this._s(this.getMsg()))]),this._v(" "),e("RouterLink",{attrs:{to:"/"}},[this._v("\n Take me home.\n ")])],1)])}),[],!1,null,null,null);e.default=h.exports}}]);

View File

@@ -0,0 +1 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[5],{351:function(t,e,n){"use strict";n.r(e);var s=n(42),l=Object(s.a)({},(function(){var t=this.$createElement;return(this._self._c||t)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);e.default=l.exports}}]);

View File

@@ -0,0 +1 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[5],{354:function(t,e,n){"use strict";n.r(e);var s=n(42),l=Object(s.a)({},(function(){var t=this.$createElement;return(this._self._c||t)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);e.default=l.exports}}]);

View File

@@ -0,0 +1 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[6],{352:function(t,s,e){"use strict";e.r(s);var n=e(42),r=Object(n.a)({},(function(){var t=this.$createElement,s=this._self._c||t;return s("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[s("h2",{attrs:{id:"常见问题"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#常见问题"}},[this._v("#")]),this._v(" 常见问题")]),this._v(" "),s("ol",[s("li")])])}),[],!1,null,null,null);s.default=r.exports}}]);

View File

@@ -0,0 +1 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[6],{351:function(t,e,n){"use strict";n.r(e);var s=n(42),l=Object(s.a)({},(function(){var t=this.$createElement;return(this._self._c||t)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);e.default=l.exports}}]);

View File

@@ -0,0 +1 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[7],{353:function(t,s,e){"use strict";e.r(s);var n=e(42),r=Object(n.a)({},(function(){var t=this.$createElement,s=this._self._c||t;return s("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[s("h2",{attrs:{id:"常见问题"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#常见问题"}},[this._v("#")]),this._v(" 常见问题")]),this._v(" "),s("ol",[s("li")])])}),[],!1,null,null,null);s.default=r.exports}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

41
docs/doc/index.html Normal file
View File

@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>ZY PLAYER</title>
<meta name="generator" content="VuePress 1.5.2">
<meta name="description" content="ZY PLAYER 文档">
<link rel="preload" href="/doc/assets/css/0.styles.7cdd3ee2.css" as="style"><link rel="preload" href="/doc/assets/js/app.441507e8.js" as="script"><link rel="preload" href="/doc/assets/js/2.b7bb5685.js" as="script"><link rel="preload" href="/doc/assets/js/5.445cad31.js" as="script"><link rel="prefetch" href="/doc/assets/js/3.0958b336.js"><link rel="prefetch" href="/doc/assets/js/4.023f7c55.js"><link rel="prefetch" href="/doc/assets/js/6.32cb0422.js"><link rel="prefetch" href="/doc/assets/js/7.e50f21bc.js"><link rel="prefetch" href="/doc/assets/js/8.d2479dad.js">
<link rel="stylesheet" href="/doc/assets/css/0.styles.7cdd3ee2.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container no-sidebar"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/doc/" aria-current="page" class="home-link router-link-exact-active router-link-active"><!----> <span class="site-name">ZY PLAYER</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/doc/" aria-current="page" class="nav-link router-link-exact-active router-link-active">
主页
</a></div><div class="nav-item"><a href="/doc/sites/" class="nav-link">
管理源
</a></div><div class="nav-item"><a href="/doc/shortcut/" class="nav-link">
快捷键
</a></div><div class="nav-item"><a href="/doc/question/" class="nav-link">
常见问题
</a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/doc/" aria-current="page" class="nav-link router-link-exact-active router-link-active">
主页
</a></div><div class="nav-item"><a href="/doc/sites/" class="nav-link">
管理源
</a></div><div class="nav-item"><a href="/doc/shortcut/" class="nav-link">
快捷键
</a></div><div class="nav-item"><a href="/doc/question/" class="nav-link">
常见问题
</a></div> <!----></nav> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>Home</span> <!----></p> <!----></section></li></ul> </aside> <main aria-labelledby="main-title" class="home"><header class="hero"><!----> <h1 id="main-title">
ZY PLAYER
</h1> <p class="description">
ZY PLAYER 文档
</p> <p class="action"><a href="/doc/sites/" class="nav-link action-button">
开始阅读
</a></p></header> <div class="features"><div class="feature"><h2>管理源</h2> <p>导入, 导出, 编辑源</p></div><div class="feature"><h2>快捷键</h2> <p>导入, 导出, 编辑快捷键</p></div><div class="feature"><h2>常见问题问答</h2> <p>一些常见问题问答</p></div></div> <div class="theme-default-content custom content__default"></div> <div class="footer">
MIT Licensed | Copyright © 2020 Hunlongyu
</div></main></div><div class="global-ui"></div></div>
<script src="/doc/assets/js/app.441507e8.js" defer></script><script src="/doc/assets/js/2.b7bb5685.js" defer></script><script src="/doc/assets/js/5.445cad31.js" defer></script>
</body>
</html>

View File

@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>常见问题 | ZY PLAYER</title>
<meta name="generator" content="VuePress 1.5.2">
<meta name="description" content="ZY PLAYER 文档">
<link rel="preload" href="/doc/assets/css/0.styles.7cdd3ee2.css" as="style"><link rel="preload" href="/doc/assets/js/app.441507e8.js" as="script"><link rel="preload" href="/doc/assets/js/2.b7bb5685.js" as="script"><link rel="preload" href="/doc/assets/js/6.32cb0422.js" as="script"><link rel="prefetch" href="/doc/assets/js/3.0958b336.js"><link rel="prefetch" href="/doc/assets/js/4.023f7c55.js"><link rel="prefetch" href="/doc/assets/js/5.445cad31.js"><link rel="prefetch" href="/doc/assets/js/7.e50f21bc.js"><link rel="prefetch" href="/doc/assets/js/8.d2479dad.js">
<link rel="stylesheet" href="/doc/assets/css/0.styles.7cdd3ee2.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/doc/" class="home-link router-link-active"><!----> <span class="site-name">ZY PLAYER</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/doc/" class="nav-link">
主页
</a></div><div class="nav-item"><a href="/doc/sites/" class="nav-link">
管理源
</a></div><div class="nav-item"><a href="/doc/shortcut/" class="nav-link">
快捷键
</a></div><div class="nav-item"><a href="/doc/question/" aria-current="page" class="nav-link router-link-exact-active router-link-active">
常见问题
</a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/doc/" class="nav-link">
主页
</a></div><div class="nav-item"><a href="/doc/sites/" class="nav-link">
管理源
</a></div><div class="nav-item"><a href="/doc/shortcut/" class="nav-link">
快捷键
</a></div><div class="nav-item"><a href="/doc/question/" aria-current="page" class="nav-link router-link-exact-active router-link-active">
常见问题
</a></div> <!----></nav> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>常见问题</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/doc/question/#常见问题" class="sidebar-link">常见问题</a><ul class="sidebar-sub-headers"></ul></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h2 id="常见问题"><a href="#常见问题" class="header-anchor">#</a> 常见问题</h2> <ol><li></li></ol></div> <footer class="page-edit"><!----> <!----></footer> <!----> </main></div><div class="global-ui"></div></div>
<script src="/doc/assets/js/app.441507e8.js" defer></script><script src="/doc/assets/js/2.b7bb5685.js" defer></script><script src="/doc/assets/js/6.32cb0422.js" defer></script>
</body>
</html>

File diff suppressed because one or more lines are too long

34
docs/doc/sites/index.html Normal file

File diff suppressed because one or more lines are too long

View File

@@ -50,6 +50,7 @@
<nav class="nav-menu d-none d-lg-block">
<ul>
<li class="active"><a href="#header">Home</a></li>
<li><a href="http://zyplayer.fun/doc/">文档</a></li>
<li><a href="#features">特色</a></li>
<li><a href="#gallery">截图</a></li>
<li><a href="#faq">常见问题</a></li>
@@ -234,6 +235,7 @@
<ul>
<li><i class="bx bx-chevron-right"></i> <a target="_blank" href="#">Home</a></li>
<li><i class="bx bx-chevron-right"></i> <a target="_blank" href="https://www.ghpym.com/zyplayer.html">果核剥壳</a></li>
<li><i class="bx bx-chevron-right"></i> <a target="_blank" href="https://www.iplaysoft.com/zy-player.html">异次元软件世界</a></li>
</ul>
</div>
@@ -278,4 +280,4 @@
</body>
</html>
</html>

View File

@@ -0,0 +1,571 @@
#EXTM3U
#EXTINF:-1,CCTV1-1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/cctv1hd/4000000/mnf.m3u8
#EXTINF:-1,CCTV-1HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/cctv1hd/2300000/mnf.m3u8
#EXTINF:-1,CCTV1 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225924/1.m3u8
#EXTINF:-1,CCTV1 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226154/1.m3u8
#EXTINF:-1,CCTV1 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226155/1.m3u8
#EXTINF:-1,CCTV1 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226226/1.m3u8
#EXTINF:-1,CCTV1 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226346/1.m3u8
#EXTINF:-1,CCTV1 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226431/1.m3u8
#EXTINF:-1,CCTV2 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226230/1.m3u8
#EXTINF:-1,CCTV2 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226371/1.m3u8
#EXTINF:-1,CCTV2 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226472/1.m3u8
#EXTINF:-1,CCTV3 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226471/1.m3u8
#EXTINF:-1,CCTV4 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226314/1.m3u8
#EXTINF:-1,CCTV4 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226335/1.m3u8
#EXTINF:-1,CCTV4 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226470/1.m3u8
#EXTINF:-1,CCTV5 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226469/1.m3u8
#EXTINF:-1,CCTV5+ HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226225/1.m3u8
#EXTINF:-1,CCTV5+ CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226349/1.m3u8
#EXTINF:-1,CCTV5+ CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226458/1.m3u8
#EXTINF:-1,CCTV6 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226468/1.m3u8
#EXTINF:-1,CCTV7 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226234/1.m3u8
#EXTINF:-1,CCTV7 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226467/1.m3u8
#EXTINF:-1,CCTV8 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226485/1.m3u8
#EXTINF:-1,CCTV9 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226236/1.m3u8
#EXTINF:-1,CCTV9 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226465/1.m3u8
#EXTINF:-1,CCTV10 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226227/1.m3u8
#EXTINF:-1,CCTV10 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226464/1.m3u8
#EXTINF:-1,CCTV11 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226334/1.m3u8
#EXTINF:-1,CCTV11 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226315/1.m3u8
#EXTINF:-1,CCTV11 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226463/1.m3u8
#EXTINF:-1,CCTV12 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226228/1.m3u8
#EXTINF:-1,CCTV12 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226462/1.m3u8
#EXTINF:-1,CCTV13 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226316/1.m3u8
#EXTINF:-1,CCTV14 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226229/1.m3u8
#EXTINF:-1,CCTV14 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226461/1.m3u8
#EXTINF:-1,CCTV15 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226460/1.m3u8
#EXTINF:-1,CCTV15 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226317/1.m3u8
#EXTINF:-1,CCTV15 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226333/1.m3u8
#EXTINF:-1,CCTV17 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226318/1.m3u8
#EXTINF:-1,CCTV17 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226459/1.m3u8
#EXTINF:-1,CCTV-4K
http://112.17.40.12/PLTV/88888888/224/3221226758/1.m3u8
#EXTINF:-1,CCTV-4K
http://112.17.40.140/PLTV/88888888/224/3221226758/index.m3u8
#EXTINF:-1,CCTV-4K
http://39.134.176.148/PLTV/88888888/224/3221226758/index.m3u8
#EXTINF:-1,CCTV-4K
http://117.148.187.83/PLTV/88888888/224/3221226758/index.m3u8
#EXTINF:-1,北京卫视1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/bjwshd/4000000/mnf.m3u8
#EXTINF:-1,江苏卫视1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/jswshd/4000000/mnf.m3u8
#EXTINF:-1,浙江卫视1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/zjwshd/4000000/mnf.m3u8
#EXTINF:-1,深圳卫视1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/szwshd/4000000/mnf.m3u8
#EXTINF:-1,山东卫视1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/sdwshd/4000000/mnf.m3u8
#EXTINF:-1,湖北卫视1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/hbwshd/4000000/mnf.m3u8
#EXTINF:-1,广东卫视1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/gdwshd/4000000/mnf.m3u8
#EXTINF:-1,东方卫视1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/hddfws/4000000/mnf.m3u8
#EXTINF:-1,黑龙江卫视1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/hljwshd/4000000/mnf.m3u8
#EXTINF:-1,五星体育1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/ssty/4000000/mnf.m3u8
#EXTINF:-1,北京卫视高清
http://keonline.shanghai.liveplay.qq.com/live/program/live/bjwshd/1300000/mnf.m3u8
#EXTINF:-1,东方卫视高清
http://keonline.shanghai.liveplay.qq.com/live/program/live/hddfws/1300000/mnf.m3u8
#EXTINF:-1,浙江卫视高清
http://keonline.shanghai.liveplay.qq.com/live/program/live/zjwshd/1300000/mnf.m3u8
#EXTINF:-1,湖北卫视高清
http://keonline.shanghai.liveplay.qq.com/live/program/live/hbwshd/1300000/mnf.m3u8
#EXTINF:-1,湖南卫视高清
http://keonline.shanghai.liveplay.qq.com/live/program/live/hnwshd/1300000/mnf.m3u8
#EXTINF:-1,山东卫视高清
http://keonline.shanghai.liveplay.qq.com/live/program/live/sdwshd/1300000/mnf.m3u8
#EXTINF:-1,江苏卫视高清
http://keonline.shanghai.liveplay.qq.com/live/program/live/jswshd/1300000/mnf.m3u8
#EXTINF:-1,深圳卫视高清
http://keonline.shanghai.liveplay.qq.com/live/program/live/szwshd/1300000/mnf.m3u8
#EXTINF:-1,广东卫视高清
http://keonline.shanghai.liveplay.qq.com/live/program/live/gdwshd/1300000/mnf.m3u8
#EXTINF:-1,黑龙江卫视高清
http://keonline.shanghai.liveplay.qq.com/live/program/live/hljwshd/1300000/mnf.m3u8
#EXTINF:-1,湖南卫视HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/hnwshd/2300000/mnf.m3u8
#EXTINF:-1,北京卫视HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/bjwshd/2300000/mnf.m3u8
#EXTINF:-1,江苏卫视HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/jswshd/2300000/mnf.m3u8
#EXTINF:-1,浙江卫视HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/zjwshd/2300000/mnf.m3u8
#EXTINF:-1,深圳卫视HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/szwshd/2300000/mnf.m3u8
#EXTINF:-1,山东卫视HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/sdwshd/2300000/mnf.m3u8
#EXTINF:-1,湖北卫视HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/hbwshd/2300000/mnf.m3u8
#EXTINF:-1,广东卫视HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/gdwshd/2300000/mnf.m3u8
#EXTINF:-1,黑龙江卫视HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/hljwshd/2300000/mnf.m3u8
#EXTINF:-1,五星体育HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/ssty/2300000/mnf.m3u8
#EXTINF:-1,中国教育1 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226494/1.m3u8
#EXTINF:-1,东南卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226406/1.m3u8
#EXTINF:-1,东南卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226496/1.m3u8
#EXTINF:-1,东方卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226237/1.m3u8
#EXTINF:-1,东方卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226364/1.m3u8
#EXTINF:-1,东方卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226505/1.m3u8
#EXTINF:-1,北京卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226224/1.m3u8
#EXTINF:-1,北京卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226367/1.m3u8
#EXTINF:-1,北京卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226441/1.m3u8
#EXTINF:-1,天津卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226246/1.m3u8
#EXTINF:-1,天津卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226502/1.m3u8
#EXTINF:-1,安徽卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226223/1.m3u8
#EXTINF:-1,安徽卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226499/1.m3u8
#EXTINF:-1,山东卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225894/1.m3u8
#EXTINF:-1,山东卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226244/1.m3u8
#EXTINF:-1,山东卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226308/1.m3u8
#EXTINF:-1,山东卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226501/1.m3u8
#EXTINF:-1,广东卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225878/1.m3u8
#EXTINF:-1,广东卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226238/1.m3u8
#EXTINF:-1,广东卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226508/1.m3u8
#EXTINF:-1,江苏卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226242/1.m3u8
#EXTINF:-1,江苏卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226366/1.m3u8
#EXTINF:-1,江苏卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226506/1.m3u8
#EXTINF:-1,江西卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226243/1.m3u8
#EXTINF:-1,河北卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226507/1.m3u8
#EXTINF:-1,浙江卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226247/1.m3u8
#EXTINF:-1,浙江卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226365/1.m3u8
#EXTINF:-1,浙江卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226504/1.m3u8
#EXTINF:-1,深圳卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225897/1.m3u8
#EXTINF:-1,深圳卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226245/1.m3u8
#EXTINF:-1,深圳卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226495/1.m3u8
#EXTINF:-1,湖北卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226240/1.m3u8
#EXTINF:-1,湖北卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226310/1.m3u8
#EXTINF:-1,湖北卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226503/1.m3u8
#EXTINF:-1,湖南卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226241/1.m3u8
#EXTINF:-1,湖南卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226509/1.m3u8
#EXTINF:-1,贵州卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226497/1.m3u8
#EXTINF:-1,辽宁卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226500/1.m3u8
#EXTINF:-1,黑龙江卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226239/1.m3u8
#EXTINF:-1,黑龙江卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226498/1.m3u8
#EXTINF:-1,北京冬奥纪实 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226438/1.m3u8
#EXTINF:-1,北京影视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226486/1.m3u8
#EXTINF:-1,北京文艺 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226440/1.m3u8
#EXTINF:-1,北京新闻 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226437/1.m3u8
#EXTINF:-1,安徽卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/ahws/1300000/mnf.m3u8
#EXTINF:-1,兵团卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/btws/1300000/mnf.m3u8
#EXTINF:-1,甘肃卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/gsws/1300000/mnf.m3u8
#EXTINF:-1,陕西卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/sxws/1300000/mnf.m3u8
#EXTINF:-1,山西卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/shanxiws/1300000/mnf.m3u8
#EXTINF:-1,吉林卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/jlws/1300000/mnf.m3u8
#EXTINF:-1,河北卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/hbws/1300000/mnf.m3u8
#EXTINF:-1,四川卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/scws/1300000/mnf.m3u8
#EXTINF:-1,贵州卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/gzws/1300000/mnf.m3u8
#EXTINF:-1,云南卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/ynws/1300000/mnf.m3u8
#EXTINF:-1,辽宁卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/lnws/1300000/mnf.m3u8
#EXTINF:-1,旅游卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/lyws/1300000/mnf.m3u8
#EXTINF:-1,东南卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/dnws/1300000/mnf.m3u8
#EXTINF:-1,重庆卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/cqws/1300000/mnf.m3u8
#EXTINF:-1,广西卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/gxws/1300000/mnf.m3u8
#EXTINF:-1,青海卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/qhws/1300000/mnf.m3u8
#EXTINF:-1,江西卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/jxws/1300000/mnf.m3u8
#EXTINF:-1,内蒙古卫视
http://keonline.shanghai.liveplay.qq.com/live/program/live/nmgws/1300000/mnf.m3u8
#EXTINF:-1,天津卫视
http://112.17.40.140/PLTV/88888888/224/3221226412/index.m3u8
#EXTINF:-1,河北卫视超清1
http://223.110.245.149/ott.js.chinamobile.com/PLTV/3/224/3221225840/index.m3u8
#EXTINF:-1,湖南卫视
http://112.17.40.140/PLTV/88888888/224/3221226553/index.m3u8
#EXTINF:-1,浙江卫视
http://223.110.243.173/PLTV/3/224/3221227215/index.m3u8
#EXTINF:-1,江苏卫视
http://112.17.40.140/PLTV/88888888/224/3221226414/index.m3u8
#EXTINF:-1,东南卫视
http://117.169.124.37:6610/ysten-businessmobile/live/dongnanstv/yst.m3u8
#EXTINF:-1,湖北卫视
http://223.110.243.171/PLTV/3/224/3221227211/index.m3u8
#EXTINF:-1,广东卫视
http://112.17.40.140/PLTV/88888888/224/3221226225/index.m3u8
#EXTINF:-1,深圳卫视
http://223.110.243.171/PLTV/3/224/3221227217/index.m3u8
#EXTINF:-1,辽宁卫视
http://223.110.245.145/ott.js.chinamobile.com/PLTV/3/224/3221227410/index.m3u8
#EXTINF:-1,龙江卫视
http://112.17.40.140/PLTV/88888888/224/3221226555/index.m3u8
#EXTINF:-1,江西卫视
http://112.17.40.140/PLTV/88888888/224/3221226557/index.m3u8
#EXTINF:-1,四川卫视
http://ott.fj.chinamobile.com/PLTV/88888888/224/3221227006/1.m3u8
#EXTINF:-1,重庆卫视
http://ott.fj.chinamobile.com/PLTV/88888888/224/3221225949/1.m3u8
#EXTINF:-1,重庆卫视
http://ivi.bupt.edu.cn/hls/cqhd.m3u8
#EXTINF:-1,河南卫视超清2
http://223.110.245.157/ott.js.chinamobile.com/PLTV/3/224/3221225815/index.m3u8
#EXTINF:-1,贵州卫视超清2
http://223.110.245.149/ott.js.chinamobile.com/PLTV/3/224/3221225787/index.m3u8
#EXTINF:-1,海南卫视
http://112.50.243.8/PLTV/88888888/224/3221225855/1.m3u8
#EXTINF:-1,云南卫视超清1
http://223.110.245.159/ott.js.chinamobile.com/PLTV/3/224/3221225838/index.m3u8
#EXTINF:-1,宁夏卫视超清1
http://223.110.245.151/ott.js.chinamobile.com/PLTV/3/224/3221225842/index.m3u8
#EXTINF:-1,内蒙卫视超清1
http://223.110.245.161/ott.js.chinamobile.com/PLTV/3/224/3221225836/index.m3u8
#EXTINF:-1,广西卫视
http://112.50.243.8/PLTV/88888888/224/3221225836/1.m3u8
#EXTINF:-1,五星体育HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/ssty/1300000/mnf.m3u8
#EXTINF:-1,北京卡酷少儿 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226558/1.m3u8
#EXTINF:-1,法治天地HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/fztd/1300000/mnf.m3u8
#EXTINF:-1,欢笑剧场HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/hxjc/1300000/mnf.m3u8
#EXTINF:-1,都市剧场HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/dsjc/1300000/mnf.m3u8
#EXTINF:-1,七彩戏剧HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/qcxj/1300000/mnf.m3u8
#EXTINF:-1,动漫秀场HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/dmxc/1300000/mnf.m3u8
#EXTINF:-1,劲爆体育HD
http://keonline.shanghai.liveplay.qq.com/live/program/live/jbty/1300000/mnf.m3u8
#EXTINF:-1,极速汽车
http://keonline.shanghai.liveplay.qq.com/live/program/live/jsqc/1300000/mnf.m3u8
#EXTINF:-1,游戏风云
http://keonline.shanghai.liveplay.qq.com/live/program/live/yxfy/1300000/mnf.m3u8
#EXTINF:-1,金鹰卡通
http://keonline.shanghai.liveplay.qq.com/live/program/live/jykt/1300000/mnf.m3u8
#EXTINF:-1,炫动卡通
http://keonline.shanghai.liveplay.qq.com/live/program/live/xdkt/1300000/mnf.m3u8
#EXTINF:-1,嘉佳卡通
http://keonline.shanghai.liveplay.qq.com/live/program/live/jjkt/1300000/mnf.m3u8
#EXTINF:-1,星尚
http://keonline.shanghai.liveplay.qq.com/live/program/live/shss/1300000/mnf.m3u8
#EXTINF:-1,上海纪实
http://keonline.shanghai.liveplay.qq.com/live/program/live/jspd/1300000/mnf.m3u8
#EXTINF:-1,上海新闻
http://keonline.shanghai.liveplay.qq.com/live/program/live/xwzh/1300000/mnf.m3u8
#EXTINF:-1,上海娱乐
http://keonline.shanghai.liveplay.qq.com/live/program/live/ylpd/1300000/mnf.m3u8
#EXTINF:-1,上海电视剧
http://keonline.shanghai.liveplay.qq.com/live/program/live/dsjpd/1300000/mnf.m3u8
#EXTINF:-1,上海ICS外语频道
http://keonline.shanghai.liveplay.qq.com/live/program/live/wypd/1300000/mnf.m3u8
#EXTINF:-1,上海艺术人文
http://keonline.shanghai.liveplay.qq.com/live/program/live/ysrw/1300000/mnf.m3u8
#EXTINF:-1,东方财经浦东
http://keonline.shanghai.liveplay.qq.com/live/program/live/dfcj/1300000/mnf.m3u8
#EXTINF:-1,第一财经
http://keonline.shanghai.liveplay.qq.com/live/program/live/dycj/1300000/mnf.m3u8
#EXTINF:-1,直播1-1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/hdnba1/4000000/mnf.m3u8
#EXTINF:-1,直播2-1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/hdnba2/4000000/mnf.m3u8
#EXTINF:-1,直播3-1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/hdnba3/4000000/mnf.m3u8
#EXTINF:-1,直播4-1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/hdnba4/4000000/mnf.m3u8
#EXTINF:-1,直播5-1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/hdnba5/4000000/mnf.m3u8
#EXTINF:-1,直播6-1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/hdnba6/4000000/mnf.m3u8
#EXTINF:-1,直播7-1080P
http://keonline.shanghai.liveplay.qq.com/live/program/live/hdnba7/4000000/mnf.m3u8
#EXTINF:-1,纯享4K源码1
http://112.50.243.8/PLTV/88888888/224/3221226825/1.m3u8
#EXTINF:-1,百事4K频道
http://112.17.40.145/PLTV/88888888/224/3221226718/index.m3u8
#EXTINF:-1,凤凰资讯
http://112.17.40.140/PLTV/88888888/224/3221226491/index.m3u8
#EXTINF:-1,凤凰资讯
http://117.169.124.37:6610/ysten-businessmobile/live/fhzixun/1.m3u8
#EXTINF:-1,凤凰中文
http://117.169.124.37:6610/ysten-businessmobile/live/fhchinese/1.m3u8
#EXTINF:-1,凤凰中文
http://117.169.120.138:8080/live/fhchinese/index.m3u8
#EXTINF:-1,高清影视1台
http://112.50.243.8/PLTV/88888888/224/3221226736/1.m3u8
#EXTINF:-1,高清影视2台
http://112.50.243.8/PLTV/88888888/224/3221225881/1.m3u8
#EXTINF:-1,高清影视3台
http://112.50.243.8/PLTV/88888888/224/3221226708/1.m3u8
#EXTINF:-1,高清影视4台
http://112.50.243.8/PLTV/88888888/224/3221226712/1.m3u8
#EXTINF:-1,高清影视5台
http://112.50.243.8/PLTV/88888888/224/3221225893/1.m3u8
#EXTINF:-1,高清影视6台
http://112.50.243.8/PLTV/88888888/224/3221226692/1.m3u8
#EXTINF:-1,高清影视7台
http://112.50.243.8/PLTV/88888888/224/3221226754/1.m3u8
#EXTINF:-1,高清影视8台
http://112.17.40.145/PLTV/88888888/224/3221226608/index.m3u8
#EXTINF:-1,高清影视9台
http://112.17.40.145/PLTV/88888888/224/3221226606/index.m3u8
#EXTINF:-1,高清影视10台
http://112.17.40.145/PLTV/88888888/224/3221226360/index.m3u8
#EXTINF:-1,高清动画11台
http://112.50.243.8/PLTV/88888888/224/3221226732/1.m3u8
#EXTINF:-1,高清动画12台
http://112.50.243.8/PLTV/88888888/224/3221226741/1.m3u8
#EXTINF:-1,高清动漫13台
http://112.50.243.8/PLTV/88888888/224/3221226743/1.m3u8
#EXTINF:-1,高清影视14台
http://ivi.bupt.edu.cn/hls/chchd.m3u8
#EXTINF:-1,北京纪实高清
http://112.50.243.8/PLTV/88888888/224/3221225944/1.m3u8
#EXTINF:-1,峨眉电影高清
http://scgctvshow.sctv.com/hdlive/emei/1.m3u8
#EXTINF:-1,欢笑剧场高清
http://112.50.243.8/PLTV/88888888/224/3221226729/1.m3u8
#EXTINF:-1,纪实频道高清
http://112.50.243.8/PLTV/88888888/224/3221225946/1.m3u8
#EXTINF:-1,极速汽车高清
http://112.50.243.8/PLTV/88888888/224/3221226140/1.m3u8
#EXTINF:-1,动漫秀场高清
http://112.50.243.8/PLTV/88888888/224/3221226141/1.m3u8
#EXTINF:-1,求索纪录
http://112.17.40.145/PLTV/88888888/224/3221226610/index.m3u8
#EXTINF:-1,求索科学
http://125.210.152.18:9090/live/QSKX_1200.m3u8
#EXTINF:-1,求索动物
http://125.210.152.18:9090/live/QSDW_1200.m3u8
#EXTINF:-1,求索生活
http://125.210.152.18:9090/live/QSSH_1200.m3u8
#EXTINF:-1,日本天気预报
http://movie.mcas.jp/mcas/wn1_2/master.m3u8
#EXTINF:-1,奥林匹克高清
http://ott-live.olympicchannel.com/out/u/OC1_2.m3u8?fluxustv.m3u8
#EXTINF:-1,奥铃匹克高清
http://ott-live.olympicchannel.com/out/u/OC1_1.m3u8?fluxustv.m3u8
#EXTINF:-1,爱青春
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230130/index.m3u8
#EXTINF:-1,爱家庭
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230118/index.m3u8
#EXTINF:-1,爱探索
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230112/index.m3u8
#EXTINF:-1,爱科学
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230106/index.m3u8
#EXTINF:-1,爱猎奇
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230097/index.m3u8
#EXTINF:-1,爱谍战
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230092/index.m3u8
#EXTINF:-1,爱娱乐
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230077/index.m3u8
#EXTINF:-1,爱旅行
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230052/index.m3u8
#EXTINF:-1,爱怀旧
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230049/index.m3u8
#EXTINF:-1,爱体育
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230034/index.m3u8
#EXTINF:-1,爱赛车
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230032/index.m3u8
#EXTINF:-1,北京少儿
http://ivi.bupt.edu.cn/hls/btv10.m3u8
#EXTINF:-1,动漫电影
http://112.17.40.140/PLTV/88888888/224/3221226178/index.m3u8
#EXTINF:-1,重庆少儿
http://219.153.252.50/PLTV/88888888/224/3221225646/1.m3u8
#EXTINF:-1,嘉佳卡通
http://112.17.40.140/PLTV/88888888/224/3221226461/index.m3u8
#EXTINF:-1,耀才财经
http://202.69.67.66:443/webcast/bshdlive-mobile/playlist.m3u8
#EXTINF:-1,亚旅卫视
http://hls.jingchangkan.tv/jingchangkan/156722438_0HaM/index.m3u8
#EXTINF:-1,信吉电视
http://220.130.241.203:1935/sjtv/livestream_360p/playlist.m3u8
#EXTINF:-1,唯心電視
http://mobile.ccdntech.com/transcoder/_definst_/vod164_Live/live/chunklist_w1177047531.m3u8
#EXTINF:-1,百事通台
http://112.17.40.145/PLTV/88888888/224/3221226596/index.m3u8
#EXTINF:-1,HBO2台
http://161.0.157.5/PLTV/88888888/224/3221227026/03.m3u8fluxustv.m3u8
#EXTINF:-1,点掌财经
http://cclive2.aniu.tv/live/anzb.m3u8
#EXTINF:-1,日本NHK华语
https://nhkw-zh-hlscomp.akamaized.net/ixxemlzk1vqvy44o/playlist.m3u8
#EXTINF:-1,日本NHK英语
https://nhkwlive-ojp.akamaized.net/hls/live/2003459/nhkwlive-ojp/index_1M.m3u8
#EXTINF:-1,日本Japan News 24
http://www.news24.jp/livestream/index.m3u8
#EXTINF:-1,日本JapanetChannelDX
http://bcsecurelivehls-i.akamaihd.net/hls/live/265320/5043843989001/140130JTDX/index_1200.m3u8
#EXTINF:-1,日本QVC
http://cdn-live1.qvc.jp/iPhone/800/800.m3u8
#EXTINF:-1,韩国EBS 第一频道
http://ebsonairios.ebs.co.kr/groundwavetablet500k/tablet500k/playlist.m3u8
#EXTINF:-1,韩国EBS 少儿频道
http://ebsonairios.ebs.co.kr/ebsutablet500k/tablet500k/playlist.m3u8
#EXTINF:-1,韩国KCTV
http://119.77.96.184:1935/chn21/chn21/chunklist_w252131137.m3u8
#EXTINF:-1,朝鲜中央台
http://119.77.96.184:1935/chn05/chn05/chunklist_w644291506.m3u8
#EXTINF:-1,韩国KTV 韩国电视
http://218.38.152.31:1935/klive/klive.stream/playlist.m3u8
#EXTINF:-1,韩国EBS 儿童频道
http://ebsonairios.ebs.co.kr/ebsutablet500k/_definst_/tablet500k/chunklist_w1965791004.m3u8
#EXTINF:-1,韩国阿里郎WORLDworld
http://amdlive.ctnd.com.edgesuite.net/arirang_1ch/smil:arirang_1ch.smil/playlist.m3u8
#EXTINF:-1,韩国阿里郎WORLD
http://amdlive.ctnd.com.edgesuite.net/arirang_1ch/smil:arirang_1ch/master.m3u8
#EXTINF:-1,KOREA YTN Science
http://slive.sciencetv.kr:1935/science/yslive_20140419_1/playlist.m3u8
#EXTINF:-1,Luxury World
http://nano.teleservice.su:8080/hls/luxury.m3u8
#EXTINF:-1,韩国BBS佛教广播
http://bbstv.clouducs.com:1935/bbstv-live/livestream/chunklist_w1403706733.m3u8
#EXTINF:-1,CPAC
http://bcoveliveios-i.akamaihd.net/hls/live/248519/1242843915001_1/master.m3u8
#EXTINF:-1,中国环球
http://live.cgtn.com/1000/prog_index.m3u8
#EXTINF:-1,狗狗宠物
http://video.blivenyc.com/broadcast/prod/2061/22/file-3192k.m3u8
#EXTINF:-1,法国时尚
http://lb.streaming.sk/fashiontv/stream/chunklist_w1702070444.m3u8
#EXTINF:-1,亚洲新闻
http://d2e1asnsl7br7b.cloudfront.net/7782e205e72f43aeb4a48ec97f66ebbe/index_4.m3u8
#EXTINF:-1,越南人民报
http://vietcago.net/vstv/thnd.m3u8
#EXTINF:-1,印度音乐电视
http://104.237.60.234/live/gabruutv.m3u8?dsjtv.m3u8
#EXTINF:-1,法国第五世界台
http://v3plusinfo247hls-i.akamaihd.net/hls/live/218877-b/v3plusinfo247hls/v3plusinfo247hls_1_1.m3u8
#EXTINF:-1,俄罗斯HD时尚频道
http://95.67.47.115/hls/hdfashion_ua_hi/index.m3u8
#EXTINF:-1,乌克兰M2 音乐频道
http://live.m2.tv/hls3/stream.m3u8
#EXTINF:-1,西班牙中国环球
http://livees.cgtn.com/1000e/prog_index.m3u8
#EXTINF:-1,意大利意大利电台
http://radioitaliatv-lh.akamaihd.net/i/radioitaliatv_1@329645/index_720x480_av-p.m3u8
#EXTINF:-1,意大利V2 音乐频道
http://de1se01.v2beat.live/playlist.m3u8
#EXTINF:-1,墨西哥墨西哥电视
http://bcoveliveios-i.akamaihd.net/hls/live/201661/57828478001/milenio_center_512k@51752.m3u8
#EXTINF:-1,音乐20TV
http://m2otv-lh.akamaihd.net/i/m2oTv_1@186074/index_600_av-p.m3u8
#EXTINF:-1,当红MTV
http://unilivemtveu-lh.akamaihd.net/i/mtvno_1@346424/index_3500_av-b.m3u8
#EXTINF:-1,酷酷频道
http://edge1.tikilive.com:1935/unrestricted_tikilive/25947/amlst:NWKlw6jwyXpz/chunklist_w981409619_b1105254.m3u8?fluxustv.m3u8
#EXTINF:-1,红牛电视
http://rbmn-live.akamaized.net/hls/live/590964/BoRB-AT/master_1660.m3u8
#EXTINF:-1,NBC电视
http://161.0.157.51/PLTV/88888888/224/3221227040/index.m3u8?fluxustv.m3u8
#EXTINF:-1,Jewelry电视
http://wowzaprod134-i.akamaihd.net/hls/live/577814/ccddaf02/playlist.m3u8
#EXTINF:-1,Darcizzle电视
http://30a-tv.com/darcizzle.m3u8
#EXTINF:-1,CBS新闻
http://cbsnewshd-lh.akamaihd.net/i/CBSNHD_7@199302/master.m3u8
#EXTINF:-1,美国Deutsche Welle
http://dwstream4-lh.akamaihd.net/i/dwstream4_live@131329/master.m3u8
#EXTINF:-1,美国360 North
http://wowzaprod3-i.akamaihd.net/hls/live/252236/2147483647_360north_247/playlist.m3u8
#EXTINF:-1,美国Fox News Talk Radio
http://fnurtmp-f.akamaihd.net/i/FNRADIO_1@92141/master.m3u8
#EXTINF:-1,日本cgntv
http://cgntv-glive.ofsdelivery.net/live/_definst_/cgntv_jp/playlist.m3u8
#EXTINF:-1,日本Japanet Channel DX
http://bcsecurelivehls-i.akamaihd.net/hls/live/265320/5043843989001/140130JTDX/index_600.m3u8

View File

@@ -0,0 +1,723 @@
#EXTM3U
#EXTINF:-1 ,====== =北京移动= ======
http://0/0.m3u8
#EXTINF:-1 ,咪咕4K
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226399/1.m3u8
#EXTINF:-1 ,咪咕4K
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226400/1.m3u8
#EXTINF:-1 ,北京IPTV4K超清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226550/1.m3u8
#EXTINF:-1 ,北京IPTV淘BABY CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226554/1.m3u8
#EXTINF:-1 ,北京IPTV淘剧场 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226553/1.m3u8
#EXTINF:-1 ,北京IPTV淘娱乐 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226551/1.m3u8
#EXTINF:-1 ,北京IPTV淘电影 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226552/1.m3u8
#EXTINF:-1 ,北京IPTV萌宠TV CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226555/1.m3u8
#EXTINF:-1 ,老伙计-laoguy.com
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226555/1.m3u8
#EXTINF:-1 ,大健康 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226556/1.m3u8
#EXTINF:-1 ,凤凰中文 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225942/1.m3u8
#EXTINF:-1 ,凤凰中文 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225948/1.m3u8
#EXTINF:-1 ,凤凰资讯 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225949/1.m3u8
#EXTINF:-1 ,CCTV1 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225924/1.m3u8
#EXTINF:-1 ,CCTV1 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226154/1.m3u8
#EXTINF:-1 ,CCTV1 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226155/1.m3u8
#EXTINF:-1 ,CCTV1 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226226/1.m3u8
#EXTINF:-1 ,CCTV1 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226346/1.m3u8
#EXTINF:-1 ,CCTV1 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226431/1.m3u8
#EXTINF:-1 ,CCTV2 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226230/1.m3u8
#EXTINF:-1 ,CCTV2 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226371/1.m3u8
#EXTINF:-1 ,CCTV2 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226472/1.m3u8
#EXTINF:-1 ,CCTV3 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226471/1.m3u8
#EXTINF:-1 ,CCTV4 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226314/1.m3u8
#EXTINF:-1 ,CCTV4 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226335/1.m3u8
#EXTINF:-1 ,CCTV4 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226470/1.m3u8
#EXTINF:-1 ,CCTV5 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226469/1.m3u8
#EXTINF:-1 ,CCTV5+ HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226225/1.m3u8
#EXTINF:-1 ,CCTV5+ CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226349/1.m3u8
#EXTINF:-1 ,CCTV5+ CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226458/1.m3u8
#EXTINF:-1 ,CCTV6 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226468/1.m3u8
#EXTINF:-1 ,CCTV7 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226234/1.m3u8
#EXTINF:-1 ,CCTV7 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226467/1.m3u8
#EXTINF:-1 ,CCTV8 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226485/1.m3u8
#EXTINF:-1 ,CCTV9 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226236/1.m3u8
#EXTINF:-1 ,CCTV9 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226465/1.m3u8
#EXTINF:-1 ,CCTV10 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226227/1.m3u8
#EXTINF:-1 ,CCTV10 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226464/1.m3u8
#EXTINF:-1 ,CCTV11 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226334/1.m3u8
#EXTINF:-1 ,CCTV11 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226315/1.m3u8
#EXTINF:-1 ,CCTV11 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226463/1.m3u8
#EXTINF:-1 ,CCTV12 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226228/1.m3u8
#EXTINF:-1 ,CCTV12 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226462/1.m3u8
#EXTINF:-1 ,CCTV13 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226316/1.m3u8
#EXTINF:-1 ,CCTV14 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226229/1.m3u8
#EXTINF:-1 ,CCTV14 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226461/1.m3u8
#EXTINF:-1 ,CCTV15 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226460/1.m3u8
#EXTINF:-1 ,CCTV15 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226317/1.m3u8
#EXTINF:-1 ,CCTV15 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226333/1.m3u8
#EXTINF:-1 ,CCTV17 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226318/1.m3u8
#EXTINF:-1 ,CCTV17 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226459/1.m3u8
#EXTINF:-1 ,中国教育1 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226494/1.m3u8
#EXTINF:-1 ,东南卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226406/1.m3u8
#EXTINF:-1 ,东南卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226496/1.m3u8
#EXTINF:-1 ,东方卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226237/1.m3u8
#EXTINF:-1 ,东方卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226364/1.m3u8
#EXTINF:-1 ,东方卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226505/1.m3u8
#EXTINF:-1 ,北京卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226224/1.m3u8
#EXTINF:-1 ,北京卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226367/1.m3u8
#EXTINF:-1 ,北京卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226441/1.m3u8
#EXTINF:-1 ,天津卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226246/1.m3u8
#EXTINF:-1 ,天津卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226502/1.m3u8
#EXTINF:-1 ,安徽卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226223/1.m3u8
#EXTINF:-1 ,安徽卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226499/1.m3u8
#EXTINF:-1 ,山东卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225894/1.m3u8
#EXTINF:-1 ,山东卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226244/1.m3u8
#EXTINF:-1 ,山东卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226308/1.m3u8
#EXTINF:-1 ,山东卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226501/1.m3u8
#EXTINF:-1 ,广东卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225878/1.m3u8
#EXTINF:-1 ,广东卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226238/1.m3u8
#EXTINF:-1 ,广东卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226508/1.m3u8
#EXTINF:-1 ,江苏卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226242/1.m3u8
#EXTINF:-1 ,江苏卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226366/1.m3u8
#EXTINF:-1 ,江苏卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226506/1.m3u8
#EXTINF:-1 ,江西卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226243/1.m3u8
#EXTINF:-1 ,河北卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226507/1.m3u8
#EXTINF:-1 ,浙江卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226247/1.m3u8
#EXTINF:-1 ,浙江卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226365/1.m3u8
#EXTINF:-1 ,浙江卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226504/1.m3u8
#EXTINF:-1 ,深圳卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225897/1.m3u8
#EXTINF:-1 ,深圳卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226245/1.m3u8
#EXTINF:-1 ,深圳卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226495/1.m3u8
#EXTINF:-1 ,湖北卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226240/1.m3u8
#EXTINF:-1 ,湖北卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226310/1.m3u8
#EXTINF:-1 ,湖北卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226503/1.m3u8
#EXTINF:-1 ,湖南卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226241/1.m3u8
#EXTINF:-1 ,湖南卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226509/1.m3u8
#EXTINF:-1 ,贵州卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226497/1.m3u8
#EXTINF:-1 ,辽宁卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226500/1.m3u8
#EXTINF:-1 ,黑龙江卫视 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226239/1.m3u8
#EXTINF:-1 ,黑龙江卫视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226498/1.m3u8
#EXTINF:-1 ,北京冬奥纪实 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226438/1.m3u8
#EXTINF:-1 ,北京影视 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226486/1.m3u8
#EXTINF:-1 ,北京文艺 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226440/1.m3u8
#EXTINF:-1 ,北京新闻 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226437/1.m3u8
#EXTINF:-1 ,北京卡酷少儿 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226558/1.m3u8
#EXTINF:-1 ,湖南快乐垂钓 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226549/1.m3u8
#EXTINF:-1 ,湖南茶频道 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226548/1.m3u8
#EXTINF:-1 ,黑莓动画 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225914/1.m3u8
#EXTINF:-1 ,黑莓动画 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226289/1.m3u8
#EXTINF:-1 ,黑莓电影 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225927/1.m3u8
#EXTINF:-1 ,黑莓电影 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226292/1.m3u8
#EXTINF:-1 ,黑莓电竞 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225931/1.m3u8
#EXTINF:-1 ,黑莓电竞 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226250/1.m3u8
#EXTINF:-1 ,黑莓电竞 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226262/1.m3u8
#EXTINF:-1 ,黑莓电竞 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226307/1.m3u8
#EXTINF:-1 ,NewTV中国功夫 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225951/1.m3u8
#EXTINF:-1 ,NewTV中国功夫 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226298/1.m3u8
#EXTINF:-1 ,NewTV中国功夫 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226321/1.m3u8
#EXTINF:-1 ,NewTV怡伴健康 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225919/1.m3u8
#EXTINF:-1 ,NewTV怡伴健康 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226306/1.m3u8
#EXTINF:-1 ,NewTV怡伴健康 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226327/1.m3u8
#EXTINF:-1 ,NewTV军事评论 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225926/1.m3u8
#EXTINF:-1 ,NewTV军事评论 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226303/1.m3u8
#EXTINF:-1 ,NewTV军事评论 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226326/1.m3u8
#EXTINF:-1 ,NewTV军旅剧场 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225923/1.m3u8
#EXTINF:-1 ,NewTV军旅剧场 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226301/1.m3u8
#EXTINF:-1 ,NewTV军旅剧场 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226324/1.m3u8
#EXTINF:-1 ,NewTV农业致富 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225930/1.m3u8
#EXTINF:-1 ,NewTV农业致富 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226304/1.m3u8
#EXTINF:-1 ,NewTV动作电影 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225915/1.m3u8
#EXTINF:-1 ,NewTV动作电影 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226288/1.m3u8
#EXTINF:-1 ,NewTV动作电影 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226329/1.m3u8
#EXTINF:-1 ,NewTV古装剧场 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225916/1.m3u8
#EXTINF:-1 ,NewTV古装剧场 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226300/1.m3u8
#EXTINF:-1 ,NewTV古装剧场 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226323/1.m3u8
#EXTINF:-1 ,NewTV家庭剧场 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225918/1.m3u8
#EXTINF:-1 ,NewTV家庭剧场 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226290/1.m3u8
#EXTINF:-1 ,NewTV家庭剧场 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226330/1.m3u8
#EXTINF:-1 ,NewTV惊悚悬疑 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225921/1.m3u8
#EXTINF:-1 ,NewTV惊悚悬疑 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226294/1.m3u8
#EXTINF:-1 ,NewTV惊悚悬疑 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226423/1.m3u8
#EXTINF:-1 ,NewTV明星大片 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225929/1.m3u8
#EXTINF:-1 ,NewTV明星大片 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226295/1.m3u8
#EXTINF:-1 ,NewTV明星大片 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226425/1.m3u8
#EXTINF:-1 ,NewTV武搏世界 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226171/1.m3u8
#EXTINF:-1 ,NewTV武搏世界 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226297/1.m3u8
#EXTINF:-1 ,NewTV武搏世界 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226320/1.m3u8
#EXTINF:-1 ,NewTV海外剧场 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225917/1.m3u8
#EXTINF:-1 ,NewTV海外剧场 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226302/1.m3u8
#EXTINF:-1 ,NewTV海外剧场 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226325/1.m3u8
#EXTINF:-1 ,NewTV潮妈辣婆 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225957/1.m3u8
#EXTINF:-1 ,NewTV潮妈辣婆 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226286/1.m3u8
#EXTINF:-1 ,NewTV炫舞未来 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226248/1.m3u8
#EXTINF:-1 ,NewTV爱情喜剧 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225913/1.m3u8
#EXTINF:-1 ,NewTV爱情喜剧 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226299/1.m3u8
#EXTINF:-1 ,NewTV爱情喜剧 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226322/1.m3u8
#EXTINF:-1 ,NewTV精品体育 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226287/1.m3u8
#EXTINF:-1 ,NewTV精品体育 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226328/1.m3u8
#EXTINF:-1 ,NewTV精品体育 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225922/1.m3u8
#EXTINF:-1 ,NewTV精品大剧 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225925/1.m3u8
#EXTINF:-1 ,NewTV精品大剧 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226291/1.m3u8
#EXTINF:-1 ,NewTV精品大剧 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226331/1.m3u8
#EXTINF:-1 ,NewTV精品纪录 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226293/1.m3u8
#EXTINF:-1 ,NewTV精品纪录 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226332/1.m3u8
#EXTINF:-1 ,NewTV超级体育 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226157/1.m3u8
#EXTINF:-1 ,NewTV超级体育 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226158/1.m3u8
#EXTINF:-1 ,NewTV超级体育 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226232/1.m3u8
#EXTINF:-1 ,NewTV超级体育 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226348/1.m3u8
#EXTINF:-1 ,NewTV超级电影 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226133/1.m3u8
#EXTINF:-1 ,NewTV超级电影 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226233/1.m3u8
#EXTINF:-1 ,NewTV超级电影 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226369/1.m3u8
#EXTINF:-1 ,NewTV超级电视剧 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225864/1.m3u8
#EXTINF:-1 ,NewTV超级电视剧 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226253/1.m3u8
#EXTINF:-1 ,NewTV超级电视剧 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226368/1.m3u8
#EXTINF:-1 ,NewTV超级综艺 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226127/1.m3u8
#EXTINF:-1 ,NewTV超级综艺 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226231/1.m3u8
#EXTINF:-1 ,NewTV超级综艺 CQ
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226370/1.m3u8
#EXTINF:-1 ,NewTV金牌综艺 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225920/1.m3u8
#EXTINF:-1 ,NewTV金牌综艺 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226296/1.m3u8
#EXTINF:-1 ,NewTV金牌综艺 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226347/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226374/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226375/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226377/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226378/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226379/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226380/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226381/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226382/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226394/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226395/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226396/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226397/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226398/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226393/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226392/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226391/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226390/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226372/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226373/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226376/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226383/1.m3u8
#EXTINF:-1 ,咪咕视频 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226384/1.m3u8
#EXTINF:-1 ,北京家有购物 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226429/1.m3u8
#EXTINF:-1 ,山西优购物 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226386/1.m3u8
#EXTINF:-1 ,中视购物 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226547/1.m3u8
#EXTINF:-1 ,央广购物 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226319/1.m3u8
#EXTINF:-1 ,央广购物 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226363/1.m3u8
#EXTINF:-1 ,江苏好享购物 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226312/1.m3u8
#EXTINF:-1 ,江苏好享购物 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226344/1.m3u8
#EXTINF:-1 ,湖南快乐购 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226341/1.m3u8
#EXTINF:-1 ,江西风尚购物 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225911/1.m3u8
#EXTINF:-1 ,江西风尚购物 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226305/1.m3u8
#EXTINF:-1 ,江西风尚购物 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226342/1.m3u8
#EXTINF:-1 ,江苏好享购物 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226313/1.m3u8
#EXTINF:-1 ,5GO美妆个护 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226387/1.m3u8
#EXTINF:-1 ,5GO美妆个护 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226389/1.m3u8
#EXTINF:-1 ,5GO服饰内衣 HD
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226388/1.m3u8
#EXTINF:-1 ,CCTV1 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226432/1.m3u8
#EXTINF:-1 ,CCTV1 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226338/1.m3u8
#EXTINF:-1 ,CCTV2 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225934/1.m3u8
#EXTINF:-1 ,CCTV2 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226457/1.m3u8
#EXTINF:-1 ,CCTV3 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226456/1.m3u8
#EXTINF:-1 ,CCTV4 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226156/1.m3u8
#EXTINF:-1 ,CCTV4 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226455/1.m3u8
#EXTINF:-1 ,CCTV5 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226454/1.m3u8
#EXTINF:-1 ,CCTV5 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226256/1.m3u8
#EXTINF:-1 ,CCTV5 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226257/1.m3u8
#EXTINF:-1 ,CCTV5 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226258/1.m3u8
#EXTINF:-1 ,CCTV5 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226259/1.m3u8
#EXTINF:-1 ,CCTV5 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226260/1.m3u8
#EXTINF:-1 ,CCTV5 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226261/1.m3u8
#EXTINF:-1 ,CCTV5 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226340/1.m3u8
#EXTINF:-1 ,CCTV5+ 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225938/1.m3u8
#EXTINF:-1 ,CCTV6 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226453/1.m3u8
#EXTINF:-1 ,CCTV7 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225863/1.m3u8
#EXTINF:-1 ,CCTV7 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226452/1.m3u8
#EXTINF:-1 ,CCTV8 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226451/1.m3u8
#EXTINF:-1 ,CCTV9 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226450/1.m3u8
#EXTINF:-1 ,CCTV9 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225865/1.m3u8
#EXTINF:-1 ,CCTV10 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225868/1.m3u8
#EXTINF:-1 ,CCTV10 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226449/1.m3u8
#EXTINF:-1 ,CCTV11 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225869/1.m3u8
#EXTINF:-1 ,CCTV11 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226448/1.m3u8
#EXTINF:-1 ,CCTV12 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225870/1.m3u8
#EXTINF:-1 ,CCTV12 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226447/1.m3u8
#EXTINF:-1 ,CCTV13 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226446/1.m3u8
#EXTINF:-1 ,CCTV13 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226159/1.m3u8
#EXTINF:-1 ,CCTV13 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226339/1.m3u8
#EXTINF:-1 ,CCTV14 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225872/1.m3u8
#EXTINF:-1 ,CCTV14 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226445/1.m3u8
#EXTINF:-1 ,CCTV14 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225928/1.m3u8
#EXTINF:-1 ,CCTV15 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225940/1.m3u8
#EXTINF:-1 ,CCTV15 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226444/1.m3u8
#EXTINF:-1 ,CCTV17 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226442/1.m3u8
#EXTINF:-1 ,CGTN 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226404/1.m3u8
#EXTINF:-1 ,CGTN 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225867/1.m3u8
#EXTINF:-1 ,CGTN 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226443/1.m3u8
#EXTINF:-1 ,CGTN纪录 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226403/1.m3u8
#EXTINF:-1 ,CGTN纪录 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225866/1.m3u8
#EXTINF:-1 ,中国教育1 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226417/1.m3u8
#EXTINF:-1 ,中国教育1 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226538/1.m3u8
#EXTINF:-1 ,中国教育1 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225905/1.m3u8
#EXTINF:-1 ,中国教育2 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226537/1.m3u8
#EXTINF:-1 ,中国教育4 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226362/1.m3u8
#EXTINF:-1 ,中国教育4 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226557/1.m3u8
#EXTINF:-1 ,东南卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226517/1.m3u8
#EXTINF:-1 ,东南卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225876/1.m3u8
#EXTINF:-1 ,东方卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226519/1.m3u8
#EXTINF:-1 ,东方卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226161/1.m3u8
#EXTINF:-1 ,云南卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226424/1.m3u8
#EXTINF:-1 ,云南卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225902/1.m3u8
#EXTINF:-1 ,云南卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226543/1.m3u8
#EXTINF:-1 ,内蒙古卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226415/1.m3u8
#EXTINF:-1 ,内蒙古卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226530/1.m3u8
#EXTINF:-1 ,内蒙古卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225891/1.m3u8
#EXTINF:-1 ,北京卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226436/1.m3u8
#EXTINF:-1 ,北京卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226160/1.m3u8
#EXTINF:-1 ,厦门卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226542/1.m3u8
#EXTINF:-1 ,吉林卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226426/1.m3u8
#EXTINF:-1 ,吉林卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226533/1.m3u8
#EXTINF:-1 ,吉林卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225886/1.m3u8
#EXTINF:-1 ,四川卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226407/1.m3u8
#EXTINF:-1 ,四川卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225898/1.m3u8
#EXTINF:-1 ,四川卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226523/1.m3u8
#EXTINF:-1 ,天津卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226489/1.m3u8
#EXTINF:-1 ,天津卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225899/1.m3u8
#EXTINF:-1 ,宁夏卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226413/1.m3u8
#EXTINF:-1 ,宁夏卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226528/1.m3u8
#EXTINF:-1 ,宁夏卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225892/1.m3u8
#EXTINF:-1 ,安徽卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225873/1.m3u8
#EXTINF:-1 ,安徽卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226490/1.m3u8
#EXTINF:-1 ,山东卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226487/1.m3u8
#EXTINF:-1 ,山西卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226410/1.m3u8
#EXTINF:-1 ,山西卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225895/1.m3u8
#EXTINF:-1 ,山西卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226531/1.m3u8
#EXTINF:-1 ,广东卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226535/1.m3u8
#EXTINF:-1 ,广西卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226408/1.m3u8
#EXTINF:-1 ,广西卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225879/1.m3u8
#EXTINF:-1 ,广西卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226534/1.m3u8
#EXTINF:-1 ,新疆卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226422/1.m3u8
#EXTINF:-1 ,新疆卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225901/1.m3u8
#EXTINF:-1 ,新疆卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226546/1.m3u8
#EXTINF:-1 ,江苏卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226491/1.m3u8
#EXTINF:-1 ,江苏卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225887/1.m3u8
#EXTINF:-1 ,江西卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226522/1.m3u8
#EXTINF:-1 ,江西卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225888/1.m3u8
#EXTINF:-1 ,河北卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226409/1.m3u8
#EXTINF:-1 ,河北卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225881/1.m3u8
#EXTINF:-1 ,河北卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226536/1.m3u8
#EXTINF:-1 ,河南卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225882/1.m3u8
#EXTINF:-1 ,河南卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226525/1.m3u8
#EXTINF:-1 ,浙江卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226492/1.m3u8
#EXTINF:-1 ,浙江卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225903/1.m3u8
#EXTINF:-1 ,海南卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226427/1.m3u8
#EXTINF:-1 ,海南卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225890/1.m3u8
#EXTINF:-1 ,湖北卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226520/1.m3u8
#EXTINF:-1 ,湖北卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225884/1.m3u8
#EXTINF:-1 ,湖南卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226493/1.m3u8
#EXTINF:-1 ,湖南卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226162/1.m3u8
#EXTINF:-1 ,甘肃卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226414/1.m3u8
#EXTINF:-1 ,甘肃卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225877/1.m3u8
#EXTINF:-1 ,甘肃卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226545/1.m3u8
#EXTINF:-1 ,西藏卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226428/1.m3u8
#EXTINF:-1 ,西藏卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225900/1.m3u8
#EXTINF:-1 ,西藏卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226527/1.m3u8
#EXTINF:-1 ,贵州卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226405/1.m3u8
#EXTINF:-1 ,贵州卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225880/1.m3u8
#EXTINF:-1 ,贵州卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226521/1.m3u8
#EXTINF:-1 ,辽宁卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226488/1.m3u8
#EXTINF:-1 ,辽宁卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226336/1.m3u8
#EXTINF:-1 ,辽宁卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225889/1.m3u8
#EXTINF:-1 ,重庆卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225904/1.m3u8
#EXTINF:-1 ,重庆卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226337/1.m3u8
#EXTINF:-1 ,重庆卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226518/1.m3u8
#EXTINF:-1 ,陕西卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226411/1.m3u8
#EXTINF:-1 ,陕西卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225896/1.m3u8
#EXTINF:-1 ,陕西卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226532/1.m3u8
#EXTINF:-1 ,青海卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226412/1.m3u8
#EXTINF:-1 ,青海卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225893/1.m3u8
#EXTINF:-1 ,青海卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226529/1.m3u8
#EXTINF:-1 ,黑龙江卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226524/1.m3u8
#EXTINF:-1 ,黑龙江卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225883/1.m3u8
#EXTINF:-1 ,山东教育卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226419/1.m3u8
#EXTINF:-1 ,山东教育卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225908/1.m3u8
#EXTINF:-1 ,山东教育卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226526/1.m3u8
#EXTINF:-1 ,广东南方卫视地面 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226540/1.m3u8
#EXTINF:-1 ,新疆兵团卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226541/1.m3u8
#EXTINF:-1 ,海南三沙卫视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226544/1.m3u8
#EXTINF:-1 ,北京卡酷少儿 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225907/1.m3u8
#EXTINF:-1 ,北京卡酷少儿 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226511/1.m3u8
#EXTINF:-1 ,北京国际 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226510/1.m3u8
#EXTINF:-1 ,北京影视 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226433/1.m3u8
#EXTINF:-1 ,北京文艺 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226435/1.m3u8
#EXTINF:-1 ,北京新闻 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226512/1.m3u8
#EXTINF:-1 ,北京生活 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226514/1.m3u8
#EXTINF:-1 ,北京科教 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226434/1.m3u8
#EXTINF:-1 ,北京财经 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226516/1.m3u8
#EXTINF:-1 ,北京青年 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226513/1.m3u8
#EXTINF:-1 ,上海哈哈炫动 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226421/1.m3u8
#EXTINF:-1 ,上海哈哈炫动 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225909/1.m3u8
#EXTINF:-1 ,广东嘉佳卡通 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226539/1.m3u8
#EXTINF:-1 ,江苏优漫卡通 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226420/1.m3u8
#EXTINF:-1 ,江苏优漫卡通 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225910/1.m3u8
#EXTINF:-1 ,湖南金鹰卡通 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225906/1.m3u8
#EXTINF:-1 ,CCTV中视购物 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226385/1.m3u8
#EXTINF:-1 ,北京家有购物 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225912/1.m3u8
#EXTINF:-1 ,北京家有购物 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226343/1.m3u8
#EXTINF:-1 ,聚鲨环球精选 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226311/1.m3u8
#EXTINF:-1 ,聚鲨环球精选 标清
http://221.179.217.9/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226345/1.m3u8

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,816 @@
#EXTM3U
#EXTINF:-1 logo="" group-title="" ,CCTV-1
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226226/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-1
http://112.50.243.8/PLTV/88888888/224/3221225922/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-1
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/8380729188125675257/1.m3u8?stbId=005301FF001589101611549359B92C46&channel-id=shvoolive&Contentid=8380729188125675257&mos=jbjhhzstsl&livemode=1&proto=7&version=1.0&owaccmark=8380729188125675257&owchid=shvoolive&owsid=9810361579531242552&AuthInfo=2TOfGIahP4HrGWrHbpJXVOhAZZf%2B%2BRvFCOimr7PCGr9K%2B8TGA2jGwhx%2FP%2B9zbDc6lyCFd7nUPkjV5yhX4M591q%2Bjz%2FVPZBSXzMBonFGRPep2MwYhKpmBifYKbDBIkjbE
#EXTINF:-1 logo="" group-title="" ,CCTV-2
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226230/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-2
http://112.50.243.8/PLTV/88888888/224/3221225923/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-2
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/9059700522149664924/1.m3u8?stbId=005301FF00158910000000212621A0DD&channel-id=shvoolive&Contentid=9059700522149664924&mos=jbjhhzstsl&livemode=1&proto=7&version=1.0&owaccmark=9059700522149664924&owchid=shvoolive&owsid=9176631579531299298&AuthInfo=2TOfGIahP4HrGWrHbpJXVOJq5SVvpOdgyIf7tzyuJqdYhL2umVWk4VA%2BiWro6vS%2FGYbJQ4PkF2oGSeOSrHR8kErWftutbDOGxkGeSWuC8HvRlxrsJs3srD2VEDgCtlA%2B
#EXTINF:-1 logo="" group-title="" ,CCTV-3
http://117.169.124.36:6610/ysten-businessmobile/live/cctv-3/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-3
http://223.110.241.130:6610/gitv/live1/G_CCTV-3-HQ/.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-3
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/7583927553614607925/1.m3u8?stbId=005301FF001589101611549359B9531C&channel-id=shvoolive&Contentid=7583927553614607925&mos=jbjhhzstsl&livemode=1&proto=7&version=1.0&owaccmark=7583927553614607925&owchid=shvoolive&owsid=4975061579531175360&AuthInfo=2TOfGIahP4HrGWrHbpJXVMtGfw%2Bi1RmSk6DRVWhSYHpPQhuPB3gB9HD2kYmj6h2ghYJH%2BZemKqNLOjvtazNyyelvyYAlIu0Li8OHrMDUf9T6xYM6NbVkTDG8Dli2hoZV
#EXTINF:-1 logo="" group-title="" ,CCTV-4
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226314/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-4
http://112.50.243.8/PLTV/88888888/224/3221225802/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-4
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/1000000002000031664/1.m3u8?channel-id=ystenlive&Contentid=1000000002000031664&livemode=1&stbId=00000250001B50800001B401420BC069&userToken=&usergroup=&version=1.0&owaccmark=1000000002000031664&owchid=ystenlive&owsid=4493204828580187354&AuthInfo=zmDeINsczUw%2bXOm6icTIplPJYM0PdJZ7nyJeCqAhmgD4h2W12vkSCe%2bw8qoQi5%2fj1BMuqFcEHMRAJlgQD47XRVqqHN3O4Si9Wv7MjAX%2b8AK0eHLMDmPByGK0oSB43DB7
#EXTINF:-1 logo="" group-title="" ,CCTV-5
http://223.110.241.130:6610/gitv/live1/G_CCTV-5-HQ/G_CCTV-5-HQ/
#EXTINF:-1 logo="" group-title="" ,CCTV-5
http://112.17.40.145/PLTV/88888888/224/3221226687/index.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-5
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/8134369599538150431/1.m3u8?stbId=005301FF001589101611549359B91F12&channel-id=shvoolive&Contentid=8134369599538150431&mos=jbjhhzstsl&livemode=1&proto=7&version=1.0&owaccmark=8134369599538150431&owchid=shvoolive&owsid=9856681579531396965&AuthInfo=2TOfGIahP4HrGWrHbpJXVHgbCHVZZF5UUv019%2FSsh88KJM1EuxjKGjHOptOCA%2B9qy7SUSUSlFcfpzdjGKbaNwXQPpC5RWUW%2BWPXxlyqlAmmp3eZqD0kAJRbC1HQjeP48
#EXTINF:-1 logo="" group-title="" ,CCTV-5+
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226225/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-5+
http://117.169.124.46:6410/ysten-businessmobile/live/hdcctv05plus/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-5+
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/1000000001000020505/1.m3u8?stbId=005301FF001589101611549359B92F26&channel-id=ystenlive&Contentid=1000000001000020505&mos=jbjhhzstsl&livemode=1&version=1.0&owaccmark=1000000001000020505&owchid=ystenlive&owsid=3007521579531929012&AuthInfo=2TOfGIahP4HrGWrHbpJXVPo6e%2BHF%2BrVo6xQQtyKDSuqu3lLj0NrV6tPDBIsVEpn3e3h8FJNoRfXgk2fJ%2B8A%2BC9FKxw7DogGmhnFazyXoBZJZPx01aV9Q%2Bs%2B%2FVnd4tZOQ
#EXTINF:-1 logo="" group-title="" ,CCTV-6
http://223.110.243.139/PLTV/3/224/3221225548/index.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-6
http://117.169.124.36:6610/ysten-businessmobile/live/cctv-6/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-6
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/6705015643145867202/1.m3u8?stbId=005301FF00158910000000212621A501&channel-id=shvoolive&Contentid=6705015643145867202&mos=jbjhhzstsl&livemode=1&proto=7&version=1.0&owaccmark=6705015643145867202&owchid=shvoolive&owsid=7641431579531463387&AuthInfo=2TOfGIahP4HrGWrHbpJXVGtyhHJPIcRRegoBYBxkr5gU2nvM3aYRu9pk6g1cfGsxitbm7ri6Y%2BkjLjny72IEdjBnss%2Faslq1wPHTyGHeHFYaAuxUDnXfdynLgAo%2FAhgd
#EXTINF:-1 logo="" group-title="" ,CCTV-7
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226234/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-7
http://112.50.243.8/PLTV/88888888/224/3221225927/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-7
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/9021776916726275968/1.m3u8?stbId=005303FF00010060000100E400EDD522&channel-id=shvoolive&Contentid=9021776916726275968&mos=jbjhhzstsl&livemode=1&proto=7&version=1.0&owaccmark=9021776916726275968&owchid=shvoolive&owsid=1117721579531499433&AuthInfo=dIshjDc3shv8ei%2BWF5V%2F4V6lf0HKCsUdpGR8CeY5ZvwycVHGQkBt0T4Mgr0s8ldsXtd9fDrW5osGZSl1tYFcN4xKXGPanSFGs4GR6kXBOyjKyNYEmAQ7njzvrMpDpEoy
#EXTINF:-1 logo="" group-title="" ,CCTV-8
http://117.169.124.36:6610/ysten-businessmobile/live/cctv-8/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-8
http://223.110.247.161:6610/cntv/live1/HD-2500k-1080P-cctv8/HD-2500k-1080P-cctv8
#EXTINF:-1 logo="" group-title="" ,CCTV-8
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/6718199708332952607/1.m3u8?stbId=005303FF00010060000100E400EDD522&channel-id=shvoolive&Contentid=6718199708332952607&mos=jbjhhzstsl&livemode=1&proto=7&version=1.0&owaccmark=6718199708332952607&owchid=shvoolive&owsid=5415971579531545952&AuthInfo=dIshjDc3shv8ei%2BWF5V%2F4V6lf0HKCsUdpGR8CeY5ZvwhPD49%2ByoYvwp35mAdL%2Fiv3IhMa6%2BWOwlWxbCOH9ParUjWZpISKyxZZPoQtekRP1dMl%2BCp9T%2BIEdj1ckDKKfLV
#EXTINF:-1 logo="" group-title="" ,CCTV-9
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226236/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-9
http://112.50.243.8/PLTV/88888888/224/3221225820/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-9
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/1000000001000014583/1.m3u8?stbId=005303FF00010060000100E400EDD522&channel-id=ystenlive&Contentid=1000000001000014583&mos=jbjhhzstsl&livemode=1&version=1.0&owaccmark=1000000001000014583&owchid=ystenlive&owsid=7167961579531601678&AuthInfo=dIshjDc3shv8ei%2BWF5V%2F4V6lf0HKCsUdpGR8CeY5Zvyu3lLj0NrV6tPDBIsVEpn34sImpRHeOmdxmKUDLs1%2BcZ4JMWbvuFdY7IsuWCFdW392C%2BvFQjyH4LwQq4yRWFvT
#EXTINF:-1 logo="" group-title="" ,CCTV-10
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226227/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-10
http://ott.fj.chinamobile.com/PLTV/88888888/224/3221225814/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-10
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/5505774374187257095/1.m3u8?stbId=005301FF001589101611549359B928C9&channel-id=shvoolive&Contentid=5505774374187257095&mos=jbjhhzstsl&livemode=1&proto=7&version=1.0&owaccmark=5505774374187257095&owchid=shvoolive&owsid=1848841579531638041&AuthInfo=2TOfGIahP4HrGWrHbpJXVO9dhnpYCD6yZADsu%2BE3e1z0TmJ04Et2oauQoqLXutIbfy6yerDX1KNDnX4OGB2ZvZf3QlZMt7Oj%2B5HhHlpl0nNoTgXky6K2iYWb1eX3xCek
#EXTINF:-1 logo="" group-title="" ,CCTV-11
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226315/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-11
http://ott.fj.chinamobile.com/PLTV/88888888/224/3221225815/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-11
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/1000000002000019789/1.m3u8?stbId=005301FF001589101611549359B96031&channel-id=ystenlive&Contentid=1000000002000019789&mos=jbjhhzstsl&livemode=1&version=1.0&owaccmark=1000000002000019789&owchid=ystenlive&owsid=5070431579531812673&AuthInfo=2TOfGIahP4HrGWrHbpJXVDOD3a2KOxiKxQ3OD0iK1ACjKNizoRlMOkuvsTe1URoeoCCSRcfgLDg%2FiG7BT3%2BNlEIMer5%2BuzAqyByddFhoQVMoMRKerLoSM5qM9Az%2Bea7u
#EXTINF:-1 logo="" group-title="" ,CCTV-12
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226228/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-12
http://112.50.243.8/PLTV/88888888/224/3221225816/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-12
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/6417486185316863297/1.m3u8?stbId=005301FF001589101611549359B92F26&channel-id=shvoolive&Contentid=6417486185316863297&mos=jbjhhzstsl&livemode=1&proto=7&version=1.0&owaccmark=6417486185316863297&owchid=shvoolive&owsid=9153671579531878340&AuthInfo=2TOfGIahP4HrGWrHbpJXVPo6e%2BHF%2BrVo6xQQtyKDSurAX3PB%2FnVIr3xix20cl8xPdgGi1rpRM1DYWZnyEDgQSmvEeryqwyIWUPNfICRzKqmuU3YFsCIaBI4jHMacn12g
#EXTINF:-1 logo="" group-title="" ,CCTV-13
http://223.110.241.130:6610/gitv/live1/G_CCTV-13-HQ/.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-13
http://223.110.247.161:6610/gitv/live1/G_CCTV-13-HQ/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-14
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226229/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-14
http://117.148.187.37/PLTV/88888888/224/3221226126/index.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-14
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/5554452538079056392/1.m3u8?stbId=005301FF001589101611549359B92F26&channel-id=shvoolive&Contentid=5554452538079056392&mos=jbjhhzstsl&livemode=1&proto=7&version=1.0&owaccmark=5554452538079056392&owchid=shvoolive&owsid=1386521579531934459&AuthInfo=2TOfGIahP4HrGWrHbpJXVPo6e%2BHF%2BrVo6xQQtyKDSuraKH2KM768ZNQcj3PAdtOdSSlj5RtbM3onnzvUC8Txgj%2BRYROAJoRcjfZ4YOPHclFuVVM2CqA1FqqLFpU5t7y%2B
#EXTINF:-1 logo="" group-title="" ,CCTV-15
http://111.13.111.167/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226333/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-15
http://ott.fj.chinamobile.com/PLTV/88888888/224/3221225818/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-15
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/1000000002000008163/1.m3u8?stbId=005301FF00158910000000212621B0EF&channel-id=ystenlive&Contentid=1000000002000008163&mos=jbjhhzstsl&livemode=1&version=1.0&owaccmark=1000000002000008163&owchid=ystenlive&owsid=8159411579531758075&AuthInfo=2TOfGIahP4HrGWrHbpJXVCfBjPWQNL5VnKaoeN%2FnWIWjKNizoRlMOkuvsTe1URoev67GfI1oIH4w2vVjbaVRzv3Enx1RBixVDhCnZtdnlMixFs9te0%2Bpvr2OpfN5d0VT
#EXTINF:-1 logo="" group-title="" ,CCTV-17
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226318/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-17
http://ott.fj.chinamobile.com/PLTV/88888888/224/3221226990/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-17
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/1000000005000056836/1.m3u8?stbId=005301FF001589101611549359B9325E&channel-id=ystenlive&Contentid=1000000005000056836&mos=jbjhhzstsl&livemode=1&version=1.0&owaccmark=1000000005000056836&owchid=ystenlive&owsid=9164551579532003738&AuthInfo=2TOfGIahP4HrGWrHbpJXVGO0L8hMYc%2BQSE26r5BPa9COQyZOTKfJypXfULnzEX8ov4wHfTVtjr5%2BH1gBPIHFdZVbPTqDjqKmcARryOXhfL7mPOk1Na7QiYpdWHg0hz19
#EXTINF:-1 logo="" group-title="" ,CCTV-4K
http://112.17.40.12/PLTV/88888888/224/3221226758/1.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-4K
http://112.17.40.140/PLTV/88888888/224/3221226758/index.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-4K
http://39.134.176.148/PLTV/88888888/224/3221226758/index.m3u8
#EXTINF:-1 logo="" group-title="" ,CCTV-4K
http://117.148.187.83/PLTV/88888888/224/3221226758/index.m3u8
#EXTINF:-1 logo="" group-title="" ,纯享4K源码1
http://112.50.243.8/PLTV/88888888/224/3221226825/1.m3u8
#EXTINF:-1 logo="" group-title="" ,纯享4K源码2
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn/000000001000/1000000004000011651/index.m3u8?channel-id=ystenlive&Contentid=1000000004000011651&livemode=1&authCode=3a&stbId=8A3603DD004735200000049573C4E39B&version=1.0&owaccmark=1000000004000011651&owchid=ystenlive&owsid=6721581571186720581&AuthInfo=QejU%2ByFkapDLEHjn7Vi7Bsh98cz5RjIeOqbMi0Qqlame2O8Id%2BgCUUdS4cJUD1ieqKIx8wFJ0pPdF5P8MGRzRrjFLuuRCIZ2D2ha%2Fr9iiM%2BAnSOfyc4s5zWrjzUdrEbf
#EXTINF:-1 logo="" group-title="" ,百事4K频道
http://112.17.40.145/PLTV/88888888/224/3221226718/index.m3u8
#EXTINF:-1 logo="" group-title="" ,凤凰资讯
http://112.17.40.140/PLTV/88888888/224/3221226491/index.m3u8
#EXTINF:-1 logo="" group-title="" ,凤凰资讯
http://117.169.124.37:6610/ysten-businessmobile/live/fhzixun/1.m3u8
#EXTINF:-1 logo="" group-title="" ,凤凰中文
http://117.169.124.37:6610/ysten-businessmobile/live/fhchinese/1.m3u8
#EXTINF:-1 logo="" group-title="" ,凤凰中文
http://117.169.120.138:8080/live/fhchinese/index.m3u8
#EXTINF:-1 logo="" group-title="" ,北京卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226224/1.m3u8
#EXTINF:-1 logo="" group-title="" ,北京卫视
http://111.40.205.87/PLTV/88888888/224/3221225728/index.m3u8
#EXTINF:-1 logo="" group-title="" ,天津卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226246/1.m3u8
#EXTINF:-1 logo="" group-title="" ,天津卫视
http://112.17.40.140/PLTV/88888888/224/3221226412/index.m3u8
#EXTINF:-1 logo="" group-title="" ,河北卫视超清1
http://223.110.245.149/ott.js.chinamobile.com/PLTV/3/224/3221225840/index.m3u8
#EXTINF:-1 logo="" group-title="" ,河北卫视超清2
http://223.110.247.161:6610/gitv/live1/G_HEBEI/G_HEBEI
#EXTINF:-1 logo="" group-title="" ,东方卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226237/1.m3u8
#EXTINF:-1 logo="" group-title="" ,东方卫视
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/1000000001000005866/1.m3u8?stbId=005301FF001589101611549359B9656A&channel-id=ystenlive&Contentid=1000000001000005866&mos=jbjhhzstsl&livemode=1&version=1.0&owaccmark=1000000001000005866&owchid=ystenlive&owsid=6312751579529792174&AuthInfo=2TOfGIahP4HrGWrHbpJXVB51rvh1oS437liFJd26gOOu3lLj0NrV6tPDBIsVEpn3OZnoLrZwa8b70lofXkPptSAmb4xhM2tKBJ0VUyBQsWCEzNrIVXcTeS%2F12UFJevdi
#EXTINF:-1 logo="" group-title="" ,湖南卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226241/1.m3u8
#EXTINF:-1 logo="" group-title="" ,湖南卫视
http://112.17.40.140/PLTV/88888888/224/3221226553/index.m3u8
#EXTINF:-1 logo="" group-title="" ,浙江卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226247/1.m3u8
#EXTINF:-1 logo="" group-title="" ,浙江卫视
http://223.110.243.173/PLTV/3/224/3221227215/index.m3u8
#EXTINF:-1 logo="" group-title="" ,江苏卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226242/1.m3u8
#EXTINF:-1 logo="" group-title="" ,江苏卫视
http://112.17.40.140/PLTV/88888888/224/3221226414/index.m3u8
#EXTINF:-1 logo="" group-title="" ,东南卫视
http://117.169.124.37:6610/ysten-businessmobile/live/dongnanstv/yst.m3u8
#EXTINF:-1 logo="" group-title="" ,东南卫视
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/1000000002000009263/1.m3u8?channel-id=ystenlive&Contentid=1000000002000009263&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000009263&owchid=ystenlive&owsid=1106497909461310172&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhM1XYZKCRYYY%2ff447%2bzETLijqfFgMTSA9x9T2lf3pyhagZIF%2fdE1lc49i65lODYA%2f
#EXTINF:-1 logo="" group-title="" ,山东卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226308/1.m3u8
#EXTINF:-1 logo="" group-title="" ,山东卫视
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/1000000001000012807/1.m3u8?channel-id=ystenlive&Contentid=1000000001000012807&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000012807&owchid=ystenlive&owsid=1106497909461291586&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaR3cBsIsjm7UHdGO3a4NjD1C4TiYtYt%2by66pvMI%2bkz57DAkgjzetftIzpJRR8RWa0K
#EXTINF:-1 logo="" group-title="" ,湖北卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226310/1.m3u8
#EXTINF:-1 logo="" group-title="" ,湖北卫视
http://223.110.243.171/PLTV/3/224/3221227211/index.m3u8
#EXTINF:-1 logo="" group-title="" ,安徽卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226223/1.m3u8
#EXTINF:-1 logo="" group-title="" ,安徽卫视
http://223.110.247.161:6610/gitv/live1/G_ANHUI-CQ/G_ANHUI-CQ
#EXTINF:-1 logo="" group-title="" ,广东卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226238/1.m3u8
#EXTINF:-1 logo="" group-title="" ,广东卫视
http://112.17.40.140/PLTV/88888888/224/3221226225/index.m3u8
#EXTINF:-1 logo="" group-title="" ,深圳卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226245/1.m3u8
#EXTINF:-1 logo="" group-title="" ,深圳卫视
http://223.110.243.171/PLTV/3/224/3221227217/index.m3u8
#EXTINF:-1 logo="" group-title="" ,辽宁卫视
http://ott.fj.chinamobile.com/PLTV/88888888/224/3221225947/1.m3u8
#EXTINF:-1 logo="" group-title="" ,辽宁卫视
http://223.110.245.145/ott.js.chinamobile.com/PLTV/3/224/3221227410/index.m3u8
#EXTINF:-1 logo="" group-title="" ,龙江卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226239/1.m3u8
#EXTINF:-1 logo="" group-title="" ,龙江卫视
http://112.17.40.140/PLTV/88888888/224/3221226555/index.m3u8
#EXTINF:-1 logo="" group-title="" ,吉林卫视
http://116.199.5.52:8114/00000000/index.m3u8?&Fsv_ctype=LIVES&Fsv_otype=1&FvSeid=5abd1660af1babb4&Fsv_filetype=1&Fsv_ctype=LIVES&Fsv_cid=0&Fsv_chan_hls_se_idx=25&Fsv_rate_id=0&Fsv_SV_PARAM1=0&Fsv_ShiftEnable=0&Fsv_ShiftTsp=0&Provider_id=&Pcontent_id=&Fsv_CMSID=&Fsv_otype=1
#EXTINF:-1 logo="" group-title="" ,吉林卫视
http://223.110.247.161:6610/gitv/live1/G_JILIN/G_JILIN
#EXTINF:-1 logo="" group-title="" ,江西卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226243/1.m3u8
#EXTINF:-1 logo="" group-title="" ,江西卫视
http://112.17.40.140/PLTV/88888888/224/3221226557/index.m3u8
#EXTINF:-1 logo="" group-title="" ,四川卫视
http://ott.fj.chinamobile.com/PLTV/88888888/224/3221227006/1.m3u8
#EXTINF:-1 logo="" group-title="" ,四川卫视
http://223.110.247.161:6610/gitv/live1/SCWS/SCWS
#EXTINF:-1 logo="" group-title="" ,重庆卫视
http://ott.fj.chinamobile.com/PLTV/88888888/224/3221225949/1.m3u8
#EXTINF:-1 logo="" group-title="" ,重庆卫视
http://ivi.bupt.edu.cn/hls/cqhd.m3u8
#EXTINF:-1 logo="" group-title="" ,厦门卫视
http://ott.fj.chinamobile.com/PLTV/88888888/224/3221226781/1.m3u8
#EXTINF:-1 logo="" group-title="" ,厦门卫视
http://223.110.247.161:6610/gitv/live1/G_XIAMEN/G_XIAMEN
#EXTINF:-1 logo="" group-title="" ,河南卫视
http://116.199.5.52:8114/00000000/index.m3u8?&Fsv_ctype=LIVES&Fsv_otype=1&FvSeid=5abd1660af1babb4&Fsv_filetype=1&Fsv_ctype=LIVES&Fsv_cid=0&Fsv_chan_hls_se_idx=19&Fsv_rate_id=0&Fsv_SV_PARAM1=0&Fsv_ShiftEnable=0&Fsv_ShiftTsp=0&Provider_id=&Pcontent_id=&Fsv_CMSID=&Fsv_otype=1
#EXTINF:-1 logo="" group-title="" ,河南卫视超清2
http://223.110.245.157/ott.js.chinamobile.com/PLTV/3/224/3221225815/index.m3u8
#EXTINF:-1 logo="" group-title="" ,贵州卫视
http://116.199.5.52:8114/00000000/index.m3u8?&Fsv_ctype=LIVES&Fsv_otype=1&FvSeid=5abd1660af1babb4&Fsv_filetype=1&Fsv_ctype=LIVES&Fsv_cid=0&Fsv_chan_hls_se_idx=41&Fsv_rate_id=0&Fsv_SV_PARAM1=0&Fsv_ShiftEnable=0&Fsv_ShiftTsp=0&Provider_id=&Pcontent_id=&Fsv_CMSID=&Fsv_otype=1
#EXTINF:-1 logo="" group-title="" ,贵州卫视超清2
http://223.110.245.149/ott.js.chinamobile.com/PLTV/3/224/3221225787/index.m3u8
#EXTINF:-1 logo="" group-title="" ,海南卫视超清1
http://hnhbxww.com/live.php?http://mlive1.91kds.cn/b9/hitv.m3u8?id=lywshd
#EXTINF:-1 logo="" group-title="" ,海南卫视
http://112.50.243.8/PLTV/88888888/224/3221225855/1.m3u8
#EXTINF:-1 logo="" group-title="" ,甘肃卫视超清1
http://116.199.5.52:8114/00000000/index.m3u8?&Fsv_ctype=LIVES&Fsv_otype=1&FvSeid=5abd1660af1babb4&Fsv_filetype=1&Fsv_ctype=LIVES&Fsv_cid=0&Fsv_chan_hls_se_idx=142&Fsv_rate_id=0&Fsv_SV_PARAM1=0&Fsv_ShiftEnable=0&Fsv_ShiftTsp=0&Provider_id=&Pcontent_id=&Fsv_CMSID=&Fsv_otype=1
#EXTINF:-1 logo="" group-title="" ,甘肃卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225877/1.m3u8
#EXTINF:-1 logo="" group-title="" ,青海卫视超清1
http://116.199.5.52:8114/00000000/index.m3u8?&Fsv_ctype=LIVES&Fsv_otype=1&FvSeid=5abd1660af1babb4&Fsv_filetype=1&Fsv_ctype=LIVES&Fsv_cid=0&Fsv_chan_hls_se_idx=206&Fsv_rate_id=0&Fsv_SV_PARAM1=0&Fsv_ShiftEnable=0&Fsv_ShiftTsp=0&Provider_id=&Pcontent_id=&Fsv_CMSID=&Fsv_otype=1
#EXTINF:-1 logo="" group-title="" ,青海卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225893/1.m3u8
#EXTINF:-1 logo="" group-title="" ,云南卫视超清1
http://223.110.245.159/ott.js.chinamobile.com/PLTV/3/224/3221225838/index.m3u8
#EXTINF:-1 logo="" group-title="" ,云南卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225902/1.m3u8
#EXTINF:-1 logo="" group-title="" ,陕西卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225896/1.m3u8
#EXTINF:-1 logo="" group-title="" ,陕西卫视
http://223.110.247.161:6610/gitv/live1/G_SHANXI/G_SHANXI
#EXTINF:-1 logo="" group-title="" ,宁夏卫视超清1
http://223.110.245.151/ott.js.chinamobile.com/PLTV/3/224/3221225842/index.m3u8
#EXTINF:-1 logo="" group-title="" ,宁夏卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225892/1.m3u8
#EXTINF:-1 logo="" group-title="" ,内蒙卫视超清1
http://223.110.245.161/ott.js.chinamobile.com/PLTV/3/224/3221225836/index.m3u8
#EXTINF:-1 logo="" group-title="" ,内蒙卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225891/1.m3u8
#EXTINF:-1 logo="" group-title="" ,西藏卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225900/1.m3u8
#EXTINF:-1 logo="" group-title="" ,西藏卫视
http://223.110.247.161:6610/gitv/live1/G_XIZANG/G_XIZANG
#EXTINF:-1 logo="" group-title="" ,山西卫视
http://223.110.247.161:6610/gitv/live1/SXWS/SXWS
#EXTINF:-1 logo="" group-title="" ,山西卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225895/1.m3u8
#EXTINF:-1 logo="" group-title="" ,广西卫视
http://112.50.243.8/PLTV/88888888/224/3221225836/1.m3u8
#EXTINF:-1 logo="" group-title="" ,广西卫视
http://223.110.247.161:6610/gitv/live1/GXWS/GXWS
#EXTINF:-1 logo="" group-title="" ,新疆卫视
http://223.110.247.161:6610/gitv/live1/G_XINJIANG/G_XINJIANG
#EXTINF:-1 logo="" group-title="" ,新疆卫视
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225901/1.m3u8
#EXTINF:-1 logo="" group-title="" ,南方卫视高清
http://223.110.247.161:6610/gitv/live1/G_NANFANG/G_NANFANG
#EXTINF:-1 logo="" group-title="" ,兵团卫视高清
http://223.110.247.161:6610/gitv/live1/G_BINGTUAN/G_BINGTUAN
#EXTINF:-1 logo="" group-title="" ,延边卫视高清
http://223.110.247.161:6610/gitv/live1/G_YANBIAN/G_YANBIAN
#EXTINF:-1 logo="" group-title="" ,农林卫视高清
http://223.110.247.161:6610/gitv/live1/G_NONGLIN/G_NONGLIN
#EXTINF:-1 logo="" group-title="" ,康巴卫视高清
http://223.110.247.161:6610/gitv/live1/G_KANGBA/G_KANGBA
#EXTINF:-1 logo="" group-title="" ,安多卫视高清
http://223.110.247.161:6610/gitv/live1/G_ANDUO/G_ANDUO
#EXTINF:-1 logo="" group-title="" ,高清影视1台
http://112.50.243.8/PLTV/88888888/224/3221226736/1.m3u8
#EXTINF:-1 logo="" group-title="" ,高清影视2台
http://112.50.243.8/PLTV/88888888/224/3221225881/1.m3u8
#EXTINF:-1 logo="" group-title="" ,高清影视3台
http://112.50.243.8/PLTV/88888888/224/3221226708/1.m3u8
#EXTINF:-1 logo="" group-title="" ,高清影视4台
http://112.50.243.8/PLTV/88888888/224/3221226712/1.m3u8
#EXTINF:-1 logo="" group-title="" ,高清影视5台
http://112.50.243.8/PLTV/88888888/224/3221225893/1.m3u8
#EXTINF:-1 logo="" group-title="" ,高清影视6台
http://112.50.243.8/PLTV/88888888/224/3221226692/1.m3u8
#EXTINF:-1 logo="" group-title="" ,高清影视7台
http://112.50.243.8/PLTV/88888888/224/3221226754/1.m3u8
#EXTINF:-1 logo="" group-title="" ,高清影视8台
http://112.17.40.145/PLTV/88888888/224/3221226608/index.m3u8
#EXTINF:-1 logo="" group-title="" ,高清影视9台
http://112.17.40.145/PLTV/88888888/224/3221226606/index.m3u8
#EXTINF:-1 logo="" group-title="" ,高清影视10台
http://112.17.40.145/PLTV/88888888/224/3221226360/index.m3u8
#EXTINF:-1 logo="" group-title="" ,高清动画11台
http://112.50.243.8/PLTV/88888888/224/3221226732/1.m3u8
#EXTINF:-1 logo="" group-title="" ,高清动画12台
http://112.50.243.8/PLTV/88888888/224/3221226741/1.m3u8
#EXTINF:-1 logo="" group-title="" ,高清动漫13台
http://112.50.243.8/PLTV/88888888/224/3221226743/1.m3u8
#EXTINF:-1 logo="" group-title="" ,高清影视14台
http://ivi.bupt.edu.cn/hls/chchd.m3u8
#EXTINF:-1 logo="" group-title="" ,东方影视高清
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/5000000010000032212/index.m3u8?channel-id=bestzb&Contentid=5000000010000032212&livemode=1&authCode=3a&stbId=005301FF00158910000000212621B1F2&version=1.0&owaccmark=5000000010000032212&owchid=bestzb&owsid=2093431579530013084&AuthInfo=2TOfGIahP4HrGWrHbpJXVC70y2PVjmhUubUspsIcpqbPt3njBIzWc%2Fam35vTsnvWPWGkzpZH3A16MnnNHKq3GxKdDnIii87ggbdt%2FwooaevY4cuAtO0vMGGwXuHO%2Biok
#EXTINF:-1 logo="" group-title="" ,纪实人文高清
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/1000000001000010606/1.m3u8?stbId=005301FF001589101611549359B92C46&channel-id=ystenlive&Contentid=1000000001000010606&mos=jbjhhzstsl&livemode=1&version=1.0&owaccmark=1000000001000010606&owchid=ystenlive&owsid=5474771579530255373&AuthInfo=2TOfGIahP4HrGWrHbpJXVOhAZZf%2B%2BRvFCOimr7PCGr%2Bu3lLj0NrV6tPDBIsVEpn3QZdNn969VxaznG4qedKIxPvWqo6nkyvxK0SnJLSEP%2FF4Wxm5gCchMH9VO%2BhWyofF
#EXTINF:-1 logo="" group-title="" ,上海外语高清
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/5000000010000030951/index.m3u8?channel-id=bestzb&Contentid=5000000010000030951&livemode=1&authCode=3a&stbId=005303FF0002189018212C1875540E0E&version=1.0&owaccmark=5000000010000030951&owchid=bestzb&owsid=5275181579530295306&AuthInfo=%2FcylGCbqLdFJuk2wbal8%2B%2FwyUq8npJ58oVaJUzBhF9PPt3njBIzWc%2Fam35vTsnvW6JhDYuiodydLTeMKHTm0L2zYfQnHdO1Iw0VU34c0CqRBZ788c%2Fr%2FVjoxJ5D0QVcG
#EXTINF:-1 logo="" group-title="" ,第一财经高清
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/5000000010000027146/index.m3u8?channel-id=bestzb&Contentid=5000000010000027146&livemode=1&authCode=3a&stbId=005301FF00158910000000212621B272&version=1.0&owaccmark=5000000010000027146&owchid=bestzb&owsid=2047321579530436324&AuthInfo=2TOfGIahP4HrGWrHbpJXVGQxu5HMK%2BIheH%2BppAJUFQfPt3njBIzWc%2Fam35vTsnvW%2Bh72VHwN1p1HFLVpAXsbYI0I2J%2FhJvUENkmrKWvJBWHflOM1WROOndOSHiRR8ilK
#EXTINF:-1 logo="" group-title="" ,冬奥纪实高清
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/1000000001000001910/1.m3u8?stbId=005301FF001589101611549359B93B82&channel-id=ystenlive&Contentid=1000000001000001910&mos=jbjhhzstsl&livemode=1&version=1.0&owaccmark=1000000001000001910&owchid=ystenlive&owsid=6204131579532167784&AuthInfo=2TOfGIahP4HrGWrHbpJXVB3TJIR2vriLvDYSdNB63hOu3lLj0NrV6tPDBIsVEpn3tQTMvk8FXaCJplQYdE%2FaRS95e%2BAlAk4PMAmwzVuVNoUAyrBQjkJ2X3eTsBSYe8ta
#EXTINF:-1 logo="" group-title="" ,北京纪实高清
http://112.50.243.8/PLTV/88888888/224/3221225944/1.m3u8
#EXTINF:-1 logo="" group-title="" ,五星体育高清
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/5000000010000017540/index.m3u8?channel-id=bestzb&Contentid=5000000010000017540&livemode=1&stbId=004003FF0017301364008422F151297C&userToken=22da83031e59d012e61af366ad30871e02vv&usergroup=g02020000000&version=1.0&owaccmark=5000000010000017540&owchid=bestzb&owsid=4493204831455228383&AuthInfo=N%2biD7%2bHgi9LcszGFRGa51uAqiHNpkS5d0%2fEIXqMyy8J6GNpZ%2bE47AWi696WsOzmj7u8gynrDaeemmd3KgHvW7jm8s%2fkPykV1GmMdpMkc7doBK82U9CVAXx34x1%2fYjl4A
#EXTINF:-1 logo="" group-title="" ,生活时尚高清
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/8538616372715313491/index.m3u8?channel-id=bestzb&Contentid=8538616372715313491&livemode=1&authCode=3a&stbId=005301FF001589101611549359B95001&version=1.0&owaccmark=8538616372715313491&owchid=bestzb&owsid=9384351579529030195&AuthInfo=2TOfGIahP4HrGWrHbpJXVMf9GKsKSOxo3z9oMCSFNzfvIfeh1IeRuYy1UKStuEqgLEq69vAaIVm8yJ1Bv9Ubfc12nlc%2FSga%2FjQ8%2F3mwUrQxWfqFwePA0JQWqj9IZCH10
#EXTINF:-1 logo="" group-title="" ,五星体育高清
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/4612233678249154892/index.m3u8?channel-id=bestzb&Contentid=4612233678249154892&livemode=1&authCode=3a&stbId=005301FF001589101611549359B95001&version=1.0&owaccmark=4612233678249154892&owchid=bestzb&owsid=1779721579529023740&AuthInfo=2TOfGIahP4HrGWrHbpJXVMf9GKsKSOxo3z9oMCSFNzd9hkuYOs2VB84It64D80NJi4eXOKW3GuNNz9Fm%2FKg8xywLT7mM729fPyVIkI9Esx1ZNxN%2F6BsKFZl0vwsL8fqK
#EXTINF:-1 logo="" group-title="" ,上海都市高清
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/6789517052815334336/index.m3u8?channel-id=bestzb&Contentid=6789517052815334336&livemode=1&authCode=3a&stbId=005301FF001589101611549359B94488&version=1.0&owaccmark=6789517052815334336&owchid=bestzb&owsid=3529791579529328057&AuthInfo=2TOfGIahP4HrGWrHbpJXVG%2BEERpEQIU%2FdtpJfuYgRAZD6434P427oxBuLbFRCJn4JFqerLYeYbaWyhUzdTsyRsJkPPbC14Prjj67uIG3APHUBp7pkUo1m6jlajTP1QwT
#EXTINF:-1 logo="" group-title="" ,风尚音乐高清
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/5529729098703832176/z.m3u8?authCode=07110409322147352675&stbId=005301FF001589101611549359B92801&Contentid=5529729098703832176&mos=jbjhhzstsl&livemode=1&channel-id=wasusyt&version=1.0&owaccmark=5529729098703832176&owchid=wasusyt&owsid=3246571579530794909&AuthInfo=2TOfGIahP4HrGWrHbpJXVM8tIjUabzvkQw3IFgi64wePjBmkxCliyfsNixolB3vk0fJDbsUHwM4ZMkLD2%2FuFtJVT%2FBKMSil0ujuXkiQNzBbZ5U6pNSIVxD4YjUWtTd0X
#EXTINF:-1 logo="" group-title="" ,精品剧场高清
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/8230197131234717902/z.m3u8?authCode=07110409322147352675&stbId=005303FF000218901813C88F26C4CD9A&Contentid=8230197131234717902&mos=jbjhhzstsl&livemode=1&channel-id=wasusyt&version=1.0&owaccmark=8230197131234717902&owchid=wasusyt&owsid=7188071579532237669&AuthInfo=%2FcylGCbqLdFJuk2wbal8%2B0%2FXYYDGLpWdBEstTIR1PqI%2FOctjqHm7uarF9hdI%2FegylabK%2B2Kjwr6YmfYB%2B0U4%2FVMlD9%2BUH6H5BTAiFyR%2BGJWsoX2Ruwovu0ZMFHxX6702
#EXTINF:-1 logo="" group-title="" ,亚洲影院高清
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/5841816227539527643/z.m3u8?authCode=07110409322147352675&stbId=005301FF001589101611549359B93B82&Contentid=5841816227539527643&mos=jbjhhzstsl&livemode=1&channel-id=wasusyt&version=1.0&owaccmark=5841816227539527643&owchid=wasusyt&owsid=1431411579532174401&AuthInfo=2TOfGIahP4HrGWrHbpJXVB3TJIR2vriLvDYSdNB63hPyA9qk2%2BTKLoJATlqPnb0MXm7l%2FiHeo2whk7VLomWH7w5GNiHxzOX6JECr7x0TLTmTY895HMYgWz4jiaElB1nN
#EXTINF:-1 logo="" group-title="" ,上海都市高清
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/6789517052815334336/index.m3u8?channel-id=bestzb&Contentid=6789517052815334336&livemode=1&stbId=004003FF0041848666008422F155939C&userToken=22da83031e59d012e61af366ad30871e02vv&usergroup=g02020000000&version=1.0&owaccmark=6789517052815334336&owchid=bestzb&owsid=4493204831455331826&AuthInfo=zI7Ouajzmvoo0pGb64%2fbgLE2RFvrprmD90MrWZVi%2bL3HPQnDcXoFLI6SzbzVwjU3sNLudmh14A4CtBNHjWANkrrgGz1D3dYfcKudsIt%2bpr%2fjXiUqpuQHmAckVE8okPuA
#EXTINF:-1 logo="" group-title="" ,上海ICS高清
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/6032059665143203976/index.m3u8?channel-id=bestzb&Contentid=6032059665143203976&livemode=1&authCode=3a&stbId=8A3603DD004735200000049573C4E39B&version=1.0&owaccmark=6032059665143203976&owchid=bestzb&owsid=8862091567733940095&AuthInfo=QejU%2ByFkapDLEHjn7Vi7Bsh98cz5RjIeOqbMi0QqlalAzdP65EW1KAjwws9eqr8onRppCkq5lhXK46o%2BFK3dV%2BCK3fxe9S11%2B88%2FynrqkhlXX%2BzVbd%2F5J%2FreUEsqODX5
#EXTINF:-1 logo="" group-title="" ,生活时尚高清
http://121.18.168.149/cache.ott.ystenlive.itv.cmvideo.cn:80/000000001000/8538616372715313491/index.m3u8?channel-id=bestzb&Contentid=8538616372715313491&livemode=1&authCode=3a&stbId=8A3603DD004735200000049573C4E39B&version=1.0&owaccmark=8538616372715313491&owchid=bestzb&owsid=5457861567734659356&AuthInfo=QejU%2ByFkapDLEHjn7Vi7Bsh98cz5RjIeOqbMi0QqlakS%2FOYtRGR5wcGJDIS9OeTlipH2OO8alDz%2F1TUrW3QAaMFdRScr5Z2333r7naICD73KmBnoU9%2B3A5Ot%2BJeysO4p
#EXTINF:-1 logo="" group-title="" ,峨眉电影高清
http://scgctvshow.sctv.com/hdlive/emei/1.m3u8
#EXTINF:-1 logo="" group-title="" ,欢笑剧场高清
http://112.50.243.8/PLTV/88888888/224/3221226729/1.m3u8
#EXTINF:-1 logo="" group-title="" ,纪实频道高清
http://112.50.243.8/PLTV/88888888/224/3221225946/1.m3u8
#EXTINF:-1 logo="" group-title="" ,极速汽车高清
http://112.50.243.8/PLTV/88888888/224/3221226140/1.m3u8
#EXTINF:-1 logo="" group-title="" ,动漫秀场高清
http://112.50.243.8/PLTV/88888888/224/3221226141/1.m3u8
#EXTINF:-1 logo="" group-title="" ,黑莓动画高清
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225914/1.m3u8
#EXTINF:-1 logo="" group-title="" ,黑莓电竞高清
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225931/1.m3u8
#EXTINF:-1 logo="" group-title="" ,黑莓电影高清
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225927/1.m3u8
#EXTINF:-1 logo="" group-title="" ,求索纪录
http://112.17.40.145/PLTV/88888888/224/3221226610/index.m3u8
#EXTINF:-1 logo="" group-title="" ,求索科学
http://125.210.152.18:9090/live/QSKX_1200.m3u8
#EXTINF:-1 logo="" group-title="" ,求索动物
http://125.210.152.18:9090/live/QSDW_1200.m3u8
#EXTINF:-1 logo="" group-title="" ,求索生活
http://125.210.152.18:9090/live/QSSH_1200.m3u8
#EXTINF:-1 logo="" group-title="" ,日本天気预报
http://movie.mcas.jp/mcas/wn1_2/master.m3u8
#EXTINF:-1 logo="" group-title="" ,中国教育1台
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225905/1.m3u8
#EXTINF:-1 logo="" group-title="" ,中国教育2台
http://cctvalih5ca.v.myalicdn.com/cstv/cetv2_2/index.m3u8
#EXTINF:-1 logo="" group-title="" ,中国教育3台
http://cctvalih5ca.v.myalicdn.com/cstv/cetv3_2/index.m3u8
#EXTINF:-1 logo="" group-title="" ,中国教育4台
http://cctvalih5ca.v.myalicdn.com/cstv/cetv4_2/index.m3u8
#EXTINF:-1 logo="" group-title="" ,山东教育
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225908/1.m3u8
#EXTINF:-1 logo="" group-title="" ,奥林匹克高清
http://ott-live.olympicchannel.com/out/u/OC1_2.m3u8?fluxustv.m3u8
#EXTINF:-1 logo="" group-title="" ,奥铃匹克高清
http://ott-live.olympicchannel.com/out/u/OC1_1.m3u8?fluxustv.m3u8
#EXTINF:-1 logo="" group-title="" ,超级电影
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226233/1.m3u8
#EXTINF:-1 logo="" group-title="" ,超级综艺
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226231/1.m3u8
#EXTINF:-1 logo="" group-title="" ,超级体育
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226232/1.m3u8
#EXTINF:-1 logo="" group-title="" ,超级剧集
http://111.13.111.167/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225864/1.m3u8
#EXTINF:-1 logo="" group-title="" ,中国功夫
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226298/1.m3u8
#EXTINF:-1 logo="" group-title="" ,金牌综艺
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226296/1.m3u8
#EXTINF:-1 logo="" group-title="" ,农业致富
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226304/1.m3u8
#EXTINF:-1 logo="" group-title="" ,潮妈辣婆
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226286/1.m3u8
#EXTINF:-1 logo="" group-title="" ,炫舞未来
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226248/1.m3u8
#EXTINF:-1 logo="" group-title="" ,明星大片
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226295/1.m3u8
#EXTINF:-1 logo="" group-title="" ,自由搏击
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226297/1.m3u8
#EXTINF:-1 logo="" group-title="" ,海外综合
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226302/1.m3u8
#EXTINF:-1 logo="" group-title="" ,惊梀悬疑
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226294/1.m3u8
#EXTINF:-1 logo="" group-title="" ,爱情喜剧
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226299/1.m3u8
#EXTINF:-1 logo="" group-title="" ,精品记录
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226293/1.m3u8
#EXTINF:-1 logo="" group-title="" ,精品体育
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226328/1.m3u8
#EXTINF:-1 logo="" group-title="" ,精品大剧
http://111.13.111.167/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226331/1.m3u8
#EXTINF:-1 logo="" group-title="" ,古装剧场
http://111.13.111.167/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226323/1.m3u8
#EXTINF:-1 logo="" group-title="" ,军旅剧场
http://111.13.111.167/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226324/1.m3u8
#EXTINF:-1 logo="" group-title="" ,军事评论
http://111.13.111.167/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226326/1.m3u8
#EXTINF:-1 logo="" group-title="" ,健康有约
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225919/1.m3u8
#EXTINF:-1 logo="" group-title="" ,家庭剧场
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225918/1.m3u8
#EXTINF:-1 logo="" group-title="" ,动作电影
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226288/1.m3u8
#EXTINF:-1 logo="" group-title="" ,爱电竞
http://101.71.255.229:6610/zjhs/2/10110/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱动漫
http://101.71.255.229:6610/zjhs/2/10107/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱都市
http://101.71.255.229:6610/zjhs/2/10111/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱江湖
http://101.71.255.229:6610/zjhs/2/10114/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱解密
http://101.71.255.229:6610/zjhs/2/10109/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱经典
http://101.71.255.229:6610/zjhs/2/10106/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱军武
http://101.71.255.229:6610/zjhs/2/10119/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱科幻
http://101.71.255.229:6610/zjhs/2/10113/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱历史
http://101.71.255.229:6610/zjhs/2/10120/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱美食
http://101.71.255.229:6610/zjhs/2/10108/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱奇谈
http://101.71.255.229:6610/zjhs/2/10103/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱时尚
http://101.71.255.229:6610/zjhs/2/10118/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱世界
http://101.71.255.229:6610/zjhs/2/10121/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱玩具
http://101.71.255.229:6610/zjhs/2/10117/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱喜剧
http://101.71.255.229:6610/zjhs/2/10105/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱悬疑
http://101.71.255.229:6610/zjhs/2/10104/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱幼教
http://101.71.255.229:6610/zjhs/2/10112/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱院线
http://101.71.255.229:6610/zjhs/2/10116/index.m3u8?virtualDomain=zjhs.live_hls.zte.com
#EXTINF:-1 logo="" group-title="" ,爱青春
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230130/index.m3u8
#EXTINF:-1 logo="" group-title="" ,爱家庭
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230118/index.m3u8
#EXTINF:-1 logo="" group-title="" ,爱探索
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230112/index.m3u8
#EXTINF:-1 logo="" group-title="" ,爱科学
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230106/index.m3u8
#EXTINF:-1 logo="" group-title="" ,爱猎奇
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230097/index.m3u8
#EXTINF:-1 logo="" group-title="" ,爱谍战
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230092/index.m3u8
#EXTINF:-1 logo="" group-title="" ,爱娱乐
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230077/index.m3u8
#EXTINF:-1 logo="" group-title="" ,爱旅行
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230052/index.m3u8
#EXTINF:-1 logo="" group-title="" ,爱怀旧
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230049/index.m3u8
#EXTINF:-1 logo="" group-title="" ,爱体育
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230034/index.m3u8
#EXTINF:-1 logo="" group-title="" ,爱赛车
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230032/index.m3u8
#EXTINF:-1 logo="" group-title="" ,爱浪漫
http://112.17.40.140/hwltc.tv.cdn.zj.chinamobile.com/PLTV/88888888/224/3221230005/index.m3u8?fmt=ts2hls
#EXTINF:-1 logo="" group-title="" ,票房大片
http://101.72.196.41/r/baiducdnct.inter.iqiyi.com/tslive/c16_lb_heibangdianying_1080p_t10/c16_lb_heibangdianying_1080p_t10.m3u8
#EXTINF:-1 logo="" group-title="" ,惊悚午夜
http://101.72.196.41/r/baiducdnct.inter.iqiyi.com/tslive/c16_lb_jingnawuyechang_1080p_t10/c16_lb_jingnawuyechang_1080p_t10.m3u8
#EXTINF:-1 logo="" group-title="" ,动画电影
http://101.72.196.41/r/baiducdnct.inter.iqiyi.com/tslive/c16_lb_donghuadianying_1080p_t10/c16_lb_donghuadianying_1080p_t10.m3u8
#EXTINF:-1 logo="" group-title="" ,怀旧剧场
http://101.72.196.41/r/baiducdnct.inter.iqiyi.com/tslive/c16_lb_huaijiujuchang_1080p_t10/c16_lb_huaijiujuchang_1080p_t10.m3u8
#EXTINF:-1 logo="" group-title="" ,温情影院
http://101.72.196.41/r/baiducdnct.inter.iqiyi.com/tslive/c15_lb_chenglong_1080p_t10/c15_lb_chenglong_1080p_t10.m3u8
#EXTINF:-1 logo="" group-title="" ,周末影院
http://101.72.196.41/r/baiducdnct.inter.iqiyi.com/tslive/c16_lb_fengxiaogang_1080p_t10/c16_lb_fengxiaogang_1080p_t10.m3u8
#EXTINF:-1 logo="" group-title="" ,经典重温
http://101.72.196.41/r/baiducdnct.inter.iqiyi.com/tslive/c16_lb_jingdianjuchang_1080p_t10/c16_lb_jingdianjuchang_1080p_t10.m3u8
#EXTINF:-1 logo="" group-title="" ,谍战剧场
http://101.72.196.41/r/baiducdnct.inter.iqiyi.com/tslive/c16_lb_diezhanjuchang_1080p_t10/c16_lb_diezhanjuchang_1080p_t10.m3u8
#EXTINF:-1 logo="" group-title="" ,军旅剧场
http://101.72.196.41/r/baiducdnct.inter.iqiyi.com/tslive/c16_lb_junlvjuchang_1080p_t10/c16_lb_junlvjuchang_1080p_t10.m3u8
#EXTINF:-1 logo="" group-title="" ,青春剧场
http://101.72.196.41/r/baiducdnct.inter.iqiyi.com/tslive/c15_lb_weizhangzhe_1080p_t10/c15_lb_weizhangzhe_1080p_t10.m3u8
#EXTINF:-1 logo="" group-title="" ,抗战剧场
http://101.72.196.41/r/baiducdnct.inter.iqiyi.com/tslive/c15_lb_kangzhanjuchang_1080p_t10/c15_lb_kangzhanjuchang_1080p_t10.m3u8
#EXTINF:-1 logo="" group-title="" ,侦探柯南
http://jvc.flashapp.cn/baiducdnct.inter.iqiyi.com/tslive/c20_lb_mingzhentankenan_720p_t10/c20_lb_mingzhentankenan_720p_t10.m3u8
#EXTINF:-1 logo="" group-title="" ,喜羊灰狼
http://101.72.196.41/r/baiducdnct.inter.iqiyi.com/tslive/c15_lb_xiyangyang_1080p_t10/c15_lb_xiyangyang_1080p_t10.m3u8
#EXTINF:-1 logo="" group-title="" ,儿子爸爸
http://101.72.196.41/r/baiducdnct.inter.iqiyi.com/tslive/c16_lb_datouerzi_1080p_t10/c16_lb_datouerzi_1080p_t10.m3u8
#EXTINF:-1 logo="" group-title="" ,儿歌大全
http://101.72.196.41/r/baiducdnct.inter.iqiyi.com/tslive/c15_lb_ergedaquan_1080p_t10/c15_lb_ergedaquan_1080p_t10.m3u8
#EXTINF:-1 logo="" group-title="" ,北京少儿
http://ivi.bupt.edu.cn/hls/btv10.m3u8
#EXTINF:-1 logo="" group-title="" ,动漫电影
http://112.17.40.140/PLTV/88888888/224/3221226178/index.m3u8
#EXTINF:-1 logo="" group-title="" ,云南少儿
http://edge2.yntv.cn/channels/yntv/ynse/flv:sd/live
#EXTINF:-1 logo="" group-title="" ,重庆少儿
http://219.153.252.50/PLTV/88888888/224/3221225646/1.m3u8
#EXTINF:-1 logo="" group-title="" ,嘉佳卡通
http://112.17.40.140/PLTV/88888888/224/3221226461/index.m3u8
#EXTINF:-1 logo="" group-title="" ,金鹰卡通
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225906/1.m3u8
#EXTINF:-1 logo="" group-title="" ,哈哈卡通
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225909/1.m3u8
#EXTINF:-1 logo="" group-title="" ,优漫卡通
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225910/1.m3u8
#EXTINF:-1 logo="" group-title="" ,卡酷少儿
http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225907/1.m3u8
#EXTINF:-1 logo="" group-title="" ,企鹅辅导一年级
http://live-edu.wasu.tv/live/QiEFuDao-lv1.m3u8
#EXTINF:-1 logo="" group-title="" ,企鹅辅导二年级
http://live-edu.wasu.tv/live/QiEFuDao-lv2.m3u8
#EXTINF:-1 logo="" group-title="" ,企鹅辅导三年级
http://live-edu.wasu.tv/live/QiEFuDao-lv3.m3u8
#EXTINF:-1 logo="" group-title="" ,企鹅辅导四年级
http://live-edu.wasu.tv/live/QiEFuDao-lv4.m3u8
#EXTINF:-1 logo="" group-title="" ,企鹅辅导五年级
http://live-edu.wasu.tv/live/QiEFuDao-lv5.m3u8
#EXTINF:-1 logo="" group-title="" ,企鹅辅导六年级
http://live-edu.wasu.tv/live/QiEFuDao-lv6.m3u8
#EXTINF:-1 logo="" group-title="" ,企鹅辅导初一
http://live-edu.wasu.tv/live/QiEFuDao-lv7.m3u8
#EXTINF:-1 logo="" group-title="" ,企鹅辅导初二
http://live-edu.wasu.tv/live/QiEFuDao-lv8.m3u8
#EXTINF:-1 logo="" group-title="" ,企鹅辅导初三
http://live-edu.wasu.tv/live/QiEFuDao-lv9.m3u8
#EXTINF:-1 logo="" group-title="" ,企鹅辅导高一
http://live-edu.wasu.tv/live/QiEFuDao-lv10.m3u8
#EXTINF:-1 logo="" group-title="" ,八大精彩台
http://hdtv.ub1818.com/ublive/index_1.m3u8
#EXTINF:-1 logo="" group-title="" ,民视第一台
http://hdtv.ub1818.com/ublive/index_2.m3u8
#EXTINF:-1 logo="" group-title="" ,民视台湾台
http://hdtv.ub1818.com/ublive/index_3.m3u8
#EXTINF:-1 logo="" group-title="" ,民视HD
http://hdtv.ub1818.com/ublive/index_4.m3u8
#EXTINF:-1 logo="" group-title="" ,TvbsHD
http://hdtv.ub1818.com/ublive/index_5.m3u8
#EXTINF:-1 logo="" group-title="" ,非凡新闻HD
http://hdtv.ub1818.com/ublive/index_8.m3u8
#EXTINF:-1 logo="" group-title="" ,中视新闻HD
http://hdtv.ub1818.com/ublive/index_9.m3u8
#EXTINF:-1 logo="" group-title="" ,华视新闻资讯HD
http://hdtv.ub1818.com/ublive/index_10.m3u8
#EXTINF:-1 logo="" group-title="" ,FTV综艺
http://hdtv.ub1818.com/ublive/index_11.m3u8
#EXTINF:-1 logo="" group-title="" ,八大综合台
http://hdtv.ub1818.com/ublive/index_12.m3u8
#EXTINF:-1 logo="" group-title="" ,ELTA娱乐
http://hdtv.ub1818.com/ublive/index_13.m3u8
#EXTINF:-1 logo="" group-title="" ,亮社
http://hdtv.ub1818.com/ublive/index_14.m3u8
#EXTINF:-1 logo="" group-title="" ,华视CTS
http://hdtv.ub1818.com/ublive/index_15.m3u8
#EXTINF:-1 logo="" group-title="" ,公视戏剧
http://hdtv.ub1818.com/ublive/index_16.m3u8
#EXTINF:-1 logo="" group-title="" ,动漫
http://hdtv.ub1818.com/ublive/index_17.m3u8
#EXTINF:-1 logo="" group-title="" ,靖洋卡通台
http://hdtv.ub1818.com/ublive/index_18.m3u8
#EXTINF:-1 logo="" group-title="" ,靖天综合台
http://hdtv.ub1818.com/ublive/index_19.m3u8
#EXTINF:-1 logo="" group-title="" ,靖天日本台
http://hdtv.ub1818.com/ublive/index_20.m3u8
#EXTINF:-1 logo="" group-title="" ,靖天卡通台
http://hdtv.ub1818.com/ublive/index_21.m3u8
#EXTINF:-1 logo="" group-title="" ,靖天戏剧台
http://hdtv.ub1818.com/ublive/index_22.m3u8
#EXTINF:-1 logo="" group-title="" ,靖天电影台
http://hdtv.ub1818.com/ublive/index_23.m3u8
#EXTINF:-1 logo="" group-title="" ,靖天音乐台
http://hdtv.ub1818.com/ublive/index_24.m3u8
#EXTINF:-1 logo="" group-title="" ,靖天国际台
http://hdtv.ub1818.com/ublive/index_25.m3u8
#EXTINF:-1 logo="" group-title="" ,靖天映画
http://hdtv.ub1818.com/ublive/index_26.m3u8
#EXTINF:-1 logo="" group-title="" ,台湾采昌
http://hdtv.ub1818.com/ublive/index_27.m3u8
#EXTINF:-1 logo="" group-title="" ,台湾影迷电影
http://hdtv.ub1818.com/ublive/index_28.m3u8
#EXTINF:-1 logo="" group-title="" ,台湾CNEX
http://hdtv.ub1818.com/ublive/index_29.m3u8
#EXTINF:-1 logo="" group-title="" ,台湾AMC电影
http://hdtv.ub1818.com/ublive/index_30.m3u8
#EXTINF:-1 logo="" group-title="" ,靖天资讯台
http://hdtv.ub1818.com/ublive/index_31.m3u8
#EXTINF:-1 logo="" group-title="" ,靖天欢乐台
http://hdtv.ub1818.com/ublive/index_32.m3u8
#EXTINF:-1 logo="" group-title="" ,靖洋戏剧台
http://hdtv.ub1818.com/ublive/index_33.m3u8
#EXTINF:-1 logo="" group-title="" ,台湾音乐
http://hdtv.ub1818.com/ublive/index_34.m3u8
#EXTINF:-1 logo="" group-title="" ,韩国娱乐台
http://hdtv.ub1818.com/ublive/index_35.m3u8
#EXTINF:-1 logo="" group-title="" ,旅游频道
http://hdtv.ub1818.com/ublive/index_36.m3u8
#EXTINF:-1 logo="" group-title="" ,户外频道
http://hdtv.ub1818.com/ublive/index_37.m3u8
#EXTINF:-1 logo="" group-title="" ,台视财经HD
http://hdtv.ub1818.com/ublive/index_38.m3u8
#EXTINF:-1 logo="" group-title="" ,TRACE体育
http://hdtv.ub1818.com/ublive/index_39.m3u8
#EXTINF:-1 logo="" group-title="" ,TVB明珠
http://116.199.5.52:8114/00000000/index.m3u8?&Fsv_ctype=LIVES&Fsv_otype=1&FvSeid=5abd1660af1babb4&Pcontent_id=&Provider_id=&Fsv_chan_hls_se_idx=12
#EXTINF:-1 logo="" group-title="" ,香港卫视
http://zhibo.hkstv.tv/livestream/mutfysrq.flv
#EXTINF:-1 logo="" group-title="" ,翡翠明珠
http://116.199.5.52:8114/00000000/index.m3u8?&Fsv_ctype=LIVES&Fsv_otype=1&FvSeid=5abd1660af1babb4&Fsv_filetype=1&Fsv_ctype=LIVES&Fsv_cid=0&Fsv_chan_hls_se_idx=12&Fsv_rate_id=0&Fsv_SV_PARAM1=0&Fsv_ShiftEnable=0&Fsv_ShiftTsp=0&Provider_id=&Pcontent_id=&Fsv_CMSID=&Fsv_otype=1
#EXTINF:-1 logo="" group-title="" ,翡翠综合
http://116.199.5.52:8114/00000000/index.m3u8?&Fsv_ctype=LIVES&Fsv_otype=1&FvSeid=5abd1660af1babb4&Fsv_filetype=1&Fsv_ctype=LIVES&Fsv_cid=0&Fsv_chan_hls_se_idx=188&Fsv_rate_id=0&Fsv_SV_PARAM1=0&Fsv_ShiftEnable=0&Fsv_ShiftTsp=0&Provider_id=&Pcontent_id=&Fsv&_res_tag_=video
#EXTINF:-1 logo="" group-title="" ,耀才财经
http://202.69.67.66:443/webcast/bshdlive-mobile/playlist.m3u8
#EXTINF:-1 logo="" group-title="" ,亚旅卫视
http://hls.jingchangkan.tv/jingchangkan/156722438_0HaM/index.m3u8
#EXTINF:-1 logo="" group-title="" ,赛马频道
http://tvbilive11-i.akamaihd.net/hls/live/494672/CH88/CH88-01.m3u8
#EXTINF:-1 logo="" group-title="" ,東森新聞
http://104.250.154.42:8080/ZZ_dongsenxinwen/ZZ_dongsenxinwen.m3u8
#EXTINF:-1 logo="" group-title="" ,東森電影
http://104.250.154.42:8080/ZZ_dongsendianying/ZZ_dongsendianying.m3u8
#EXTINF:-1 logo="" group-title="" ,東森洋片
http://192.154.103.75:8080/ZZ_dongsenyangpian/ZZ_dongsenyangpian.m3u8
#EXTINF:-1 logo="" group-title="" ,東森洋片
http://104.250.154.42:8080/ZZ_dongsenyangpian/ZZ_dongsenyangpian.m3u8
#EXTINF:-1 logo="" group-title="" ,中天新闻
http://104.250.154.42:8080/ZZ_zhongtiannews/ZZ_zhongtiannews.m3u8
#EXTINF:-1 logo="" group-title="" ,中天综合
http://104.250.154.42:8080/ZZ_zhongtianzonghe/ZZ_zhongtianzonghe.m3u8
#EXTINF:-1 logo="" group-title="" ,中天綜合
http://192.154.103.75:8080//ZZ_zhongtianzonghe/ZZ_zhongtianzonghe.m3u8
#EXTINF:-1 logo="" group-title="" ,中天娱乐
http://192.154.103.75:8080//ZZ_zhongtianyule/ZZ_zhongtianyule.m3u8
#EXTINF:-1 logo="" group-title="" ,中天娱乐
http://104.250.154.42:8080/ZZ_zhongtianyule/ZZ_zhongtianyule.m3u8
#EXTINF:-1 logo="" group-title="" ,中視综合
http://192.154.103.75:8080//ZZ_zhongshi/ZZ_zhongshi.m3u8
#EXTINF:-1 logo="" group-title="" ,中视综合
http://104.250.154.42:8080/ZZ_zhongshi/ZZ_zhongshi.m3u8
#EXTINF:-1 logo="" group-title="" ,华视综合
http://104.250.154.42:8080/ZZ_huashi/ZZ_huashi.m3u8
#EXTINF:-1 logo="" group-title="" ,华视综合
http://192.154.103.75:8080//ZZ_huashi/ZZ_huashi.m3u8
#EXTINF:-1 logo="" group-title="" ,年代新聞
http://192.154.103.75:8080/ZZ_niandaixinwen/ZZ_niandianxinwen.m3u8
#EXTINF:-1 logo="" group-title="" ,年代新闻
http://104.250.154.42:8080/ZZ_niandaixinwen/ZZ_niandianxinwen.m3u8
#EXTINF:-1 logo="" group-title="" ,八大綜合
http://192.154.103.75:8080//ZZ_zhongtianyazhou/ZZ_zhongtianyazhou.m3u8
#EXTINF:-1 logo="" group-title="" ,八大综合
http://104.250.154.42:8080/ZZ_zhongtianyazhou/ZZ_zhongtianyazhou.m3u8
#EXTINF:-1 logo="" group-title="" ,信吉电视
http://220.130.241.203:1935/sjtv/livestream_360p/playlist.m3u8
#EXTINF:-1 logo="" group-title="" ,人間衛視
http://54.64.23.79:1935/live/vod/playlist.m3u8
#EXTINF:-1 logo="" group-title="" ,唯心電視
http://mobile.ccdntech.com/transcoder/_definst_/vod164_Live/live/chunklist_w1177047531.m3u8
#EXTINF:-1 logo="" group-title="" ,卫视卡视
http://iliketot.dyndns.tv/c8233976dbba4a06a101780907447375.m3u8?&wmsAuthSign=c2VydmVyX3RpbWU9MTAvMjIvMjAxNyAxOjM2OjExIEFNJmhhc2hfdmFsdWU9T1lvZDZ5TjFaWk53M3J4OWZOTWtFUT09JnZhbGlkbWludXRlcz0yJmlkPW1jZ2x5bWFyfDc2MXxpcHR2aGVyb3wxNTA4NjM2MTcxfDIyMy4yMDUuMTIyLjE2Nw
#EXTINF:-1 logo="" group-title="" ,国家地理
http://104.250.154.42:8080/ZZ_hbo/ZZ_hbo.m3u8
#EXTINF:-1 logo="" group-title="" ,百事通台
http://112.17.40.145/PLTV/88888888/224/3221226596/index.m3u8
#EXTINF:-1 logo="" group-title="" ,MTV音乐
http://116.199.5.52:8114/00000000/index.m3u8?&Fsv_ctype=LIVES&Fsv_otype=1&FvSeid=5abd1660af1babb4&Fsv_filetype=1&Fsv_ctype=LIVES&Fsv_cid=0&Fsv_chan_hls_se_idx=202&Fsv_rate_id=0&Fsv_SV_PARAM1=0&Fsv_ShiftEnable=0&Fsv_ShiftTsp=0&Provider_id=&Pcontent_id=&Fsv_CMSID=&Fsv_otype=1
#EXTINF:-1 logo="" group-title="" ,HBO2台
http://161.0.157.5/PLTV/88888888/224/3221227026/03.m3u8fluxustv.m3u8
#EXTINF:-1 logo="" group-title="" ,动物星球
http://104.250.154.42:8080/ZZ_dongwuxingqiu/ZZ_dongwuxingqiu.m3u8
#EXTINF:-1 logo="" group-title="" ,歐美影院
http://101.71.255.229:6610/zjhs/2/10037/z.m3u8?ZTEUPSTREAM=1&IASHttpSessionId=SLB4328320190321203540013412&m3u8_level=2&ztecid=10037&virtualDomain=zjhs.live_hls.zte.com&ispcode=3&tid=Q894B3E8EEZ3T19UG09L8B03GSWB&ts=1553493266
#EXTINF:-1 logo="" group-title="" ,亞洲影院
http://101.71.255.229:6610/zjhs/2/10052/z.m3u8?ZTEUPSTREAM=1&IASHttpSessionId=SLB4328320190321203540013412&m3u8_level=2&ztecid=10052&virtualDomain=zjhs.live_hls.zte.com&ispcode=3&tid=C3V7K4ET1VFDUJY6C1IASRV55G66&ts=1553493153
#EXTINF:-1 logo="" group-title="" ,华纳电视
http://104.250.154.42:8080/ZZ_huanadianying/ZZ_huanadianying.m3u8
#EXTINF:-1 logo="" group-title="" ,福克斯动作
http://104.250.154.42:8080/ZZ_foxaction/ZZ_foxaction.m3u8
#EXTINF:-1 logo="" group-title="" ,福克斯动作
http://192.154.103.75:8080/ZZ_foxaction/ZZ_foxaction.m3u8
#EXTINF:-1 logo="" group-title="" ,大众影视
http://39.134.52.206/wh7f454c46tw2522585283_-1736190513/hwottcdn.ln.chinamobile.com/PLTV/88888890/224/3221226752/index.m3u8?icpid=88888890&RTS=1575014274&from=1&ocs=2_39.134.52.206_80&hms_devid=835&vqe=3
#EXTINF:-1 logo="" group-title="" ,点掌财经
http://cclive2.aniu.tv/live/anzb.m3u8
#EXTINF:-1 logo="" group-title="" ,澳门卫视
http://stream.mastvnet.com/MSTV/SD/live.m3u8
#EXTINF:-1 logo="" group-title="" ,澳亚卫视
http://stream.mastvnet.com/MSTV/playlist.m3u8
#EXTINF:-1 logo="" group-title="" ,日本NHK华语
https://nhkw-zh-hlscomp.akamaized.net/ixxemlzk1vqvy44o/playlist.m3u8
#EXTINF:-1 logo="" group-title="" ,日本NHK英语
https://nhkwlive-ojp.akamaized.net/hls/live/2003459/nhkwlive-ojp/index_1M.m3u8
#EXTINF:-1 logo="" group-title="" ,日本Japan News 24
http://www.news24.jp/livestream/index.m3u8
#EXTINF:-1 logo="" group-title="" ,日本JapanetChannelDX
http://bcsecurelivehls-i.akamaihd.net/hls/live/265320/5043843989001/140130JTDX/index_1200.m3u8
#EXTINF:-1 logo="" group-title="" ,日本QVC
http://cdn-live1.qvc.jp/iPhone/800/800.m3u8
#EXTINF:-1 logo="" group-title="" ,韩国EBS 第一频道
http://ebsonairios.ebs.co.kr/groundwavetablet500k/tablet500k/playlist.m3u8
#EXTINF:-1 logo="" group-title="" ,韩国EBS 少儿频道
http://ebsonairios.ebs.co.kr/ebsutablet500k/tablet500k/playlist.m3u8
#EXTINF:-1 logo="" group-title="" ,韩国KCTV
http://119.77.96.184:1935/chn21/chn21/chunklist_w252131137.m3u8
#EXTINF:-1 logo="" group-title="" ,韩国UBC SBS
http://59.25.202.81:1935/live/UBCstream/chunklist_w1495115977.m3u8
#EXTINF:-1 logo="" group-title="" ,朝鲜中央台
http://119.77.96.184:1935/chn05/chn05/chunklist_w644291506.m3u8
#EXTINF:-1 logo="" group-title="" ,韩国KTV 韩国电视
http://218.38.152.31:1935/klive/klive.stream/playlist.m3u8
#EXTINF:-1 logo="" group-title="" ,韩国EBS 儿童频道
http://ebsonairios.ebs.co.kr/ebsutablet500k/_definst_/tablet500k/chunklist_w1965791004.m3u8
#EXTINF:-1 logo="" group-title="" ,韩国YTN 联合新闻
http://ytnmmd.mmdlive.lldns.net/ytnmmd/9484b70302db4786886ae40308bf45a1/chunklist_b2592000.m3u8
#EXTINF:-1 logo="" group-title="" ,韩国阿里郎WORLDworld
http://amdlive.ctnd.com.edgesuite.net/arirang_1ch/smil:arirang_1ch.smil/playlist.m3u8
#EXTINF:-1 logo="" group-title="" ,韩国阿里郎WORLD
http://amdlive.ctnd.com.edgesuite.net/arirang_1ch/smil:arirang_1ch/master.m3u8
#EXTINF:-1 logo="" group-title="" ,韩国MBC MAX
http://63.237.48.3/ios/MBC_MAX/MBC_MAX.m3u8
#EXTINF:-1 logo="" group-title="" ,KOREA YTN Science
http://slive.sciencetv.kr:1935/science/yslive_20140419_1/playlist.m3u8
#EXTINF:-1 logo="" group-title="" ,Luxury World
http://nano.teleservice.su:8080/hls/luxury.m3u8
#EXTINF:-1 logo="" group-title="" ,韩国BBS佛教广播
http://bbstv.clouducs.com:1935/bbstv-live/livestream/chunklist_w1403706733.m3u8
#EXTINF:-1 logo="" group-title="" ,CPAC
http://bcoveliveios-i.akamaihd.net/hls/live/248519/1242843915001_1/master.m3u8
#EXTINF:-1 logo="" group-title="" ,CGTN 记录频道
http://live.cgtn.com/1000d/prog_index.m3u8
#EXTINF:-1 logo="" group-title="" ,中国环球
http://live.cgtn.com/1000/prog_index.m3u8
#EXTINF:-1 logo="" group-title="" ,狗狗宠物
http://video.blivenyc.com/broadcast/prod/2061/22/file-3192k.m3u8
#EXTINF:-1 logo="" group-title="" ,法国时尚
http://lb.streaming.sk/fashiontv/stream/chunklist_w1702070444.m3u8
#EXTINF:-1 logo="" group-title="" ,亚洲新闻
http://d2e1asnsl7br7b.cloudfront.net/7782e205e72f43aeb4a48ec97f66ebbe/index_4.m3u8
#EXTINF:-1 logo="" group-title="" ,朝阳频道
http://d11h6a6nhl9kj9.cloudfront.net/hls/suriactv/master02.m3u8
#EXTINF:-1 logo="" group-title="" ,越南人民报
http://27.118.16.98:1935/live/truyenhinhnhandan720/chunklist_w2006762604.m3u8
#EXTINF:-1 logo="" group-title="" ,越南人民报
http://vietcago.net/vstv/thnd.m3u8
#EXTINF:-1 logo="" group-title="" ,印度音乐电视
http://104.237.60.234/live/gabruutv.m3u8?dsjtv.m3u8
#EXTINF:-1 logo="" group-title="" ,法国中国环球
http://live.cgtn.com/1000f/prog_index.m3u8
#EXTINF:-1 logo="" group-title="" ,法国第五世界台
http://v3plusinfo247hls-i.akamaihd.net/hls/live/218877-b/v3plusinfo247hls/v3plusinfo247hls_1_1.m3u8
#EXTINF:-1 logo="" group-title="" ,阿拉伯中国环球
http://live.cgtn.com/1000a/prog_index.m3u8
#EXTINF:-1 logo="" group-title="" ,俄罗斯中国环球
http://live.cgtn.com/1000r/prog_index.m3u8
#EXTINF:-1 logo="" group-title="" ,俄罗斯HD时尚频道
http://95.67.47.115/hls/hdfashion_ua_hi/index.m3u8
#EXTINF:-1 logo="" group-title="" ,乌克兰M2 音乐频道
http://live.m2.tv/hls3/stream.m3u8
#EXTINF:-1 logo="" group-title="" ,西班牙中国环球
http://livees.cgtn.com/1000e/prog_index.m3u8
#EXTINF:-1 logo="" group-title="" ,意大利Rai高清
http://b2everyrai-lh.akamaihd.net/i/raigulp_1@66350/master.m3u8
#EXTINF:-1 logo="" group-title="" ,意大利Rai 少儿
http://b2everyrai-lh.akamaihd.net/i/raiyoyo_1@191405/master.m3u8
#EXTINF:-1 logo="" group-title="" ,意大利Rai 电影
http://b2everyrai-lh.akamaihd.net/i/raimovie_1@67348/master.m3u8
#EXTINF:-1 logo="" group-title="" ,意大利意大利电台
http://radioitaliatv-lh.akamaihd.net/i/radioitaliatv_1@329645/index_720x480_av-p.m3u8
#EXTINF:-1 logo="" group-title="" ,意大利V2 音乐频道
http://de1se01.v2beat.live/playlist.m3u8
#EXTINF:-1 logo="" group-title="" ,墨西哥墨西哥电视
http://bcoveliveios-i.akamaihd.net/hls/live/201661/57828478001/milenio_center_512k@51752.m3u8
#EXTINF:-1 logo="" group-title="" ,音乐20TV
http://m2otv-lh.akamaihd.net/i/m2oTv_1@186074/index_600_av-p.m3u8
#EXTINF:-1 logo="" group-title="" ,当红MTV
http://unilivemtveu-lh.akamaihd.net/i/mtvno_1@346424/index_3500_av-b.m3u8
#EXTINF:-1 logo="" group-title="" ,WSVI-TV
http://dcunilive30-lh.akamaihd.net/i/dclive_1@534251/master.m3u8?fluxustv.m3u8
#EXTINF:-1 logo="" group-title="" ,酷酷频道
http://edge1.tikilive.com:1935/unrestricted_tikilive/25947/amlst:NWKlw6jwyXpz/chunklist_w981409619_b1105254.m3u8?fluxustv.m3u8
#EXTINF:-1 logo="" group-title="" ,红牛电视
http://rbmn-live.akamaized.net/hls/live/590964/BoRB-AT/master_1660.m3u8
#EXTINF:-1 logo="" group-title="" ,NBC电视
http://161.0.157.51/PLTV/88888888/224/3221227040/index.m3u8?fluxustv.m3u8
#EXTINF:-1 logo="" group-title="" ,Jewelry电视
http://wowzaprod134-i.akamaihd.net/hls/live/577814/ccddaf02/playlist.m3u8
#EXTINF:-1 logo="" group-title="" ,Darcizzle电视
http://30a-tv.com/darcizzle.m3u8
#EXTINF:-1 logo="" group-title="" ,CBS新闻
http://cbsnewshd-lh.akamaihd.net/i/CBSNHD_7@199302/master.m3u8
#EXTINF:-1 logo="" group-title="" ,美国Deutsche Welle
http://dwstream4-lh.akamaihd.net/i/dwstream4_live@131329/master.m3u8
#EXTINF:-1 logo="" group-title="" ,美国360 North
http://wowzaprod3-i.akamaihd.net/hls/live/252236/2147483647_360north_247/playlist.m3u8
#EXTINF:-1 logo="" group-title="" ,美国Fox News Talk Radio
http://fnurtmp-f.akamaihd.net/i/FNRADIO_1@92141/master.m3u8
#EXTINF:-1 logo="" group-title="" ,日本NHK台
http://nhkwtvglobal-i.akamaihd.net/hls/live/263941/nhkwtvglobal/index_600.m3u8
#EXTINF:-1 logo="" group-title="" ,日本cgntv
http://cgntv-glive.ofsdelivery.net/live/_definst_/cgntv_jp/playlist.m3u8
#EXTINF:-1 logo="" group-title="" ,日本映画
http://192.240.127.34:1935/live/cs19.stream/playlist.m3u8
#EXTINF:-1 logo="" group-title="" ,日本Japanet Channel DX
http://bcsecurelivehls-i.akamaihd.net/hls/live/265320/5043843989001/140130JTDX/index_600.m3u8

View File

@@ -1,18 +1,14 @@
{
"name": "zy",
"version": "1.0.23",
"version": "2.6.5",
"private": true,
"author": {
"name": "Hunlongyu",
"email": "hunlongyu@gmail.com"
},
"description": "ZY Player 资源播放器",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"electron:build": "vue-cli-service electron:build",
"dev": "vue-cli-service electron:serve",
"electron:build": "vue-cli-service electron:build",
"electron:serve": "vue-cli-service electron:serve",
"postinstall": "electron-builder install-app-deps",
"postuninstall": "electron-builder install-app-deps",
"electron:generate-icons": "electron-icon-builder --input=./public/icon.png --output=build --flatten",
@@ -21,40 +17,56 @@
},
"main": "background.js",
"dependencies": {
"axios": "^0.19.2",
"core-js": "^3.6.5",
"dexie": "^2.0.4",
"electron-updater": "^4.3.1",
"element-ui": "^2.13.2",
"html2canvas": "^1.0.0-rc.5",
"leancloud-storage": "^4.5.3",
"macaddress": "^0.5.1",
"modern-normalize": "^0.6.0",
"axios": "^0.21.0",
"cheerio": "^1.0.0-rc.3",
"core-js": "^3.7.0",
"cors": "^2.8.5",
"dexie": "^3.0.2",
"electron-localshortcut": "^3.2.1",
"electron-proxy-agent": "^1.2.0",
"electron-updater": "^4.3.5",
"element-ui": "^2.14.0",
"express": "^4.17.1",
"fast-xml-parser": "^3.17.4",
"html2canvas": "^1.0.0-rc.7",
"iptv-playlist-parser": "^0.5.0",
"m3u": "0.0.2",
"m3u8-parser": "^4.5.0",
"memcached": "^2.2.2",
"modern-normalize": "^1.0.0",
"mousetrap": "^1.6.5",
"qrcode.vue": "^1.7.0",
"vue": "^2.6.11",
"vue-i18n": "^8.17.7",
"vuex": "^3.4.0",
"xgplayer": "^2.7.1",
"xgplayer-hls.js": "^2.2.2"
"randomstring": "^1.1.5",
"session": "^0.1.0",
"v-fit-columns": "^0.2.0",
"vue": "^2.6.12",
"vue-clickaway": "^2.2.2",
"vue-infinite-loading": "^2.4.5",
"vue-waterfall-plugin": "^1.1.0",
"vuedraggable": "^2.24.3",
"vuex": "^3.5.1",
"xgplayer": "^2.13.0",
"xgplayer-hls.js": "^2.2.5"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.3.0",
"@vue/cli-plugin-eslint": "~4.3.0",
"@vue/cli-plugin-vuex": "~4.3.0",
"@vue/cli-service": "~4.3.0",
"@vue/cli-plugin-babel": "~4.4.0",
"@vue/cli-plugin-eslint": "~4.4.0",
"@vue/cli-plugin-vuex": "~4.4.0",
"@vue/cli-service": "~4.4.0",
"@vue/eslint-config-standard": "^5.1.2",
"babel-eslint": "^10.1.0",
"babel-plugin-component": "^1.1.1",
"electron": "^9.0.0",
"electron": "^10.1.5",
"electron-devtools-installer": "^3.1.0",
"eslint": "^6.7.2",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-standard": "^4.0.2",
"eslint-plugin-vue": "^6.2.2",
"sass": "^1.26.3",
"sass": "^1.29.0",
"sass-loader": "^8.0.2",
"vue-cli-plugin-electron-builder": "2.0.0-beta.6",
"vue-template-compiler": "^2.6.11"
"vue-cli-plugin-electron-builder": "2.0.0-rc.4",
"vue-template-compiler": "^2.6.12"
}
}

View File

@@ -4,17 +4,8 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>icon.png">
<title><%= htmlWebpackPlugin.options.title %></title>
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?62aeb2505bfa26a2461d2a7a3b485096";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>

View File

@@ -5,8 +5,12 @@
<Frame />
<Film v-show="view === 'Film'" />
<Play v-show="view === 'Play'" />
<IPTV v-show="view === 'IPTV'" />
<Star v-show="view === 'Star'" />
<History v-show="view === 'History'" />
<Setting v-show="view === 'Setting'" />
<EditSites v-if="view === 'EditSites'"/>
<Recommendation v-show="view === 'Recommendation'" />
</div>
<transition name="slide">
<Detail v-if="detail.show"/>
@@ -16,6 +20,7 @@
</transition>
</div>
</template>
<script>
export default {
name: 'App',
@@ -34,18 +39,27 @@ export default {
share () {
return this.$store.getters.getShare
},
theme () {
return this.$store.getters.getTheme
setting () {
return this.$store.getters.getSetting
},
editSites () {
return this.$store.getters.getEditSites
},
recommendation () {
return this.$store.getters.recommendation
}
},
watch: {
theme () {
this.changeTheme()
setting: {
handler () {
this.changeSetting()
},
deep: true
}
},
methods: {
changeTheme () {
this.appTheme = `theme-${this.theme}`
changeSetting () {
this.appTheme = `theme-${this.setting.theme}`
}
}
}
@@ -55,7 +69,7 @@ export default {
@import './assets/scss/theme.scss';
html, body, #app{
height: 100%;
border-radius: 6px;
border-radius: 0px;
}
#app {
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', SimSun, sans-serif;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

View File

@@ -42,6 +42,22 @@
border-left: .3em solid transparent;
}
}
.vs-input{
height: 30px;
input{
border: none;
width: 200px;
height: 30px;
text-indent: 22px;
background-color: #ffffff00;
outline: none;
}
}
.vs-noAfter{
&::after{
display: none;
}
}
.vs-options{
z-index: 2;
width: 100%;
@@ -62,105 +78,30 @@
}
}
}
// table
.zy-table{
display: flex;
flex-direction: column;
height: 100%;
font-size: 15px;
.tHead{
height: 50px;
width: 100%;
display: flex;
justify-content: flex-start;
align-items: center;
border-bottom: 1px solid;
padding: 0 5px 0 0;
font-weight: 600;
span{
display: flex;
width: 180px;
font-size: 16px;
&.name{
flex: 1;
padding-left: 15px;
}
&.type{
width: 120px;
}
&.from{
width: 120px;
}
&.operate{
width: 170px;
}
}
}
.tBody{
flex: 1;
overflow-y: scroll;
border-bottom: 1px solid;
ul{
list-style: none;
padding: 0;
margin: 0;
li{
display: flex;
justify-content: flex-start;
align-items: center;
flex-direction: row;
height: 50px;
border-bottom: 1px solid;
cursor: pointer;
span{
display: flex;
width: 180px;
font-size: 13px;
height: 50px;
line-height: 50px;
&.name{
flex: 1;
padding-left: 15px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&.type{
width: 120px;
}
&.from{
width: 120px;
}
&.operate{
width: 170px;
}
}
}
}
}
.tFooter{
width: 100%;
height: 40px;
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: row;
padding-right: 10px;
.tFooter-span{
padding-left: 10px;
font-size: 12px;
}
.btn{
cursor: pointer;
}
.zy-input{
position: relative;
display: inline-block;
white-space: nowrap;
width: 200px;
height: 30px;
cursor: pointer;
input{
vertical-align: bottom;
position: relative;
border: none;
width: 20px;
height: 15px;
background-color: #ffffff00;
text-indent: 10px;
}
}
.zy-highlighted{
color: var(--highlight-color);
}
// scroll
.zy-scroll{
&::-webkit-scrollbar{
width: 5px;
width: 10px;
height: 1px;
}
&::-webkit-scrollbar-thumb {
@@ -173,6 +114,243 @@
}
}
// Page of list using el-table
.listpage{
position: absolute;
left: 80px;
right: 20px;
top: 40px;
bottom: 20px;
width: calc(100% - 100px);
height: calc(100% - 60px);
border-radius: 5px;
display: flex;
flex-direction: column;
.listpage-header{
height: 60px;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
z-index: 10;
.header-box{
height: 100%;
width: 100%;
align-items: center;
justify-content: space-between;
}
.el-button{
font-size: 1rem;
border: none;
&:hover{
cursor: pointer;
}
}
.el-autocomplete{
.el-input-group__prepend{
border: none;
.el-select{
width: 100px;
.el-input, .el-input__inner{
width: 100%;
border: none;
}
}
}
.el-input .el-input__inner{
width: 200px;
}
.el-input-group__append{
border: none;
}
}
.is-loading:before {
background-color: none !important;
}
.el-input{
font-size: 1rem;
width: 200px;
}
.popper {
font-size: 1rem;;
border: none;
li {
font-size: 1rem;
border: none;
}
}
}
.listpage-body{
height: calc(100% - 60px);
overflow-y: auto;
position: relative;
font-size: 1rem;
&::-webkit-scrollbar{
width: 5px;
height: 1px;
}
&::-webkit-scrollbar-thumb {
border-radius: 10px;
position: absolute;
}
&::-webkit-scrollbar-track {
border-radius: 10px;
position: absolute;
}
.show-table{
height: 100%;
width: 100%;
.el-table::before{
height: 0px;
}
.el-table{
height: 100%;
width: 100%;
overflow: hidden;
font-size: 1rem;
}
.el-table__body-wrapper{
height: 100%;
width: 100%;
&::-webkit-scrollbar{
width: 5px;
height: 1px;
}
&::-webkit-scrollbar-thumb {
border-radius: 10px;
position: absolute;
}
&::-webkit-scrollbar-track {
border-radius: 10px;
position: absolute;
}
}
.el-input{
width: 200px;
}
.el-table__body td,.el-table__body th{
border-bottom: 1px solid;
}
.el-table--enable-row-hover .el-table__body tr:hover>td{
transform: scale(1.02);
}
.el-table .highlight{
background-color: var(--highlight-color) !important; // 改为背景色,原来某些主题下看不清字
}
.el-button{
font-size: 1rem;
}
}
.show-picture{
height: 100%;
width: 100%;
padding: 10px;
.card{
border-radius: 6px;
overflow: hidden;
position: relative;
cursor: pointer;
transition: 0.2s;
&:hover {
top: -3px;
}
.img{
position: relative;
min-height: 40px;
img{
width: 100%;
height: auto;
cursor: pointer;
}
.rate{
position: absolute;
top: 3%;
right: -40%;
width: 100%;
background-color: #111111aa;
color:#2f90b9;
height: 30px;
line-height: 30px;
font-size: 14px;
font-weight: bolder;
text-align: center;
transform: rotate(45deg);
}
.progress{
position: absolute;
bottom: 10%;
left: 0%;
width: 40%;
background-color: #111111aa;
color: #f8df70;
height: 30px;
line-height: 30px;
font-size: 14px;
font-weight: bolder;
text-align: left;
}
.update{
position: absolute;
top: 5%;
left: -40%;
width: 100%;
background-color: #68b88e;
color: #cdcdcd;
height: 30px;
line-height: 30px;
font-size: 14px;
text-align: center;
transform: rotate(-45deg);
}
.operate{
display: none;
position: absolute;
left: 0;
bottom: 0;
background-color: #111111aa;
width: 100%;
font-size: 13px;
.operate-wrap{
display: flex;
justify-content: space-between;
.o-play, .o-star, .o-share{
cursor: pointer;
display: inline-block;
width: 80px;
height: 36px;
text-align: center;
line-height: 36px;
color: #cdcdcd;
&:hover{
background-color: #111;
}
}
}
}
}
.name{
font-size: 16px;
padding: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.info{
display: flex;
justify-content: space-between;
font-size: 12px;
padding: 10px;
}
&:hover{
.operate{
display: block;
}
}
}
}
}
}
// loading
.zy-loading{
width: 100%;
@@ -217,4 +395,4 @@
box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
}
}
}
}

View File

@@ -1,4 +1,6 @@
:root{
// general
--highlight-color: #38dd77;
// light
--l-c-0: #823aa0;
--l-c-1: #823aa011;
@@ -12,10 +14,10 @@
--l-fc-3: #823aa0;
--l-bgc-1: #ffffff;
--l-bgc-2: #f2f6f9;
--l-bsc: 0 3px 1px -2px #8e8da233, 0 2px 2px 0 #8e8da224, 0 1px 5px 0 #8e8da21f;
--l-bsc: 0 1px 3px #8e8da233, 0 1px 2px #8e8da244;
--l-bsc-hover: 0 14px 28px #8e8da255, 0 10px 10px #8e8da244;
--l-bsc-2: 0 -4px 23px 0 #8e8da233;
--l-bsc-hover: 0 14px 26px -12px #8e8da26b, 0 4px 23px 0 #8e8da21f, 0 8px 10px -5px #8e8da233;
--l-bsc-scroll: inset 0 0 5px #823aa005;
--l-bsc-scroll: inset 0 0 5px #823aa000;
// dark
--d-c-0: #38dd77;
@@ -30,9 +32,9 @@
--d-fc-3: #38dd77;
--d-bgc-1: #222222;
--d-bgc-2: #2f2f2f;
--d-bsc: 0 3px 1px -2px #38dd7733, 0 2px 2px 0 #38dd7722, 0 1px 5px 0 #38dd7711;
--d-bsc: 0 1px 3px #38dd7733, 0 1px 2px #38dd7744;
--d-bsc-hover: 0 14px 28px #38dd7755, 0 10px 10px #38dd7744;
--d-bsc-2: 0 -4px 23px 0 #38dd7733;
--d-bsc-hover: 0 14px 26px -12px #38dd7733, 0 4px 23px 0 #38dd7722, 0 8px 10px -5px #38dd7711;
--d-bsc-scroll: inset 0 0 5px #38dd7705;
// green
@@ -48,9 +50,9 @@
--g-fc-3: #C1D95C;
--g-bgc-1: #4baea0;
--g-bgc-2: #74b4ac;
--g-bsc: 0 3px 1px -2px #e1ebe033, 0 2px 2px 0 #e1ebe022, 0 1px 5px 0 #e1ebe011;
--g-bsc: 0 1px 3px #e1ebe033, 0 1px 2px #e1ebe044;
--g-bsc-hover: 0 14px 28px #e1ebe055, 0 10px 10px #e1ebe044;
--g-bsc-2: 0 -4px 23px 0 #e1ebe033;
--g-bsc-hover: 0 14px 26px -12px #e1ebe033, 0 4px 23px 0 #e1ebe022, 0 8px 10px -5px #e1ebe011;
--g-bsc-scroll: inset 0 0 5px #e1ebe005;
// pink
@@ -63,12 +65,12 @@
--p-c-9: #f4f7f799;
--p-fc-1: #ffffff;
--p-fc-2: #FFFFF3;
--p-fc-3: #f15c5c;
--p-fc-3: #177ea7;
--p-bgc-1: #ff8499;
--p-bgc-2: #fea1b2;
--p-bsc: 0 3px 1px -2px #ef528533, 0 2px 2px 0 #ef528522, 0 1px 5px 0 #ef528511;
--p-bsc: 0 1px 3px #ef528533, 0 1px 2px #ef528544;
--p-bsc-hover: 0 14px 28px #ef528555, 0 10px 10px #ef528544;
--p-bsc-2: 0 -4px 23px 0 #ef528533;
--p-bsc-hover: 0 14px 26px -12px #ef528533, 0 4px 23px 0 #ef528522, 0 8px 10px -5px #ef528511;
--p-bsc-scroll: inset 0 0 5px #ef528505;
}

View File

@@ -1,37 +1,10 @@
.theme-dark{
background-color: var(--d-bgc-1);
.el-pagination{
background-color: var(--d-bgc-1);
color: var(--d-fc-1);
.el-pagination__total, .el-pagination__jump, .el-input__inner{
color: var(--d-fc-1);
background-color: var(--d-bgc-1);
}
.el-input__inner{
border-color: var(--d-c-3);
}
.el-pager{
.number{
background-color: var(--d-bgc-1);
}
.number:hover{
color: var(--d-c-8);
}
.active{
color: var(--d-c-9);
}
}
.more, .btn-next, .btn-prev{
background-color: var(--d-bgc-1);
&:hover{
color: var(--d-c-8);
}
}
}
.zy-select{
color: var(--d-fc-1);
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--d-bsc-hover);
}
@@ -39,6 +12,7 @@
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
ul{
overflow-y: scroll;
li{
&:hover{
background-color: var(--d-c-1);
@@ -49,49 +23,33 @@
}
}
}
}
.zy-table{
color: var(--d-fc-2);
.tHead{
.vs-input{
color: var(--d-fc-1);
background-color: var(--d-bgc-1);
border-bottom-color: var(--d-c-3);
}
.tBody{
border-bottom-color: var(--d-c-3);
ul{
li{
border-bottom-color: var(--d-c-2);
&:hover{
animation: d-tableHoverAni 0.2s ease both;
@keyframes d-tableHoverAni {
to{
box-shadow: var(--d-bsc-hover);
}
}
}
span{
&.btn:hover{
color: var(--d-fc-3)
}
}
input{
color: var(--d-fc-1);
&::-webkit-input-placeholder{
color: var(--d-fc-1);
}
}
}
.tFooter{
.tFooter-span{
color: var(--d-fc-1);
}
}
.zy-input{
color: var(--d-fc-1);
background-color: var(--d-bgc-1);
input{
color: var(--d-fc-1);
}
}
.zy-scroll{
&:hover{
&::-webkit-scrollbar-thumb {
box-shadow: var(--d-bsc-scroll);
background: var(--d-c-3);
background: var(--d-c-5);
}
&::-webkit-scrollbar-track {
box-shadow: var(--d-bsc-scroll);
background: var(--bgc);
background: var(--d-bgc-1);
}
}
}
@@ -112,6 +70,7 @@
background-color: var(--d-c-2);
}
&.active{
background-color: var(--d-bgc-2);
svg{
stroke: var(--d-c-0);
stroke-width: 2;
@@ -123,11 +82,17 @@
.frame{
span{
&.min{
background-color: #32dc36;
}
&.max{
background-color: #ffbe2a;
}
&.close{
background-color: #ff5f56;
}
&.top{
background-color: #f3bab7;
}
}
}
.detail{
@@ -146,10 +111,17 @@
}
}
.detail-body{
.info, .desc, .m3u8_urls, .mp4_urls{
.info, .desc, .m3u8, .operate{
border-color: var(--d-c-2);
}
.m3u8_urls, .mp4_urls{
.operate{
span{
&:hover{
color: var(--d-fc-2);
}
}
}
.m3u8{
.box{
span{
border-color: var(--d-c-5);
@@ -164,44 +136,16 @@
}
}
}
.film{
.top{
.search{
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
&:hover{
box-shadow: var(--d-bsc-hover);
}
svg{
stroke: var(--d-c-0);
stroke-width: 1;
fill: none;
}
.search-box{
background-color: var(--d-bgc-1);
}
&.active{
box-shadow: var(--d-bsc-hover);
svg{
stroke-width: 1.5;
fill: var(--d-c-2);
}
}
input{
color: var(--d-fc-1);
}
}
}
.middle{
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
}
}
.play{
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
.title{
color: var(--d-fc-1);
.right {
svg {
fill: var(--d-fc-1);
}
}
}
.box{
.more{
@@ -225,6 +169,10 @@
fill: var(--d-c-3);
}
}
&.last-tip {
color: var(--d-fc-1);
font-size: 14px;
}
}
}
}
@@ -254,6 +202,9 @@
background-color: var(--d-c-2);
color: var(--d-fc-3);
}
&:hover{
background-color: var(--d-c-3);
}
}
}
.list-history{
@@ -283,14 +234,6 @@
}
}
}
.play-mask{
background-color: var(--d-bgc-1);
color: var(--d-fc-1);
}
}
.star{
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
}
.setting{
background-color: var(--d-bgc-1);
@@ -303,12 +246,18 @@
}
}
}
.view, .search, .shortcut, .site{
.title{
color: var(--d-fc-1);
}
}
.theme{
.title{
color: var(--d-fc-1);
}
.theme-item{
box-shadow: var(--d-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--d-bsc-hover);
.theme-name{
@@ -326,6 +275,10 @@
}
.qrcode-item{
box-shadow: var(--d-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--d-bsc-hover);
}
}
}
}
@@ -343,4 +296,118 @@
background-color: var(--d-bgc-1);
}
}
.history{
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
}
// Page of list using table and picture
.listpage{
color: var(--d-fc-2);
.listpage-header{
border-bottom-color: var(--d-c-3);
.btn{
&:hover{
color: var(--d-fc-3)
}
}
.el-button{
background-color: var(--d-bgc-2);
color: var(--d-fc-2);
&:hover{
color: var(--d-fc-3)
}
}
.el-input{
input{
background-color: var(--d-bgc-1);
border: 1px solid var(--d-bgc-1);
color: var(--d-fc-2);
}
}
.el-input-group__prepend{
background-color: var(--d-bgc-1);
}
.popper {
color: var(--d-fc-1);
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
li {
color: var(--d-fc-1);
background-color: var(--d-bgc-1);
&:hover{
background-color: var(--d-bgc-2);
}
}
}
.popper__arrow, .popper__arrow::after{
border-bottom-color: var(--d-bgc-1);
}
}
.listpage-body{
color: var(--d-fc-1);
background-color: var(--d-bgc-1);
&:hover{
&::-webkit-scrollbar-thumb {
box-shadow: var(--d-bsc-scroll);
background: var(--d-c-5);
}
&::-webkit-scrollbar-track {
box-shadow: var(--d-bsc-scroll);
background: var(--d-bgc-1);
}
}
/* 设置el-table的样式*/
.show-table{
.el-table{
color: var(--d-fc-1);
background-color: var(--d-bgc-1);
}
.el-table__body-wrapper{
&:hover{
&::-webkit-scrollbar-thumb {
box-shadow: var(--d-bsc-scroll);
background: var(--d-c-5);
}
&::-webkit-scrollbar-track {
box-shadow: var(--d-bsc-scroll);
background: var(--d-bgc-1);
}
}
}
.el-input{
input{
background-color: var(--d-bgc-2);
border: 1px solid var(--d-bgc-2);
color: var(--d-fc-1);
}
}
.el-table__header th, .el-table__header tr, .el-table__body td,.el-table__body th{
color: var(--d-fc-1);
background-color: var(--d-bgc-1);
border-bottom-color: var(--d-c-2);
}
.el-table--enable-row-hover .el-table__body tr:hover>td{
background-color: var(--d-bgc-2);
}
.el-button{
color: var(--d-fc-1);
&:hover{
color: var(--d-fc-3)
}
}
}
.show-picture{
color: var(--d-fc-1);
.card{
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--d-bsc-hover);
}
}
}
}
}
}

View File

@@ -1,37 +1,10 @@
.theme-green{
background-color: var(--g-bgc-1);
.el-pagination{
background-color: var(--g-bgc-1);
color: var(--g-fc-1);
.el-pagination__total, .el-pagination__jump, .el-input__inner{
color: var(--g-fc-1);
background-color: var(--g-bgc-1);
}
.el-input__inner{
border-color: var(--g-c-3);
}
.el-pager{
.number{
background-color: var(--g-bgc-1);
}
.number:hover{
color: var(--g-c-8);
}
.active{
color: var(--g-c-9);
}
}
.more, .btn-next, .btn-prev{
background-color: var(--g-bgc-1);
&:hover{
color: var(--g-c-8);
}
}
}
.zy-select{
color: var(--g-fc-1);
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--g-bsc-hover);
}
@@ -39,6 +12,7 @@
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
ul{
overflow-y: scroll;
li{
&:hover{
background-color: var(--g-c-1);
@@ -49,49 +23,33 @@
}
}
}
}
.zy-table{
color: var(--g-fc-2);
.tHead{
.vs-input{
color: var(--g-fc-1);
background-color: var(--g-bgc-1);
border-bottom-color: var(--g-c-3);
}
.tBody{
border-bottom-color: var(--g-c-3);
ul{
li{
border-bottom-color: var(--g-c-2);
&:hover{
animation: d-tableHoverAni 0.2s ease both;
@keyframes d-tableHoverAni {
to{
box-shadow: var(--g-bsc-hover);
}
}
}
span{
&.btn:hover{
color: var(--g-fc-3)
}
}
input{
color: var(--g-fc-1);
&::-webkit-input-placeholder{
color: var(--g-fc-1);
}
}
}
.tFooter{
.tFooter-span{
color: var(--g-fc-1);
}
}
.zy-input{
color: var(--g-fc-1);
background-color: var(--g-bgc-1);
input{
color: var(--g-fc-1);
}
}
.zy-scroll{
&:hover{
&::-webkit-scrollbar-thumb {
box-shadow: var(--g-bsc-scroll);
background: var(--g-c-3);
background: var(--g-c-5);
}
&::-webkit-scrollbar-track {
box-shadow: var(--g-bsc-scroll);
background: var(--bgc);
background: var(--g-bgc-1);
}
}
}
@@ -112,6 +70,7 @@
background-color: var(--g-c-2);
}
&.active{
background-color: var(--g-bgc-2);
svg{
stroke: var(--g-c-0);
stroke-width: 2;
@@ -123,15 +82,21 @@
.frame{
span{
&.min{
background-color: #32dc36;
}
&.max{
background-color: #ffbe2a;
}
&.close{
background-color: #ff5f56;
}
&.top{
background-color: #f3bab7;
}
}
}
.detail{
color: var(--g-fc-1);
color: var(--g-fc-1) !important;
background-color:var(--g-bgc-1);
box-shadow: var(--g-bsc-2);
.detail-content{
@@ -146,10 +111,17 @@
}
}
.detail-body{
.info, .desc, .m3u8_urls, .mp4_urls{
.info, .desc, .m3u8, .operate{
border-color: var(--g-c-2);
}
.m3u8_urls, .mp4_urls{
.operate{
span{
&:hover{
color: var(--g-fc-2);
}
}
}
.m3u8{
.box{
span{
border-color: var(--g-c-5);
@@ -164,44 +136,16 @@
}
}
}
.film{
.top{
.search{
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
&:hover{
box-shadow: var(--g-bsc-hover);
}
svg{
stroke: var(--g-c-0);
stroke-width: 1;
fill: none;
}
.search-box{
background-color: var(--g-bgc-1);
}
&.active{
box-shadow: var(--g-bsc-hover);
svg{
stroke-width: 1.5;
fill: var(--g-c-2);
}
}
input{
color: var(--g-fc-1);
}
}
}
.middle{
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
}
}
.play{
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
.title{
color: var(--g-fc-1);
.right {
svg {
fill: var(--g-fc-1);
}
}
}
.box{
.more{
@@ -225,6 +169,10 @@
fill: var(--g-c-3);
}
}
&.last-tip {
color: var(--g-fc-1);
font-size: 14px;
}
}
}
}
@@ -254,6 +202,9 @@
background-color: var(--g-c-2);
color: var(--g-fc-3);
}
&:hover{
background-color: var(--g-c-3);
}
}
}
.list-history{
@@ -283,14 +234,6 @@
}
}
}
.play-mask{
background-color: var(--g-bgc-1);
color: var(--g-fc-1);
}
}
.star{
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
}
.setting{
background-color: var(--g-bgc-1);
@@ -303,12 +246,18 @@
}
}
}
.view, .search, .shortcut, .site{
.title{
color: var(--g-fc-1);
}
}
.theme{
.title{
color: var(--g-fc-1);
}
.theme-item{
box-shadow: var(--g-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--g-bsc-hover);
.theme-name{
@@ -326,6 +275,10 @@
}
.qrcode-item{
box-shadow: var(--g-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--g-bsc-hover);
}
}
}
}
@@ -343,4 +296,118 @@
background-color: var(--g-bgc-1);
}
}
.history{
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
}
// Page of list using table and picture
.listpage{
color: var(--g-fc-2);
.listpage-header{
border-bottom-color: var(--g-c-3);
.btn{
&:hover{
color: var(--g-fc-3)
}
}
.el-button{
background-color: var(--g-bgc-2);
color: var(--g-fc-2);
&:hover{
color: var(--g-fc-3)
}
}
.el-input{
input{
background-color: var(--g-bgc-1);
border: 1px solid var(--g-bgc-1);
color: var(--g-fc-2);
}
}
.el-input-group__prepend{
background-color: var(--g-bgc-1);
}
.popper {
color: var(--g-fc-1);
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
li {
color: var(--g-fc-1);
background-color: var(--g-bgc-1);
&:hover{
background-color: var(--g-bgc-2);
}
}
}
.popper__arrow, .popper__arrow::after{
border-bottom-color: var(--g-bgc-1);
}
}
.listpage-body{
color: var(--g-fc-1);
background-color: var(--g-bgc-1);
&:hover{
&::-webkit-scrollbar-thumb {
box-shadow: var(--g-bsc-scroll);
background: var(--g-c-5);
}
&::-webkit-scrollbar-track {
box-shadow: var(--g-bsc-scroll);
background: var(--g-bgc-1);
}
}
/* 设置el-table的样式*/
.show-table{
.el-table{
color: var(--g-fc-1);
background-color: var(--g-bgc-1);
}
.el-table__body-wrapper{
&:hover{
&::-webkit-scrollbar-thumb {
box-shadow: var(--g-bsc-scroll);
background: var(--g-c-5);
}
&::-webkit-scrollbar-track {
box-shadow: var(--g-bsc-scroll);
background: var(--g-bgc-1);
}
}
}
.el-input{
input{
background-color: var(--g-bgc-2);
border: 1px solid var(--g-bgc-2);
color: var(--g-fc-1);
}
}
.el-table__header th, .el-table__header tr, .el-table__body td,.el-table__body th{
color: var(--g-fc-1);
background-color: var(--g-bgc-1);
border-bottom-color: var(--g-c-2);
}
.el-table--enable-row-hover .el-table__body tr:hover>td{
background-color: var(--g-bgc-2);
}
.el-button{
color: var(--g-fc-1);
&:hover{
color: var(--g-fc-3)
}
}
}
.show-picture{
color: var(--g-fc-1);
.card{
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--g-bsc-hover);
}
}
}
}
}
}

View File

@@ -1,28 +1,10 @@
.theme-light{
background-color: var(--l-bgc-1);
.el-pagination{
color: var(--l-fc-1);
.el-pagination__total, .el-pagination__jump, .el-input__inner{
color: var(--l-fc-1);
}
.el-pager{
.number:hover{
color: var(--l-c-8);
}
.active{
color: var(--l-c-9);
}
}
.more, .btn-next, .btn-prev{
&:hover{
color: var(--l-c-8);
}
}
}
.zy-select{
color: var(--l-fc-1);
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--l-bsc-hover);
}
@@ -30,6 +12,7 @@
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
ul{
overflow-y: scroll;
li{
&:hover{
background-color: var(--l-c-1);
@@ -40,49 +23,33 @@
}
}
}
}
.zy-table{
color: var(--l-fc-2);
.tHead{
.vs-input{
color: var(--l-fc-1);
background-color: var(--l-bgc-1);
border-bottom-color: var(--l-c-3);
}
.tBody{
border-bottom-color: var(--l-c-3);
ul{
li{
border-bottom-color: var(--l-c-2);
&:hover{
animation: l-tableHoverAni 0.2s ease both;
@keyframes l-tableHoverAni {
to{
box-shadow: var(--l-bsc-hover);
}
}
}
span{
&.btn:hover{
color: var(--l-fc-3)
}
}
input{
color: var(--l-fc-1);
&::-webkit-input-placeholder{
color: var(--l-fc-1);
}
}
}
.tFooter{
.tFooter-span{
color: var(--l-fc-1);
}
}
.zy-input{
color: var(--l-fc-1);
background-color: var(--l-bgc-1);
input{
color: var(--l-fc-1);
}
}
.zy-scroll{
&:hover{
&::-webkit-scrollbar-thumb {
box-shadow: var(--l-bsc-scroll);
background: var(--l-c-3);
background: var(--l-c-5);
}
&::-webkit-scrollbar-track {
box-shadow: var(--l-bsc-scroll);
background: var(--bgc);
background: var(--l-bgc-1);
}
}
}
@@ -103,6 +70,7 @@
background-color: var(--l-c-2);
}
&.active{
background-color: var(--l-bgc-2);
svg{
stroke: var(--l-c-0);
stroke-width: 2;
@@ -114,15 +82,21 @@
.frame{
span{
&.min{
background-color: #32dc36;
}
&.max{
background-color: #ffbe2a;
}
&.close{
background-color: #ff5f56;
}
&.top{
background-color: #f3bab7;
}
}
}
.detail{
color: var(--l-fc-1);
color: var(--l-fc-1) !important;
background-color:var(--l-bgc-1);
box-shadow: var(--l-bsc-2);
.detail-content{
@@ -137,10 +111,17 @@
}
}
.detail-body{
.info, .desc, .m3u8_urls, .mp4_urls{
.info, .desc, .m3u8, .operate{
border-color: var(--l-c-2);
}
.m3u8_urls, .mp4_urls{
.operate{
span{
&:hover{
color: var(--l-fc-2);
}
}
}
.m3u8{
.box{
span{
border-color: var(--l-c-5);
@@ -155,44 +136,16 @@
}
}
}
.film{
.top{
.search{
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
&:hover{
box-shadow: var(--l-bsc-hover);
}
svg{
stroke: #823aa099;
stroke-width: 1;
fill: none;
}
.search-box{
background-color: none;
}
&.active{
box-shadow: var(--l-bsc-hover);
svg{
stroke-width: 1.5;
fill: var(--l-c-2);
}
}
input{
color: var(--l-fc-1);
}
}
}
.middle{
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
}
}
.play{
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
.title{
color: var(--d-fc-1);
color: var(--l-fc-1);
.right {
svg {
fill: var(--l-fc-1);
}
}
}
.box{
.more{
@@ -216,11 +169,12 @@
fill: var(--l-c-3);
}
}
&.last-tip {
color: var(--l-fc-1);
font-size: 14px;
}
}
}
.mask{
background-color: var(--l-bgc-1);
}
}
.list{
border: 1px solid var(--l-c-3);
@@ -248,6 +202,9 @@
background-color: var(--l-c-2);
color: var(--l-fc-3);
}
&:hover{
background-color: var(--l-c-3);
}
}
}
.list-history{
@@ -277,14 +234,6 @@
}
}
}
.play-mask{
background-color: var(--l-bgc-1);
color: var(--l-fc-1);
}
}
.star{
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
}
.setting{
background-color: var(--l-bgc-1);
@@ -297,12 +246,18 @@
}
}
}
.view, .search, .shortcut, .site{
.title{
color: var(--l-fc-1);
}
}
.theme{
.title{
color: var(--l-fc-1);
}
.theme-item{
box-shadow: var(--l-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--l-bsc-hover);
.theme-name{
@@ -320,6 +275,10 @@
}
.qrcode-item{
box-shadow: var(--l-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--l-bsc-hover);
}
}
}
}
@@ -337,4 +296,118 @@
background-color: var(--l-bgc-1);
}
}
.history{
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
}
// Page of list using table and picture
.listpage{
color: var(--l-fc-2);
.listpage-header{
border-bottom-color: var(--l-c-3);
.btn{
&:hover{
color: var(--l-fc-3)
}
}
.el-button{
background-color: var(--l-bgc-2);
color: var(--l-fc-2);
&:hover{
color: var(--l-fc-3)
}
}
.el-input{
input{
background-color: var(--l-bgc-1);
border: 1px solid var(--l-bgc-1);
color: var(--l-fc-2);
}
}
.el-input-group__prepend{
background-color: var(--l-bgc-1);
}
.popper {
color: var(--l-fc-1);
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
li {
color: var(--l-fc-1);
background-color: var(--l-bgc-1);
&:hover{
background-color: var(--l-bgc-2);
}
}
}
.popper__arrow, .popper__arrow::after{
border-bottom-color: var(--l-bgc-1);
}
}
.listpage-body{
color: var(--l-fc-1);
background-color: var(--l-bgc-1);
&:hover{
&::-webkit-scrollbar-thumb {
box-shadow: var(--l-bsc-scroll);
background: var(--l-c-5);
}
&::-webkit-scrollbar-track {
box-shadow: var(--l-bsc-scroll);
background: var(--l-bgc-1);
}
}
/* 设置el-table的样式*/
.show-table{
.el-table{
color: var(--l-fc-1);
background-color: var(--l-bgc-1);
}
.el-table__body-wrapper{
&:hover{
&::-webkit-scrollbar-thumb {
box-shadow: var(--l-bsc-scroll);
background: var(--l-c-5);
}
&::-webkit-scrollbar-track {
box-shadow: var(--l-bsc-scroll);
background: var(--l-bgc-1);
}
}
}
.el-input{
input{
background-color: var(--l-bgc-2);
border: 1px solid var(--l-bgc-2);
color: var(--l-fc-1);
}
}
.el-table__header th, .el-table__header tr, .el-table__body td,.el-table__body th{
color: var(--l-fc-1);
background-color: var(--l-bgc-1);
border-bottom-color: var(--l-c-2);
}
.el-table--enable-row-hover .el-table__body tr:hover>td{
background-color: var(--l-bgc-2);
}
.el-button{
color: var(--l-fc-1);
&:hover{
color: var(--l-fc-3)
}
}
}
.show-picture{
color: var(--l-fc-1);
.card{
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--l-bsc-hover);
}
}
}
}
}
}

View File

@@ -1,37 +1,10 @@
.theme-pink{
background-color: var(--p-bgc-1);
.el-pagination{
background-color: var(--p-bgc-1);
color: var(--p-fc-1);
.el-pagination__total, .el-pagination__jump, .el-input__inner{
color: var(--p-fc-1);
background-color: var(--p-bgc-1);
}
.el-input__inner{
border-color: var(--p-c-3);
}
.el-pager{
.number{
background-color: var(--p-bgc-1);
}
.number:hover{
color: var(--p-c-8);
}
.active{
color: var(--p-c-9);
}
}
.more, .btn-next, .btn-prev{
background-color: var(--p-bgc-1);
&:hover{
color: var(--p-c-8);
}
}
}
.zy-select{
color: var(--p-fc-1);
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--p-bsc-hover);
}
@@ -39,6 +12,7 @@
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
ul{
overflow-y: scroll;
li{
&:hover{
background-color: var(--p-c-1);
@@ -49,49 +23,33 @@
}
}
}
}
.zy-table{
color: var(--p-fc-2);
.tHead{
.vs-input{
color: var(--p-fc-1);
background-color: var(--p-bgc-1);
border-bottom-color: var(--p-c-3);
}
.tBody{
border-bottom-color: var(--p-c-3);
ul{
li{
border-bottom-color: var(--p-c-2);
&:hover{
animation: d-tableHoverAni 0.2s ease both;
@keyframes d-tableHoverAni {
to{
box-shadow: var(--p-bsc-hover);
}
}
}
span{
&.btn:hover{
color: var(--p-fc-3)
}
}
input{
color: var(--p-fc-1);
&::-webkit-input-placeholder{
color: var(--p-fc-1);
}
}
}
.tFooter{
.tFooter-span{
color: var(--p-fc-1);
}
}
.zy-input{
color: var(--p-fc-1);
background-color: var(--p-bgc-1);
input{
color: var(--p-fc-1);
}
}
.zy-scroll{
&:hover{
&::-webkit-scrollbar-thumb {
box-shadow: var(--p-bsc-scroll);
background: var(--p-c-3);
background: var(--p-c-5);
}
&::-webkit-scrollbar-track {
box-shadow: var(--p-bsc-scroll);
background: var(--bgc);
background: var(--p-bgc-1);
}
}
}
@@ -112,6 +70,7 @@
background-color: var(--p-c-2);
}
&.active{
background-color: var(--p-bgc-2);
svg{
stroke: var(--p-c-0);
stroke-width: 2;
@@ -123,15 +82,21 @@
.frame{
span{
&.min{
background-color: #32dc36;
}
&.max{
background-color: #ffbe2a;
}
&.close{
background-color: #ff5f56;
}
&.top{
background-color: #f3bab7;
}
}
}
.detail{
color: var(--p-fc-1);
color: var(--p-fc-1) !important;
background-color:var(--p-bgc-1);
box-shadow: var(--p-bsc-2);
.detail-content{
@@ -146,10 +111,17 @@
}
}
.detail-body{
.info, .desc, .m3u8_urls, .mp4_urls{
.info, .desc, .m3u8, .operate{
border-color: var(--p-c-2);
}
.m3u8_urls, .mp4_urls{
.operate{
span{
&:hover{
color: var(--p-fc-2);
}
}
}
.m3u8{
.box{
span{
border-color: var(--p-c-5);
@@ -164,44 +136,16 @@
}
}
}
.film{
.top{
.search{
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
&:hover{
box-shadow: var(--p-bsc-hover);
}
svg{
stroke: var(--p-c-0);
stroke-width: 1;
fill: none;
}
.search-box{
background-color: var(--p-bgc-1);
}
&.active{
box-shadow: var(--p-bsc-hover);
svg{
stroke-width: 1.5;
fill: var(--p-c-2);
}
}
input{
color: var(--p-fc-1);
}
}
}
.middle{
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
}
}
.play{
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
.title{
color: var(--p-fc-1);
.right {
svg {
fill: var(--p-fc-1);
}
}
}
.box{
.more{
@@ -225,6 +169,10 @@
fill: var(--p-c-3);
}
}
&.last-tip {
color: var(--p-fc-1);
font-size: 14px;
}
}
}
}
@@ -254,6 +202,9 @@
background-color: var(--p-c-2);
color: var(--p-fc-3);
}
&:hover{
background-color: var(--p-c-3);
}
}
}
.list-history{
@@ -283,14 +234,6 @@
}
}
}
.play-mask{
background-color: var(--p-bgc-1);
color: var(--p-fc-1);
}
}
.star{
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
}
.setting{
background-color: var(--p-bgc-1);
@@ -303,12 +246,18 @@
}
}
}
.view, .search, .shortcut, .site{
.title{
color: var(--p-fc-1);
}
}
.theme{
.title{
color: var(--p-fc-1);
}
.theme-item{
box-shadow: var(--p-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--p-bsc-hover);
.theme-name{
@@ -326,6 +275,10 @@
}
.qrcode-item{
box-shadow: var(--p-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--p-bsc-hover);
}
}
}
}
@@ -343,4 +296,118 @@
background-color: var(--p-bgc-1);
}
}
.history{
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
}
// Page of list using table and picture
.listpage{
color: var(--p-fc-2);
.listpage-header{
border-bottom-color: var(--p-c-3);
.btn{
&:hover{
color: var(--p-fc-3)
}
}
.el-button{
background-color: var(--p-bgc-2);
color: var(--p-fc-2);
&:hover{
color: var(--p-fc-3)
}
}
.el-input{
input{
background-color: var(--p-bgc-1);
border: 1px solid var(--p-bgc-1);
color: var(--p-fc-2);
}
}
.el-input-group__prepend{
background-color: var(--p-bgc-1);
}
.popper {
color: var(--p-fc-1);
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
li {
color: var(--p-fc-1);
background-color: var(--p-bgc-1);
&:hover{
background-color: var(--p-bgc-2);
}
}
}
.popper__arrow, .popper__arrow::after{
border-bottom-color: var(--p-bgc-1);
}
}
.listpage-body{
color: var(--p-fc-1);
background-color: var(--p-bgc-1);
&:hover{
&::-webkit-scrollbar-thumb {
box-shadow: var(--p-bsc-scroll);
background: var(--p-c-5);
}
&::-webkit-scrollbar-track {
box-shadow: var(--p-bsc-scroll);
background: var(--p-bgc-1);
}
}
/* 设置el-table的样式*/
.show-table{
.el-table{
color: var(--p-fc-1);
background-color: var(--p-bgc-1);
}
.el-table__body-wrapper{
&:hover{
&::-webkit-scrollbar-thumb {
box-shadow: var(--p-bsc-scroll);
background: var(--p-c-5);
}
&::-webkit-scrollbar-track {
box-shadow: var(--p-bsc-scroll);
background: var(--p-bgc-1);
}
}
}
.el-input{
input{
background-color: var(--p-bgc-2);
border: 1px solid var(--p-bgc-2);
color: var(--p-fc-1);
}
}
.el-table__header th, .el-table__header tr, .el-table__body td,.el-table__body th{
color: var(--p-fc-1);
background-color: var(--p-bgc-1);
border-bottom-color: var(--p-c-2);
}
.el-table--enable-row-hover .el-table__body tr:hover>td{
background-color: var(--p-bgc-2);
}
.el-button{
color: var(--p-fc-1);
&:hover{
color: var(--p-fc-3)
}
}
}
.show-picture{
color: var(--p-fc-1);
.card{
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--p-bsc-hover);
}
}
}
}
}
}

View File

@@ -1,71 +1,69 @@
'use strict'
import { app, ipcMain, protocol, BrowserWindow } from 'electron'
import {
createProtocol
// installVueDevtools
} from 'vue-cli-plugin-electron-builder/lib'
import path from 'path'
import { autoUpdater } from 'electron-updater'
import './lib/site/server'
import { app, protocol, BrowserWindow, globalShortcut, ipcMain } from 'electron'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
import { initUpdater } from './lib/update/update'
const isDevelopment = process.env.NODE_ENV !== 'production'
const globalShortcut = require('electron').globalShortcut
app.commandLine.appendSwitch('disable-features', 'OutOfBlinkCors') // 允许跨域
// app.commandLine.appendSwitch('--ignore-certificate-errors', 'true') // 忽略证书相关错误
let win
let mini
// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([{ scheme: 'app', privileges: { secure: true, standard: true } }])
function createWindow() {
function createWindow () {
win = new BrowserWindow({
width: 1080,
height: 720,
frame: false,
resizable: true,
transparent: true,
webPreferences: {
webSecurity: false,
enableRemoteModule: true,
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION
},
// eslint-disable-next-line
icon: path.join(__static, 'icon.png')
}
})
if (process.env.WEBPACK_DEV_SERVER_URL) {
win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
if (!process.env.IS_TEST) win.webContents.openDevTools()
} else {
createProtocol('app')
win.loadURL('app://./index.html')
autoUpdater.checkForUpdatesAndNotify()
}
initUpdater(win)
win.on('closed', () => {
win = null
})
}
function createMini() {
function createMini () {
mini = new BrowserWindow({
width: 550,
minWidth: 260,
miniWidth: 860,
height: 340,
minHeight: 180,
miniHeight: 180,
frame: false,
resizable: true,
transparent: true,
alwaysOnTop: true,
webPreferences: {
sandbox: false,
webSecurity: false,
enableRemoteModule: true,
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION
},
// eslint-disable-next-line
icon: path.join(__static, 'icon.png')
}
})
if (process.env.WEBPACK_DEV_SERVER_URL) {
mini.loadURL(process.env.WEBPACK_DEV_SERVER_URL + 'mini')
if (!process.env.IS_TEST) mini.webContents.openDevTools()
} else {
createProtocol('app')
mini.loadURL('app://./mini.html')
}
@@ -77,12 +75,11 @@ function createMini() {
if (process.platform === 'darwin') {
app.dock.show()
}
app.allowRendererProcessReuse = true
app.commandLine.appendSwitch('disable-features', 'OutOfBlinkCors')
if (process.platform === 'Linux') {
app.disableHardwareAcceleration()
app.commandLine.appendSwitch('--no-sandbox') // linux 关闭沙盒模式
}
app.allowRendererProcessReuse = true
app.on('window-all-closed', () => {
app.quit()
@@ -92,31 +89,17 @@ app.on('activate', () => {
if (win === null) {
createWindow()
}
if (mini === null) {
createMini()
}
})
ipcMain.on('min', () => {
win.minimize()
})
ipcMain.on('close', () => {
win.close()
})
ipcMain.on('mini', () => {
createMini()
win.close()
win.hide()
})
ipcMain.on('miniMin', () => {
mini.minimize()
})
ipcMain.on('miniClose', () => {
mini.close()
createWindow()
})
ipcMain.on('miniOpacity', (e, arg) => {
mini.setOpacity(arg)
ipcMain.on('win', () => {
mini.destroy()
win.show()
win.webContents.send('miniClosed')
})
const gotTheLock = app.requestSingleInstanceLock()
@@ -124,65 +107,31 @@ if (!gotTheLock) {
app.quit()
} else {
app.on('second-instance', (event, commandLine, workingDirectory) => {
// 当运行第二个实例时,将会聚焦到win这个窗口
if (win) {
if (win.isMinimized()) win.restore()
win.focus()
}
})
// 创建 win, 加载应用的其余部分, etc...
app.on('ready', () => {
globalShortcut.register('CommandOrControl+right', function () {
if (win) {
win.webContents.send('next', 0)
app.on('ready', async () => {
if (isDevelopment && !process.env.IS_TEST) {
try {
await installExtension(VUEJS_DEVTOOLS)
} catch (e) {
console.error('Vue Devtools failed to install:', e.toString())
}
if (mini) {
mini.webContents.send('next', 0)
}
})
globalShortcut.register('CommandOrControl+left', function () {
if (win) {
win.webContents.send('prev', 0)
}
if (mini) {
mini.webContents.send('prev', 0)
}
})
globalShortcut.register('CommandOrControl+up', function () {
if (mini) {
mini.webContents.send('up', 0)
}
})
globalShortcut.register('CommandOrControl+down', function () {
if (mini) {
mini.webContents.send('down', 0)
}
})
globalShortcut.register('shift+up', function () {
if (win) {
win.webContents.send('playbackRateUp', 0)
}
if (mini) {
mini.webContents.send('playbackRateUp', 0)
}
})
globalShortcut.register('shift+down', function () {
if (win) {
win.webContents.send('playbackRateDown', 0)
}
if (mini) {
mini.webContents.send('playbackRateDown', 0)
}
})
if (!process.env.WEBPACK_DEV_SERVER_URL) {
createProtocol('app')
}
createWindow()
globalShortcut.register('Alt+Space', () => {
if (win) {
win.isFocused() ? win.blur() : win.focus()
}
if (mini) {
mini.isFocused() ? mini.blur() : mini.focus()
}
})
})
}
// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
if (process.platform === 'win32') {
process.on('message', data => {

View File

@@ -2,7 +2,7 @@
<div class="aside">
<span :class="[view === 'Film' ? 'active ': ''] + 'zy-svg'" @click="changeView('Film')">
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="apertureIconTitle">
<title id="apertureIconTitle">{{$t('view')}}</title>
<title id="apertureIconTitle">电影</title>
<path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z"></path>
<g stroke-linecap="round">
<path d="M3 16H14.3164"></path>
@@ -14,21 +14,42 @@
</g>
</svg>
</span>
<span :class="[view === 'Recommendation' ? 'active ': ''] + 'zy-svg'" @click="changeView('Recommendation')">
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="48px" height="48px" viewBox="0 0 24 24" aria-labelledby="thumbUpIconTitle" stroke="#2329D6" stroke-width="1" stroke-linecap="square" stroke-linejoin="miter" fill="none" color="#2329D6">
<title id="thumbUpIconTitle">影视推荐</title>
<path d="M8,8.73984815 C8,8.26242561 8.17078432,7.80075162 8.4814868,7.43826541 L13.2723931,1.84887469 C13.7000127,1.34998522 14.4122932,1.20614658 15,1.5 C15.5737957,1.78689785 15.849314,2.45205792 15.6464466,3.06066017 L14,8 L18.6035746,8 C18.7235578,8 18.8432976,8.01079693 18.9613454,8.03226018 C20.0480981,8.22985158 20.7689058,9.27101818 20.5713144,10.3577709 L19.2985871,17.3577709 C19.1256814,18.3087523 18.2974196,19 17.3308473,19 L10,19 C8.8954305,19 8,18.1045695 8,17 L8,8.73984815 Z"/>
<path d="M4,18 L4,9"/>
</svg>
</span>
<span :class="[view === 'IPTV' ? 'active ': ''] + 'zy-svg'" @click="changeView('IPTV')">
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="tvIconTitle">
<title id="tvIconTitle">电视直播</title>
<polygon points="20 8 20 20 4 20 4 8"></polygon>
<polyline stroke-linejoin="round" points="8 4 12 7.917 16 4"></polyline>
</svg>
</span>
<span :class="[view === 'Play' ? 'active ': ''] + 'zy-svg'" @click="changeView('Play')">
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="playIconTitle">
<title id="playIconTitle">{{$t('play')}}</title>
<title id="playIconTitle">播放</title>
<path d="M20 12L5 21V3z"></path>
</svg>
</span>
<span :class="[view === 'Star' ? 'active ': ''] + 'zy-svg'" @click="changeView('Star')">
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="favouriteIconTitle">
<title id="favouriteIconTitle">{{$t('star')}}</title>
<title id="favouriteIconTitle">收藏</title>
<path d="M12,21 L10.55,19.7051771 C5.4,15.1242507 2,12.1029973 2,8.39509537 C2,5.37384196 4.42,3 7.5,3 C9.24,3 10.91,3.79455041 12,5.05013624 C13.09,3.79455041 14.76,3 16.5,3 C19.58,3 22,5.37384196 22,8.39509537 C22,12.1029973 18.6,15.1242507 13.45,19.7149864 L12,21 Z"></path>
</svg>
</span>
<span :class="[view === 'History' ? 'active ': ''] + 'zy-svg'" @click="changeView('History')">
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="timeIconTitle">
<title id="timeIconTitle">历史记录</title>
<circle cx="12" cy="12" r="10"></circle>
<polyline points="12 5 12 12 16 16"></polyline>
</svg>
</span>
<span :class="[view === 'Setting' ? 'active ': ''] + 'zy-svg'" @click="changeView('Setting')">
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="settingsIconTitle">
<title id="settingsIconTitle">{{$t('setting')}}</title>
<title id="settingsIconTitle">设置</title>
<path d="M5.03506429,12.7050339 C5.01187484,12.4731696 5,12.2379716 5,12 C5,11.7620284 5.01187484,11.5268304 5.03506429,11.2949661 L3.20577137,9.23205081 L5.20577137,5.76794919 L7.9069713,6.32070904 C8.28729123,6.0461342 8.69629298,5.80882212 9.12862533,5.61412402 L10,3 L14,3 L14.8713747,5.61412402 C15.303707,5.80882212 15.7127088,6.0461342 16.0930287,6.32070904 L18.7942286,5.76794919 L20.7942286,9.23205081 L18.9649357,11.2949661 C18.9881252,11.5268304 19,11.7620284 19,12 C19,12.2379716 18.9881252,12.4731696 18.9649357,12.7050339 L20.7942286,14.7679492 L18.7942286,18.2320508 L16.0930287,17.679291 C15.7127088,17.9538658 15.303707,18.1911779 14.8713747,18.385876 L14,21 L10,21 L9.12862533,18.385876 C8.69629298,18.1911779 8.28729123,17.9538658 7.9069713,17.679291 L5.20577137,18.2320508 L3.20577137,14.7679492 L5.03506429,12.7050339 Z"></path>
<circle cx="12" cy="12" r="1"></circle>
</svg>
@@ -47,12 +68,23 @@ export default {
set (val) {
this.SET_VIEW(val)
}
},
detail: {
get () {
return this.$store.getters.getDetail
},
set (val) {
this.SET_DETAIL(val)
}
}
},
methods: {
...mapMutations(['SET_VIEW']),
...mapMutations(['SET_VIEW', 'SET_DETAIL']),
changeView (e) {
this.view = e
this.detail = {
show: false
}
}
}
}
@@ -61,17 +93,17 @@ export default {
.aside{
width: 60px;
height: 100%;
user-select: none;
-webkit-app-region: drag;
display: flex;
justify-content: center;
user-select: none;
align-items: center;
flex-direction: column;
justify-content: center;
-webkit-app-region: drag;
span{
-webkit-app-region: no-drag;
width: 60px;
height: 60px;
cursor: pointer;
-webkit-app-region: no-drag;
}
}
</style>

View File

@@ -2,28 +2,60 @@
<div class="detail">
<div class="detail-content">
<div class="detail-header">
<span class="detail-title">{{$t('detail')}}</span>
<span class="detail-close zy-svg" @click="closeDetail">
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="closeIconTitle">
<title id="closeIconTitle">{{$t('close')}}</title>
<span class="detail-title">详情</span>
<span class="detail-close zy-svg" @click="close">
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
aria-labelledby="closeIconTitle"
>
<title id="closeIconTitle">关闭</title>
<path d="M6.34314575 6.34314575L17.6568542 17.6568542M6.34314575 17.6568542L17.6568542 6.34314575"></path>
</svg>
</span>
</div>
<div class="detail-body zy-scroll" v-show="!loading" :style="{overflowY:scroll? 'auto' : 'hidden',paddingRight: scroll ? '0': '5px' }" @mouseenter="scroll = true" @mouseleave="scroll = false">
<div class="info" v-html="vDetail.info"></div>
<div class="desc" v-html="vDetail.desc" v-if="show.desc"></div>
<div class="m3u8_urls">
<div class="title">{{$t('play')}}:</div>
<div class="box">
<span v-for="(i, j) in vDetail.m3u8_urls" :key="j" @click="playEvent(j)">{{i | ftName}}</span>
<div class="detail-body zy-scroll" v-show="!loading">
<div class="info">
<div class="info-left">
<img :src="info.pic" alt="">
</div>
<div class="info-right">
<div class="name">{{info.name}}</div>
<div class="director" v-show="info.director">导演: {{info.director}}</div>
<div class="actor" v-show="info.actor">主演: {{info.actor}}</div>
<div class="type" v-show="info.type">类型: {{info.type}}</div>
<div class="area" v-show="info.area">地区: {{info.area}}</div>
<div class="lang" v-show="info.lang">语言: {{info.lang}}</div>
<div class="year" v-show="info.year">上映: {{info.year}}</div>
<div class="last" v-show="info.last">更新: {{info.last}}</div>
<div class="note" v-show="info.note">备注: {{info.note}}</div>
<div class="rate" v-show="info.rate">豆瓣评分: {{info.rate}}</div>
</div>
</div>
<div class="mp4_urls" v-if="show.download">
<div class="title">{{$t('download')}}:</div>
<div class="operate">
<span @click="playEvent(0)">播放</span>
<span @click="starEvent">收藏</span>
<span @click="downloadEvent">下载</span>
<span @click="shareEvent">分享</span>
<span @click="doubanLinkEvent">豆瓣</span>
<span @click="togglePlayOnlineEvent">
<input type="checkbox" v-model="playOnline"> 播放在线高清视频
</span>
<span>
<select v-model="selectedOnlineSite" class="vs-options">
<option disabled value="">Please select one</option>
<option v-for="(i, j) in onlineSites" :key="j">{{i}}</option>
</select>
</span>
</div>
<div
class="desc" v-show="info.des">{{info.des}}</div>
<div class="m3u8">
<div class="box">
<span v-for="(i, j) in vDetail.mp4_urls" :key="j" @click="download(i)">{{i | ftName}}</span>
<span @click="allDownload" v-show="vDetail.mp4_urls.length > 1">{{$t('all_download')}}</span>
<span v-for="(i, j) in m3u8List" :key="j" @click="playEvent(j)">{{i | ftName}}</span>
</div>
</div>
</div>
@@ -35,19 +67,20 @@
</template>
<script>
import { mapMutations } from 'vuex'
import tools from '../lib/site/tools'
import zy from '../lib/site/tools'
import onlineVideo from '../lib/site/onlineVideo'
import { star, history } from '../lib/dexie'
const { clipboard } = require('electron')
export default {
name: 'detail',
data () {
return {
scroll: false,
loading: true,
vDetail: {},
show: {
desc: false,
download: false
}
m3u8List: [],
info: {},
playOnline: false,
selectedOnlineSite: '哔嘀',
onlineSites: ['哔嘀', '素白白', '简影', '极品', '喜欢看', '1080影视']
}
},
filters: {
@@ -65,6 +98,14 @@ export default {
this.SET_VIEW(val)
}
},
detail: {
get () {
return this.$store.getters.getDetail
},
set (val) {
this.SET_DETAIL(val)
}
},
video: {
get () {
return this.$store.getters.getVideo
@@ -73,274 +114,341 @@ export default {
this.SET_VIDEO(val)
}
},
detail: {
share: {
get () {
return this.$store.getters.getDetail
return this.$store.getters.getShare
},
set (val) {
this.SET_DETAIL(val)
this.SET_SHARE(val)
}
}
},
methods: {
...mapMutations(['SET_VIEW', 'SET_VIDEO', 'SET_DETAIL']),
closeDetail () {
...mapMutations(['SET_VIEW', 'SET_VIDEO', 'SET_DETAIL', 'SET_SHARE']),
close () {
this.detail.show = false
},
getDetail () {
tools.detail_get(this.detail.v.site, this.detail.v.detail).then(res => {
this.vDetail = res
if (res.desc.length > 0) {
this.show.desc = true
async playEvent (n) {
if (!this.playOnline) {
console.log(this.detail)
const db = await history.find({ site: this.detail.key, ids: this.detail.info.id })
if (db) {
this.video = { key: db.site, info: { id: db.ids, name: db.name, index: n, site: this.detail.site } }
} else {
this.video = { key: this.detail.key, info: { id: this.detail.info.id, name: this.detail.info.name, index: n, site: this.detail.site } }
}
if (res.mp4_urls.length > 0) {
this.show.download = true
this.video.detail = this.info
this.view = 'Play'
this.detail.show = false
} else {
const db = await history.find({ site: this.detail.key, ids: this.detail.info.id })
if (db) {
db.index = n
db.detail = this.info
history.update(db.id, db)
} else {
const doc = {
site: this.detail.key,
ids: this.detail.info.id,
name: this.detail.info.name,
type: this.detail.info.type,
year: this.detail.info.year,
index: n,
time: '',
detail: this.info
}
history.add(doc)
}
this.$nextTick(() => {
this.loading = false
onlineVideo.playVideoOnline(this.selectedOnlineSite, this.detail.info.name, n)
}
},
async starEvent () {
const db = await star.find({ key: this.detail.key, ids: this.info.id })
const doc = {
key: this.detail.key,
ids: this.info.id,
site: this.detail.site,
name: this.info.name,
detail: this.info,
rate: this.info.rate
}
if (db) {
star.update(db.id, doc)
this.$message.success('收藏更新成功')
} else {
star.add(doc).then(res => {
this.$message.success('收藏成功')
})
}
},
togglePlayOnlineEvent () {
this.playOnline = !this.playOnline
},
playVideoOnline (videoName, videoIndex) {
switch (this.selectedOnlineSite) {
case '哔嘀':
onlineVideo.playVideoOnBde4(videoName, videoIndex)
break
case '1080影视':
onlineVideo.playVideoOnK1080(videoName, videoIndex)
break
case '素白白':
onlineVideo.playVideoOnSubaibai(videoName, videoIndex)
break
case '哆咪动漫':
onlineVideo.playVideoOndmdm2020(videoName, videoIndex)
break
case '樱花动漫':
onlineVideo.playVideoOnYhdm(videoName, videoIndex)
break
case '简影':
onlineVideo.playVideoOnSyrme(videoName, videoIndex)
break
case '极品':
onlineVideo.playVideoOnJpysvip(videoName, videoIndex)
break
default:
this.$message.console.error(`不支持该网站:${this.selectedOnlineSite}`)
}
},
downloadEvent () {
zy.download(this.detail.key, this.info.id).then(res => {
if (res && res.dl && res.dl.dd) {
const text = res.dl.dd._t
if (text) {
const list = text.split('#')
let downloadUrl = res.name + '\n'
for (const i of list) {
const url = encodeURI(i.split('$')[1])
downloadUrl += (url + '\n')
}
clipboard.writeText(downloadUrl)
this.$message.success('『MP4』格式的链接已复制, 快去下载吧!')
} else {
this.$message.warning('没有查询到下载链接.')
}
} else {
const list = [...this.m3u8List]
let downloadUrl = this.detail.info.name + '\n'
for (const i of list) {
const url = encodeURI(i.split('$')[1])
downloadUrl += (url + '\n')
}
clipboard.writeText(downloadUrl)
this.$message.success('『M3U8』格式的链接已复制, 快去下载吧!')
}
})
},
playEvent (n) {
const v = { ...this.detail.v }
v.index = n
this.video = v
this.detail.show = false
this.view = 'Play'
},
download (e) {
const name = e.split('$')[0]
const txt = encodeURI(e.split('$')[1])
clipboard.writeText(txt)
this.$m.success(name + this.$t('copy_success'))
},
allDownload () {
const urls = [...this.vDetail.mp4_urls]
let txt = ''
for (const i of urls) {
const url = encodeURI(i.split('$')[1])
txt += (url + '\n')
shareEvent () {
this.share = {
show: true,
key: this.detail.key,
info: this.detail.info
}
clipboard.writeText(txt)
this.$m.success(this.$t('copy_success'))
},
doubanLinkEvent () {
const name = this.detail.info.name.trim()
zy.doubanLink(name).then(link => {
const open = require('open')
open(link)
})
},
getDoubanRate () {
const name = this.detail.info.name.trim()
zy.doubanRate(name).then(res => {
this.info.rate = res
})
},
getDetailInfo () {
const id = this.detail.info.ids || this.detail.info.id
zy.detail(this.detail.key, id).then(res => {
if (res) {
this.info = res
this.$set(this.info, 'rate', '')
this.m3u8List = res.m3u8List
this.getDoubanRate()
this.loading = false
}
})
}
},
created () {
this.getDetail()
this.getDetailInfo()
}
}
</script>
<style lang="scss">
.detail{
<style lang="scss" scoped>
.detail {
position: absolute;
left: 0;
left: 80px;
right: 20px;
bottom: 0;
width: 100%;
width: calc(100% - 100px);
height: calc(100% - 40px);
z-index: 999;
.detail-content{
z-index: 888;
.detail-content {
height: calc(100% - 10px);
padding: 0 60px;
position: relative;
.detail-header{
.detail-header {
width: 100%;
height: 40px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 -40px;
.detail-title{
justify-content: space-between;
.detail-title {
font-size: 16px;
}
.detail-close{
.detail-close {
cursor: pointer;
}
}
.detail-body{
height: calc(100% - 50px);
overflow-y: auto;
.info{
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: wrap;
width: 100%;
padding: 10px;
border: 1px solid;
border-radius: 2px;
margin-bottom: 10px;
.vodImg{
width: 200px;
img{
width: 100%;
height: auto;
}
}
.vodAd{
display: none;
}
.vodInfo{
flex: 1;
margin-left: 20px;
overflow: hidden;
.vodh{
margin-bottom: 6px;
h2{
display: inline-block;
margin: 0;
}
span{
font-size: 12px;
margin-left: 10px;
}
label{
font-size: 20px;
font-weight: bold;
margin-left: 20px;
}
}
.cont, .tags{
display: none;
}
ul{
padding: 0;
margin: 0;
}
a{
display: none;
pointer-events: none;
}
li{
list-style: none;
font-size: 14px;
line-height: 18px;
height: 18px;
overflow: hidden;
span{
word-wrap: nowrap;
}
}
}
.whitetitle{
}
.detail-body {
height: calc(100% - 50px);
overflow-y: auto;
.info {
width: 100%;
padding: 10px;
display: flex;
flex-wrap: wrap;
align-items: flex-start;
justify-content: flex-start;
border: 1px solid;
border-radius: 2px;
margin-bottom: 10px;
height: auto;
.info-left {
width: 200px;
height: 100%;
img {
width: 100%;
font-size: 22px;
height: auto;
}
}
.info-right {
flex: 1;
margin-left: 20px;
.name {
font-size: 20px;
margin-bottom: 10px;
font-weight: bold;
margin: 4px 0;
}
.people{
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: wrap;
.left{
width: 200px;
img{
width: 100%;
height: auto;
}
}
.right{
flex: 1;
margin-left: 20px;
overflow: hidden;
p{
font-size: 14px;
}
a{
pointer-events: none;
text-decoration: none;
}
}
.director,
.actor,
.type,
.area,
.lang,
.year,
.last,
.note {
font-size: 14px;
line-height: 26px;
}
}
.desc{
border: 1px solid;
padding: 10px;
width: 100%;
margin-bottom: 10px;
border-radius: 2px;
font-size: 14px;
line-height: 20px;
}
.m3u8_urls, .mp4_urls{
border: 1px solid;
padding: 10px;
width: 100%;
margin-bottom: 10px;
border-radius: 2px;
.title{
.rate {
font-size: 16px;
line-height: 26px;
font-weight: bolder;
}
.box{
width: 100%;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
span{
font-size: 12px;
border: 1px solid;
border-radius: 2px;
cursor: pointer;
margin: 6px 6px 0px 0px;
padding: 8px 22px;
}
&::after {
content: '';
flex: 1;
}
}
}
.mp4_urls{
margin-bottom: 10px;
}
}
.detail-mask{
position: absolute;
top: 50px;
left: 0;
.operate {
border: 1px solid;
padding: 10px;
width: 100%;
height: calc(100% - 50px);
display: flex;
justify-content: center;
align-items: center;
.loader {
font-size: 8px;
width: 1em;
height: 1em;
border-radius: 50%;
position: relative;
text-indent: -9999em;
animation: load4 1.3s infinite linear;
transform: translateZ(0);
margin-bottom: 10px;
border-radius: 2px;
span {
margin-right: 20px;
font-size: 14px;
cursor: pointer;
user-select: none;
}
@keyframes load4 {
0%,
100% {
box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
}
12.5% {
box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
}
25% {
box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
}
37.5% {
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
}
50% {
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
}
62.5% {
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
}
75% {
box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0;
}
87.5% {
box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
}
.desc {
border: 1px solid;
padding: 10px;
width: 100%;
margin-bottom: 10px;
border-radius: 2px;
font-size: 14px;
line-height: 20px;
}
.m3u8 {
border: 1px solid;
padding: 10px 0 10px 10px;
width: 100%;
margin-bottom: 10px;
border-radius: 2px;
.box {
width: 100%;
span {
display: inline-block;
font-size: 12px;
border: 1px solid;
border-radius: 2px;
cursor: pointer;
margin: 6px 10px 0px 0px;
padding: 8px 22px;
}
}
}
}
.detail-mask {
position: absolute;
top: 50px;
left: 0;
width: 100%;
height: calc(100% - 50px);
display: flex;
justify-content: center;
align-items: center;
.loader {
font-size: 8px;
width: 1em;
height: 1em;
border-radius: 50%;
position: relative;
text-indent: -9999em;
animation: load4 1.3s infinite linear;
transform: translateZ(0);
}
@keyframes load4 {
0%,
100% {
box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em,
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
}
12.5% {
box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em,
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
}
25% {
box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0,
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
}
37.5% {
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em,
0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
}
50% {
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em,
0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
}
62.5% {
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em,
0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
}
75% {
box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em,
2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em,
-2em -2em 0 0;
}
87.5% {
box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em,
0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
}
}
}
}
</style>

View File

@@ -0,0 +1,504 @@
<template>
<div class="listpage" id="sites">
<div class="listpage-header" v-show="!enableBatchEdit">
<el-switch v-model="enableBatchEdit" active-text="批处理分组">></el-switch>
<el-checkbox v-model="setting.excludeR18Films" @change="excludeR18FilmsChangeEvent">屏蔽福利片</el-checkbox>
<el-button @click="addSite" icon="el-icon-document-add">新增</el-button>
<el-button @click="exportSites" icon="el-icon-upload2" >导出</el-button>
<el-button @click="importSites" icon="el-icon-download">导入</el-button>
<el-button @click="checkAllSite" icon="el-icon-refresh" :loading="checkAllSitesLoading">检测{{ this.checkAllSitesLoading ? this.checkProgress + '/' + this.sites.length : '' }}</el-button>
<el-button @click="resetSitesEvent" icon="el-icon-refresh-left">重置</el-button>
</div>
<div class="listpage-header" v-show="enableBatchEdit">
<el-switch v-model="enableBatchEdit" active-text="批处理分组"></el-switch>
<el-input placeholder="新组名" v-model="batchGroupName"></el-input>
<el-switch v-model="batchIsActive" active-text="启用"></el-switch>
<el-button type="primary" icon="el-icon-edit" @click.stop="saveBatchEdit">保存</el-button>
<el-button @click="removeSelectedSites" icon="el-icon-delete-solid">删除</el-button>
</div>
<div class="listpage-body" id="sites-body">
<div class="show-table" id="sites-table">
<el-table size="mini" fit height="100%" row-key="id"
ref="editSitesTable"
:data="sites"
@select="selectionCellClick"
@selection-change="handleSelectionChange"
@sort-change="handleSortChange">
<el-table-column
type="selection"
v-if="enableBatchEdit">
</el-table-column>
<el-table-column
prop="name"
label="资源名">
</el-table-column>
<el-table-column
prop="isActive"
width="120"
:filters = "[{text:'启用', value: true}, {text:'停用', value: false}]"
:filter-method="(value, row) => value === row.isActive"
label="启用">
<template slot-scope="scope">
<el-switch
v-model="scope.row.isActive"
@click.native.stop='isActiveChangeEvent(scope.row)'>
</el-switch>
</template>
</el-table-column>
<el-table-column
prop="group"
label="分组"
:filters="getFilters"
:filter-method="(value, row) => value === row.group"
filter-placement="bottom-end">
</el-table-column>
<el-table-column
label="状态"
sortable
:sort-by="['status']"
width="120">
<template slot-scope="scope">
<span v-if="scope.row.status === ' '">
<i class="el-icon-loading"></i>
检测中...
</span>
<span v-else>{{scope.row.status}}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
header-align="center"
align="right"
:width="sites.every(site => site.status) && !checkAllSitesLoading ? 200 : 150">
<template slot-scope="scope">
<el-button size="mini" @click.stop="moveToTopEvent(scope.row)" type="text">置顶</el-button>
<el-button size="mini" @click.stop="editSite(scope.row)" type="text">编辑</el-button>
<!-- 检测时先强制批量检测一遍,如果不强制直接单个检测时第一次不会显示“检测中” -->
<el-button size="mini" v-if="sites.every(site => site.status)" v-show="!checkAllSitesLoading" @click.stop="checkSingleSite(scope.row)" type="text">检测</el-button>
<el-button size="mini" @click.stop="removeEvent(scope.row)" type="text">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
<!-- 编辑页面 -->
<div>
<el-dialog :visible.sync="dialogVisible" v-if='dialogVisible' :title="dialogType==='edit'?'编辑源':'新增源'" :append-to-body="true" @close="closeDialog">
<el-form :model="siteInfo" ref='siteInfo' label-width="75px" label-position="left" :rules="rules">
<el-form-item label="源站名" prop='name'>
<el-input v-model="siteInfo.name" placeholder="请输入源站名" />
</el-form-item>
<el-form-item label="API接口" prop='api'>
<el-input v-model="siteInfo.api" :autosize="{ minRows: 2, maxRows: 4}" type="textarea" placeholder="请输入API接口地址"/>
</el-form-item>
<el-form-item label="下载接口" prop='download'>
<el-input v-model="siteInfo.download" :autosize="{ minRows: 2, maxRows: 4}" type="textarea" placeholder="请输入Download接口地址可以空着"/>
</el-form-item>
<el-form-item label="分组" prop='group'>
<el-select v-model="siteInfo.group" allow-create filterable default-first-option placeholder="请输入分组">
<el-option v-for="item in siteGroup" :key="item" :label="item" :value="item"></el-option>
</el-select>
</el-form-item>
<el-form-item label="源站标识" prop='key'>
<el-input v-model="siteInfo.key" placeholder="请输入源站标识如果为空系统则自动生成" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="addOrEditSite">保存</el-button>
</span>
</el-dialog>
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import { sites, setting } from '../lib/dexie'
import zy from '../lib/site/tools'
import { remote } from 'electron'
import { sites as defaultSites } from '../lib/dexie/initData'
import fs from 'fs'
import Sortable from 'sortablejs'
export default {
name: 'editSites',
data () {
return {
show: false,
sites: [],
dialogType: 'new',
dialogVisible: false,
siteInfo: {
key: '',
name: '',
api: '',
download: '',
group: '',
isActive: true
},
siteGroup: [],
rules: {
name: [
{ required: true, message: '源站名不能为空', trigger: 'blur' }
],
api: [
{ required: true, message: 'API地址不能为空', trigger: 'blur' }
]
},
enableBatchEdit: false,
batchGroupName: '',
batchIsActive: true,
shiftDown: false,
selectionBegin: '',
selectionEnd: '',
multipleSelection: [],
checkAllSitesLoading: false,
checkProgress: 0,
stopFlag: false,
editOldkey: ''
}
},
computed: {
setting: {
get () {
return this.$store.getters.getSetting
},
set (val) {
this.SET_SETTING(val)
}
},
getFilters () {
const groups = [...new Set(this.sites.map(site => site.group))]
var filters = []
groups.forEach(g => {
var doc = {
text: g,
value: g
}
filters.push(doc)
})
return filters
}
},
watch: {
enableBatchEdit () {
if (this.checkAllSitesLoading) {
this.$message.info('正在检测, 请勿操作.')
this.enableBatchEdit = false
}
}
},
methods: {
...mapMutations(['SET_SETTING']),
excludeR18FilmsChangeEvent () {
setting.find().then(res => {
res.excludeR18Films = this.setting.excludeR18Films
setting.update(res)
})
},
selectionCellClick (selection, row) {
if (this.shiftDown && this.selectionBegin !== '' && selection.includes(row)) {
this.selectionEnd = row.id
const start = Math.min(this.selectionBegin, this.selectionEnd) - 1
const end = Math.max(this.selectionBegin, this.selectionEnd)
const selections = this.sites.slice(start, end)
this.$nextTick(() => {
selections.forEach(e => this.$refs.editSitesTable.toggleRowSelection(e, true))
})
this.selectionBegin = this.selectionEnd = ''
return
}
if (selection.includes(row)) {
this.selectionBegin = row.id
} else {
this.selectionBegin = ''
}
},
handleSelectionChange (rows) {
this.multipleSelection = rows
},
handleSortChange (column, prop, order) {
if (this.checkAllSitesLoading) {
this.$message.info('正在检测, 请勿操作.')
return false
}
this.updateDatabase(this.sites)
},
saveBatchEdit () {
this.multipleSelection.forEach(ele => {
if (this.batchGroupName) {
ele.group = this.batchGroupName
}
ele.isActive = this.batchIsActive
})
this.updateDatabase()
},
getSites () {
sites.all().then(res => {
this.sites = res
})
},
getSitesGroup () {
const arr = []
for (const i of this.sites) {
if (arr.indexOf(i.group) < 0) {
arr.push(i.group)
}
}
this.siteGroup = arr
},
addSite () {
if (this.checkAllSitesLoading) {
this.$message.info('正在检测, 请勿操作.')
return false
}
this.getSitesGroup()
this.dialogType = 'new'
this.dialogVisible = true
this.siteInfo = {
key: '',
name: '',
api: '',
download: '',
group: '',
isActive: true
}
},
editSite (siteInfo) {
if (this.checkAllSitesLoading) {
this.$message.info('正在检测, 请勿操作.')
return false
}
this.getSitesGroup()
this.dialogType = 'edit'
this.dialogVisible = true
this.siteInfo = siteInfo
this.editOldkey = siteInfo.key
},
closeDialog () {
this.dialogVisible = false
this.getSites()
},
removeEvent (e) {
if (this.checkAllSitesLoading) {
this.$message.info('正在检测, 请勿操作.')
return false
}
sites.remove(e.id).then(res => {
this.getSites()
}).catch(err => {
this.$message.warning('删除源失败, 错误信息: ' + err)
})
},
checkSiteKey (e) {
if (this.dialogType === 'edit' && this.editOldkey === this.siteInfo.key) {
return true
} else {
for (const i of this.sites) {
if (i.key === this.siteInfo.key) {
this.$message.warning(`源站标识: ${i.key} 已存在, 请勿重复填写.`)
return false
}
}
return true
}
},
addOrEditSite () {
if (!this.siteInfo.name || !this.siteInfo.api) {
this.$message.error('名称和API接口不能为空。')
return false
}
if (!this.checkSiteKey()) {
return false
}
var randomstring = require('randomstring')
var doc = {
key: this.dialogType === 'edit' ? this.siteInfo.key : this.siteInfo.key ? this.siteInfo.key : randomstring.generate(6),
id: this.dialogType === 'edit' ? this.siteInfo.id : this.sites[this.sites.length - 1].id + 1,
name: this.siteInfo.name,
api: this.siteInfo.api,
download: this.siteInfo.download,
group: this.siteInfo.group,
isActive: this.siteInfo.isActive
}
if (this.dialogType === 'edit') sites.remove(this.siteInfo.id)
sites.add(doc).then(res => {
this.siteInfo = {
key: '',
name: '',
api: '',
download: '',
group: ''
}
this.dialogType === 'edit' ? this.$message.success('修改成功!') : this.$message.success('新增源成功!')
this.dialogVisible = false
this.getSites()
})
this.editOldkey = ''
},
exportSites () {
this.getSites()
const arr = [...this.sites]
const str = JSON.stringify(arr, null, 2)
const options = {
filters: [
{ name: 'JSON file', extensions: ['json'] },
{ name: 'Normal text file', extensions: ['txt'] },
{ name: 'All types', extensions: ['*'] }
]
}
remote.dialog.showSaveDialog(options).then(result => {
if (!result.canceled) {
fs.writeFileSync(result.filePath, str)
this.$message.success('已保存成功')
}
}).catch(err => {
this.$message.error(err)
})
},
importSites () {
if (this.checkAllSitesLoading) {
this.$message.info('正在检测, 请勿操作.')
return false
}
const options = {
filters: [
{ name: 'JSON file', extensions: ['json'] },
{ name: 'Normal text file', extensions: ['txt'] },
{ name: 'All types', extensions: ['*'] }
],
properties: ['openFile', 'multiSelections']
}
remote.dialog.showOpenDialog(options).then(result => {
if (!result.canceled) {
result.filePaths.forEach(file => {
var str = fs.readFileSync(file)
const json = JSON.parse(str)
json.forEach(ele => {
if (ele.api && this.sites.filter(x => x.key === ele.key).length === 0 && this.sites.filter(x => x.name === ele.name && x.api === ele.api).length === 0) {
// 不含该key 同时也不含名字和url一样的
if (ele.isActive === undefined) {
ele.isActive = true
}
if (ele.group === undefined) {
ele.group = '导入'
}
this.sites.push(ele)
}
})
this.resetId(this.sites)
sites.clear().then(sites.bulkAdd(this.sites))
this.$message.success('导入成功')
this.getSites()
})
}
})
},
resetSitesEvent () {
this.stopFlag = true
if (this.checkAllSitesLoading) {
this.$message.info('部分检测还未完全终止, 请稍等...')
return
}
sites.clear().then(sites.bulkAdd(defaultSites).then(this.getSites()))
this.$message.success('重置源成功')
},
moveToTopEvent (i) {
if (this.checkAllSitesLoading) {
this.$message.info('正在检测, 请勿操作.')
return false
}
this.sites.sort(function (x, y) { return x.key === i.key ? -1 : y.key === i.key ? 1 : 0 })
this.updateDatabase()
},
syncTableData () {
if (this.$refs.editSitesTable.tableData) {
this.sites = this.$refs.editSitesTable.tableData
}
},
isActiveChangeEvent (row) {
sites.remove(row.id)
sites.add(row)
},
resetId (inArray) {
var id = 1
inArray.forEach(ele => {
ele.id = id
id += 1
})
},
updateDatabase () {
// 因为el-table的数据是单向绑定,我们先同步el-table里的数据和其绑定的数据
this.syncTableData()
sites.clear().then(res => {
var id = 1
this.sites.forEach(ele => {
ele.id = id
id += 1
})
sites.bulkAdd(this.sites).then(this.getSites())
})
},
removeSelectedSites () {
this.multipleSelection.forEach(e => sites.remove(e.id))
this.$refs.editSitesTable.clearFilter()
this.getSites()
this.updateDatabase()
this.enableBatchEdit = false
},
rowDrop () {
if (this.checkAllSitesLoading) {
this.$message.info('正在检测, 请勿操作.')
return false
}
const tbody = document.getElementById('sites-table').querySelector('.el-table__body-wrapper tbody')
var _this = this
Sortable.create(tbody, {
onEnd ({ newIndex, oldIndex }) {
const currRow = _this.sites.splice(oldIndex, 1)[0]
_this.sites.splice(newIndex, 0, currRow)
_this.updateDatabase()
}
})
},
async checkAllSite () {
this.checkAllSitesLoading = true
this.stopFlag = false
this.checkProgress = 0
const uncheckedList = this.sites.filter(e => e.status === undefined || e.status === ' ') // 未检测过的优先
const other = this.sites.filter(e => !uncheckedList.includes(e))
await Promise.all(uncheckedList.map(site => this.checkSingleSite(site)))
await Promise.all(other.map(site => this.checkSingleSite(site))).then(res => {
this.checkAllSitesLoading = false
this.getSites()
})
},
async checkSingleSite (row) {
row.status = ' '
if (this.stopFlag) {
this.checkProgress += 1
return row.status
}
const flag = await zy.check(row.key)
this.checkProgress += 1
if (flag) {
row.status = '可用'
} else {
row.status = '失效'
row.isActive = false
}
sites.remove(row.id)
sites.add(row)
return row.status
}
},
mounted () {
this.rowDrop()
addEventListener('keydown', code => { if (code.keyCode === 16) this.shiftDown = true })
addEventListener('keyup', code => { if (code.keyCode === 16) this.shiftDown = false })
},
created () {
this.getSites()
}
}
</script>

View File

@@ -1,117 +1,275 @@
<template>
<div class="film">
<div class="top" v-if="top">
<!-- site -->
<div class="zy-select" @mouseleave="show.site = false">
<div class="vs-placeholder" @click="show.site = true">{{site.name}}</div>
<div class="vs-options" v-show="show.site">
<ul>
<li :class="site === j ? 'active' : ''" v-for="(i, j) in sites" :key="j" @click="siteClick(i)">{{ i.name }}</li>
</ul>
</div>
</div>
<!-- tags -->
<div class="zy-select" @mouseleave="show.tags = false" v-if="site.tags.length > 0 && keywords.length <= 0">
<div class="vs-placeholder" @click="show.tags = true">{{site.tags[tag].title}}</div>
<div class="vs-options" v-show="show.tags">
<ul>
<li :class="tag === j ? 'active' : ''" v-for="(i, j) in site.tags" :key="j" @click="tagClick(i, j)">{{ i.title }}</li>
</ul>
</div>
</div>
<!-- type -->
<div class="zy-select" @mouseleave="show.type = false" v-if="site.tags[tag].children.length > 0 && keywords.length <= 0">
<div class="vs-placeholder" @click="show.type = true">{{typeName}}</div>
<div class="vs-options" v-show="show.type">
<ul>
<li :class="type === j ? 'active' : ''" v-for="(i, j) in site.tags[tag].children" :key="j" @click="typeClick(i, j)">{{ i.title }}</li>
</ul>
</div>
</div>
<div :class="[inputFocus ? 'active ': ''] + 'search'" @mouseover="inputFocus = true" @mouseleave="inputFocus = false">
<div class="search-icon">
<span class="zy-svg">
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="searchIconTitle">
<title id="searchIconTitle">Search</title>
<path d="M14.4121122,14.4121122 L20,20"></path>
<circle cx="10" cy="10" r="6"></circle>
</svg>
</span>
</div>
<input type="text" class="search-box" v-model="keywords" @keypress.enter="searchEvent">
</div>
<div class="listpage" id="film">
<div class="listpage-header" id="film-header">
<el-select v-model="selectedSiteName" size="small" placeholder="源站" :popper-append-to-body="false" popper-class="popper" @change="siteClick">
<el-option
v-for="item in sites"
:key="item.key"
:label="item.name"
:value="item.name">
</el-option>
</el-select>
<el-select v-model="selectedClassName" size="small" placeholder="类型" :popper-append-to-body="false" popper-class="popper" @change="classClick" v-show="show.class">
<el-option
v-for="item in classList"
:key="item.tid"
:label="item.name"
:value="item.name">
</el-option>
</el-select>
<el-autocomplete
clearable
size="small"
v-model.trim="searchTxt"
value-key="keywords"
:fetch-suggestions="querySearch"
:popper-append-to-body="false"
popper-class="popper"
placeholder="搜索"
@keyup.enter.native="searchAndRecord"
@select="searchEvent"
@change="searchChangeEvent">
<el-select v-model="searchGroup" size="small" slot="prepend"
:popper-append-to-body="false"
popper-class="popper"
default-first-option placeholder="请选择"
@change="searchEvent">
<el-option
v-for="item in searchGroups"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
<!--方便触屏-->
<el-button icon="el-icon-search" @click.stop="searchEvent" slot="append" />
</el-autocomplete>
</div>
<div class="middle">
<div class="zy-table">
<div class="tHead">
<span class="name">{{$t('videoName')}}</span>
<span class="type">{{$t('type')}}</span>
<span class="time">{{$t('time')}}</span>
<span class="operate">{{$t('operate')}}</span>
</div>
<div class="tBody zy-scroll">
<ul v-show="!tb.loading">
<li v-for="(i, j) in tb.list" :key="j" @click="detailEvent(i)">
<span class="name">{{i.name}}</span>
<span class="type">{{i.type}}</span>
<span class="time">{{i.time}}</span>
<span class="operate">
<span class="btn" @click.stop="playEvent(i)">{{$t('play')}}</span>
<span class="btn" @click.stop="starEvent(i)">{{$t('star')}}</span>
<span class="btn" @click.stop="shareEvent(i)">{{$t('share')}}</span>
<span class="btn" @click.stop="downloadEvent(i)">{{$t('download')}}</span>
</span>
</li>
</ul>
<div class="tBody-mask zy-loading" v-show="tb.loading">
<div class="loader"></div>
</div>
</div>
<div class="tFooter">
<span class="tFooter-span">今日更新: {{ tb.update }} </span>
<span class="tFooter-span btn" @click="goWebsite">加载不出来,点这里</span>
<el-pagination small :page-size="tb.size" :total="tb.total" :current-page="tb.page" @current-change="tbPageChange" layout="total, prev, pager, next, jumper"></el-pagination>
</div>
<div class="listpage-body" id="film-body" infinite-wrapper>
<div class="show-picture" v-if="setting.view === 'picture' && !show.find">
<Waterfall ref="filmWaterfall" :list="list" :gutter="20" :width="240"
:breakpoints="{
1200: { //当屏幕宽度小于等于1200
rowPerView: 4,
},
800: { //当屏幕宽度小于等于800
rowPerView: 3,
},
500: { //当屏幕宽度小于等于500
rowPerView: 2,
}
}"
animationEffect="fadeIn"
backgroundColor="rgba(0, 0, 0, 0)">
<template slot="item" slot-scope="props">
<div class="card" v-show="!setting.excludeR18Films || !containsR18Keywords(props.data.type)">
<div class="img">
<img style="width: 100%" :src="props.data.pic" alt="" @load="$refs.filmWaterfall.refresh()" @click="detailEvent(site, props.data)">
<div class="operate">
<div class="operate-wrap">
<span class="o-play" @click="playEvent(site, props.data)">播放</span>
<span class="o-star" @click="starEvent(site, props.data)">收藏</span>
<span class="o-share" @click="shareEvent(site, props.data)">分享</span>
</div>
</div>
</div>
<div class="name" @click="detailEvent(site, props.data)">{{props.data.name}}</div>
<div class="info">
<span>{{props.data.area}}</span>
<span>{{props.data.year}}</span>
<span>{{props.data.note}}</span>
<span>{{props.data.type}}</span>
</div>
</div>
</template>
</Waterfall>
<infinite-loading force-use-infinite-wrapper :identifier="infiniteId" @infinite="infiniteHandler"></infinite-loading>
</div>
<div class="show-table" v-if="setting.view === 'table' && !show.find">
<el-table
size="mini"
:data="list.filter(res => !setting.excludeR18Films || !containsR18Keywords(res.type))"
height="100%"
:empty-text="statusText"
@row-click="(row) => detailEvent(site, row)"
style="width: 100%">
<el-table-column
prop="name"
label="片名">
</el-table-column>
<el-table-column
prop="type"
label="类型"
width="100">
</el-table-column>
<el-table-column
prop="year"
label="上映"
align="center"
width="100">
</el-table-column>
<el-table-column
prop="area"
label="地区"
width="100">
</el-table-column>
<el-table-column
prop="lang"
label="语言"
width="100">
</el-table-column>
<el-table-column
prop="note"
label="备注"
width="120">
</el-table-column>
<el-table-column
prop="last"
label="最近更新"
:formatter="dateFormat"
align="left">
</el-table-column>
<el-table-column
label="操作"
header-align="center"
align="right"
width="200">
<template slot-scope="scope">
<el-button @click.stop="playEvent(site, scope.row)" type="text">播放</el-button>
<el-button @click.stop="starEvent(site, scope.row)" type="text">收藏</el-button>
<el-button @click.stop="shareEvent(site, scope.row)" type="text">分享</el-button>
<el-button @click.stop="downloadEvent(site, scope.row)" type="text">下载</el-button>
</template>
</el-table-column>
<infinite-loading
slot="append"
:identifier="infiniteId"
@infinite="infiniteHandler"
force-use-infinite-wrapper=".el-table__body-wrapper">
<div slot="no-more">数据量过少时请重复操作一次,以防网站抽风</div>
</infinite-loading>
</el-table>
</div>
<div class="show-table" v-show="show.find">
<el-table size="mini"
ref="searchResultTable"
:data="searchContents.filter(res => !setting.excludeR18Films || (res.type !== undefined && !containsR18Keywords(res.type)))"
height="100%"
:empty-text="statusText"
@filter-change="filterChange"
@row-click="(row) => detailEvent(row.site, row)"
style="width: 100%">
<el-table-column
sortable
:sort-method="(a , b) => sortByLocaleCompare(a.name, b.name)"
prop="name"
label="片名">
</el-table-column>
<el-table-column v-if="searchGroup !== '站内'"
sortable
:sort-method="(a , b) => sortByLocaleCompare(a.site.name, b.site.name)"
:filters="getFilters('siteName')"
:filter-method="(value, row, column) => { this.currentColumn = column; return value === row.site.name }"
prop="site"
label="源站"
width="120">
<template slot-scope="scope">
<span>{{ scope.row.site.name }}</span>
</template>
</el-table-column>
<el-table-column
prop="type"
:filters="getFilters('type')"
:filter-method="(value, row, column) => { this.currentColumn = column; return value === row.type }"
label="类型"
width="90">
</el-table-column>
<el-table-column
sortable
prop="year"
label="上映"
width="90">
</el-table-column>
<el-table-column
prop="area"
:filters="getFilters('area')"
:filter-method="(value, row, column) => { this.currentColumn = column; return value === row.area }"
label="地区"
width="90">
</el-table-column>
<el-table-column
:filters="getFilters('lang')"
:filter-method="(value, row, column) => { this.currentColumn = column; return value === row.lang }"
prop="lang"
label="语言"
width="70">
</el-table-column>
<el-table-column
sortable
prop="note"
label="备注"
width="120">
</el-table-column>
<el-table-column
label="操作"
header-align="center"
align="right"
width="200">
<template slot-scope="scope">
<el-button @click.stop="playEvent(scope.row.site, scope.row)" type="text">播放</el-button>
<el-button @click.stop="starEvent(scope.row.site, scope.row)" type="text">收藏</el-button>
<el-button @click.stop="shareEvent(scope.row.site, scope.row)" type="text">分享</el-button>
<el-button @click.stop="downloadEvent(scope.row.site, scope.row)" type="text">下载</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import { sites, getSite } from '../lib/site/sites'
import tools from '../lib/site/tools'
import video from '../lib/dexie/video'
import setting from '../lib/dexie/setting'
import { shell } from 'electron'
import { star, history, search, sites, setting } from '../lib/dexie'
import zy from '../lib/site/tools'
import Waterfall from 'vue-waterfall-plugin'
import InfiniteLoading from 'vue-infinite-loading'
const { clipboard } = require('electron')
export default {
name: 'film',
data () {
return {
sites: sites,
site: {},
top: false,
tag: 0,
type: 0,
typeName: '',
keywords: '',
id: '',
show: {
body: false,
site: false,
tags: false,
type: false
class: false,
classList: false,
find: false
},
inputFocus: false,
tb: {
list: [],
page: 1,
size: 50,
total: 0,
update: 0,
loading: true
}
sites: [],
site: {},
classList: [],
type: {},
selectedClassName: '最新',
selectedSiteName: '',
pagecount: 0,
list: [],
statusText: ' ',
infiniteId: +new Date(),
searchID: 0,
searchList: [],
searchTxt: '',
searchContents: [],
currentColumn: '',
searchGroup: '',
searchGroups: [],
// 福利片关键词
r18KeyWords: ['伦理', '论理', '倫理', '福利', '激情', '理论', '写真', '情色', '美女', '街拍', '赤足', '性感', '里番']
}
},
components: {
Waterfall,
InfiniteLoading
},
computed: {
view: {
get () {
@@ -121,12 +279,12 @@ export default {
this.SET_VIEW(val)
}
},
gSite: {
video: {
get () {
return this.$store.getters.getSite
return this.$store.getters.getVideo
},
set (val) {
this.SET_SITE(val)
this.SET_VIDEO(val)
}
},
detail: {
@@ -137,14 +295,6 @@ export default {
this.SET_DETAIL(val)
}
},
video: {
get () {
return this.$store.getters.getVideo
},
set (val) {
this.SET_VIDEO(val)
}
},
share: {
get () {
return this.$store.getters.getShare
@@ -152,216 +302,417 @@ export default {
set (val) {
this.SET_SHARE(val)
}
},
setting: {
get () {
return this.$store.getters.getSetting
},
set (val) {
this.SET_SETTING(val)
}
},
filterSettings () {
return this.$store.getters.getSetting.excludeR18Films // 需要监听的数据
}
},
filters: {
classNameFilter: (name) => {
const clsName = name.toString()
return clsName.replace(/[^\u4e00-\u9fa5]/gi, '')
}
},
watch: {
gSite (n, o) {
const s = getSite(n)
this.siteClick(s)
view () {
this.changeView()
},
searchTxt () {
if (this.searchTxt === '清除历史记录...') {
this.clearSearchHistory()
this.searchTxt = ''
this.searchChangeEvent()
}
},
filterSettings () {
this.siteClick(this.site.name)
}
},
methods: {
...mapMutations(['SET_VIEW', 'SET_SITE', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
init () {
setting.find().then(res => {
this.site = getSite(res.site)
this.top = true
tools.film_get(res.site).then(tRes => {
this.tb.list = tRes.list
this.tb.total = tRes.total
this.tb.update = tRes.update
this.tb.loading = false
})
})
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE', 'SET_SETTING']),
sortByLocaleCompare (a, b) {
return a.localeCompare(b, 'zh')
},
siteClick (e) {
this.site = e
this.tag = 0
this.id = e.tags[0].id
this.show.site = false
if (this.keywords.length > 0) {
dateFormat (row, column) {
var date = row[column.property]
if (date === undefined) {
return ''
}
return date.split(/\s/)[0]
},
getFilters (column) {
const searchContents = this.searchContents.filter(res => !this.setting.excludeR18Films || (res.type !== undefined && !this.containsR18Keywords(res.type)))
if (column === 'siteName') return [...new Set(searchContents.map(row => row.site.name))].map(e => { return { text: e, value: e } }) // 有方法合并这两行吗?
return [...new Set(searchContents.map(row => row[column]))].map(e => { return { text: e, value: e } })
},
filterChange (filters) {
// 一次只能一列
if (Object.values(filters)[0].length) {
const otherColumns = this.$refs.searchResultTable.columns.filter(col => col.id !== this.currentColumn.id)
otherColumns.forEach(col => { col.filterable = false })
} else {
const filterLabels = ['源站', '类型', '地区', '语言']
const columns = this.$refs.searchResultTable.columns.filter(col => filterLabels.includes(col.label))
columns.forEach(col => { col.filterable = true })
}
},
siteClick (siteName) {
this.list = []
this.site = this.sites.find(x => x.name === siteName)
if (this.searchTxt.length > 0 && this.searchGroup === '站内') {
this.searchEvent()
} else {
this.tb.update = 0
this.tb.total = 0
this.tb.loading = true
tools.film_get(e.key, this.id).then(res => {
this.tb.list = res.list
this.tb.total = res.total
this.tb.update = res.update
this.tb.loading = false
this.searchTxt = ''
this.show.find = false
this.classList = []
this.type = {}
this.getClass().then(res => {
this.infiniteId += 1
this.classClick(this.classList[0].name)
})
}
},
tagClick (e, n) {
this.tb.update = 0
this.tb.total = 0
this.tag = n
this.id = e.id
this.typeName = 'All'
this.tb.loading = true
this.show.tags = false
tools.film_get(this.site.key, this.id).then(res => {
this.tb.list = res.list
this.tb.total = res.total
this.tb.update = res.update
this.tb.loading = false
classClick (className) {
this.show.classList = false
this.list = []
this.type = this.classList.find(x => x.name === className)
this.getPage().then(res => {
if (res) {
this.infiniteId += 1
}
})
},
typeClick (e, n) {
this.tb.update = 0
this.tb.total = 0
this.type = n
this.typeName = e.title
this.id = e.id
this.tb.loading = true
this.show.type = false
tools.film_get(this.site.key, this.id).then(res => {
this.tb.list = res.list
this.tb.total = res.total
this.tb.update = res.update
this.tb.loading = false
getClass () {
return new Promise((resolve, reject) => {
const key = this.site.key
// 屏蔽主分类
const classToHide = ['电影', '电影片', '电视剧', '连续剧', '综艺', '动漫']
zy.class(key).then(res => {
var allClass = [{ name: '最新', tid: 0 }]
res.class.forEach(element => {
if (!this.setting.excludeRootClasses || !classToHide.includes(element.name)) {
if (this.setting.excludeR18Films) {
const containKeyWord = this.containsR18Keywords(element.name)
if (!containKeyWord) {
allClass.push(element)
}
} else {
allClass.push(element)
}
}
})
this.classList = allClass
this.show.class = true
this.pagecount = res.pagecount
this.type = this.classList[0]
resolve(true)
}).catch(err => {
reject(err)
})
})
},
containsR18Keywords (name) {
var containKeyWord = false
if (!name) {
return containKeyWord
}
return this.r18KeyWords.some(v => name.includes(v))
},
getPage () {
return new Promise((resolve, reject) => {
const key = this.site.key
const type = this.type.tid
zy.page(key, type).then(res => {
this.pagecount = res.pagecount
this.show.body = true
resolve(true)
}).catch(err => {
reject(err)
})
})
},
infiniteHandler ($state) {
const key = this.site.key
const type = this.type.tid
const page = this.pagecount
this.statusText = ' '
if (key && page < 1) { // OK资源前几类硬是去不掉
$state.complete()
this.statusText = '暂无数据'
return false
}
zy.list(key, page, type).then(res => {
if (res) {
this.pagecount -= 1
const type = Object.prototype.toString.call(res)
if (type === '[object Undefined]') {
$state.complete()
}
if (type === '[object Array]') {
// zy.list 返回的是按时间从旧到新排列, 我门需要翻转为从新到旧
this.list.push(...res.reverse())
}
if (type === '[object Object]') {
this.list.push(res)
}
$state.loaded()
} else {
$state.complete()
this.statusText = '暂无数据'
}
})
},
detailEvent (site, e) {
this.detail = {
show: true,
key: site.key,
site: site,
info: e
}
},
async playEvent (site, e) {
const db = await history.find({ site: site.key, ids: e.id })
if (db) {
this.video = { key: db.site, info: { id: db.ids, name: db.name, index: db.index, site: site } }
} else {
this.video = { key: site.key, info: { id: e.id, name: e.name, index: 0, site: site } }
}
zy.detail(site.key, e.id).then(detailRes => {
this.video.detail = detailRes
})
this.view = 'Play'
},
async starEvent (site, e) {
const db = await star.find({ key: site.key, ids: e.id })
if (db) {
this.$message.info('已存在')
} else {
zy.detail(site.key, e.id).then(detailRes => {
const docs = {
key: site.key,
ids: e.id,
site: site,
name: e.name,
detail: detailRes
}
star.add(docs).then(res => {
this.$message.success('收藏成功')
})
})
}
},
shareEvent (site, e) {
this.share = {
show: true,
key: site.key,
info: e
}
},
downloadEvent (site, row) {
zy.download(site.key, row.id).then(res => {
if (res && res.length > 0) {
const text = res.dl.dd._t
if (text) {
const list = text.split('#')
let downloadUrl = res.name + '\n'
for (const i of list) {
const url = encodeURI(i.split('$')[1])
downloadUrl += (url + '\n')
}
clipboard.writeText(downloadUrl)
this.$message.success('『MP4』格式的链接已复制, 快去下载吧!')
} else {
this.$message.warning('没有查询到下载链接.')
}
} else {
let m3u8List = []
const dd = row.dl.dd
const type = Object.prototype.toString.call(dd)
if (type === '[object Array]') {
for (const i of dd) {
if (i._flag.indexOf('m3u8') >= 0) {
m3u8List = i._t.split('#')
}
}
} else {
m3u8List = dd._t.split('#')
}
let downloadUrl = row.name + '\n'
for (const i of m3u8List) {
const url = encodeURI(i.split('$')[1])
downloadUrl += (url + '\n')
}
clipboard.writeText(downloadUrl)
this.$message.success('『M3U8』格式的链接已复制, 快去下载吧!')
}
})
},
changeView () {
if (this.view === 'Film') {
this.getAllSites()
if (this.setting.view === 'picture') {
if (this.$refs.filmWaterfall) {
this.$refs.filmWaterfall.refresh()
}
this.getPage().then(() => {
this.infiniteId += 1
})
}
}
},
querySearch (queryString, cb) {
if (this.searchList.length === 0) return
var searchList = this.searchList.slice(0, -1)
var results = queryString ? searchList.filter(this.createFilter(queryString)) : this.searchList
// 调用 callback 返回建议列表的数据
cb(results)
},
createFilter (queryString) {
return (item) => {
return (item.keywords.toLowerCase().indexOf(queryString.toLowerCase()) === 0)
}
},
addSearchRecord () {
const wd = this.searchTxt
if (wd) {
search.find({ keywords: wd }).then(res => {
if (!res) {
search.add({ keywords: wd })
}
this.getSearchHistory()
})
}
},
clearSearchHistory () {
search.clear().then(res => {
this.getSearchHistory()
})
},
getSearchHistory () {
search.all().then(res => {
this.searchList = res.reverse()
this.searchList.push({ id: this.searchList.length + 1, keywords: '清除历史记录...' })
})
},
searchEvent () {
const flag = this.site.search
if (flag === '') {
this.$m.warning(this.$t('not_support_search'))
return false
const wd = this.searchTxt
if (this.setting.searchGroup !== this.searchGroup) {
this.setting.searchGroup = this.searchGroup
setting.update(this.setting)
}
this.tb.loading = true
this.tb.update = 0
this.tb.total = 0
tools.search_get(this.site.key, this.keywords).then(res => {
this.tb.list = res.list
this.tb.total = res.total
this.tb.loading = false
})
},
detailEvent (e) {
this.detail = {
show: true,
v: e
if (!wd) return
this.searchID += 1
var searchSites = []
if (this.searchGroup === '站内') searchSites.push(this.site)
if (this.searchGroup === '全站') searchSites = this.sites
if (!searchSites.length) {
searchSites = this.sites.filter(site => site.group === this.searchGroup)
}
this.searchContents = []
this.pagecount = 0
this.show.find = true
this.show.class = false
this.statusText = ' '
if (wd) {
searchSites.forEach(site => {
const id = this.searchID
zy.search(site.key, wd).then(res => {
if (id !== this.searchID) return
const type = Object.prototype.toString.call(res)
if (type === '[object Array]') {
res.forEach(element => {
zy.detail(site.key, element.id).then(detailRes => {
detailRes.site = site
if (id !== this.searchID) return
this.searchContents.push(detailRes)
this.searchContents.sort(function (a, b) {
return a.site.id - b.site.id
})
this.statusText = '暂无数据'
})
})
}
if (type === '[object Object]') {
zy.detail(site.key, res.id).then(detailRes => {
detailRes.site = site
if (id !== this.searchID) return
this.searchContents.push(detailRes)
this.searchContents.sort(function (a, b) {
return a.site.id - b.site.id
})
this.statusText = '暂无数据'
})
}
})
})
}
},
playEvent (e) {
this.video = e
this.view = 'Play'
searchAndRecord () {
this.addSearchRecord()
this.searchEvent()
},
starEvent (e) {
video.find({ detail: e.detail }).then(res => {
if (res) {
this.$m.warning(this.$t('exists'))
searchChangeEvent () {
if (this.searchTxt.length >= 1) {
this.show.class = false
} else {
this.show.class = true
this.searchContents = []
this.show.find = false
if (this.setting.view === 'picture' && this.$refs.filmWaterfall) {
this.$refs.filmWaterfall.refresh()
} else {
video.add(e).then(res => {
this.$m.success(this.$t('star_success'))
this.getClass().then(res => {
if (res) {
this.infiniteId += 1
}
})
}
})
},
shareEvent (e) {
this.share = {
show: true,
v: e
}
},
downloadEvent (e) {
tools.detail_get(e.site, e.detail).then(res => {
if (res.mp4_urls.length > 0) {
const urls = [...res.mp4_urls]
let txt = `${e.name}\n`
for (const i of urls) {
const name = i.split('$')[0]
const url = encodeURI(i.split('$')[1])
txt += (name + ': ' + url + '\n')
getAllSites () {
sites.all().then(res => {
if (res.length <= 0) {
this.site = {}
this.type = {}
this.list = []
} else {
this.sites = res.filter(item => item.isActive)
if (this.site === undefined || !this.sites.some(x => x.key === this.site.key)) {
this.site = this.sites[0]
this.selectedSiteName = this.sites[0].name
}
clipboard.writeText(txt)
this.$m.success('〖MP4〗: ' + this.$t('copy_success'))
return false
}
if (res.m3u8_urls.length > 0) {
const urls = [...res.m3u8_urls]
let txt = `${e.name}\n`
for (const i of urls) {
const name = i.split('$')[0]
const url = encodeURI(i.split('$')[1])
txt += (name + ': ' + url + '\n')
}
clipboard.writeText(txt)
this.$m.success('〖M3U8〗: ' + this.$t('copy_success'))
}
this.searchGroups = [...new Set(this.sites.map(site => site.group))]
if (this.searchGroups.length === 1) this.searchGroups = []
this.searchGroups.unshift('站内')
this.searchGroups.push('全站')
this.searchGroup = this.setting.searchGroup
if (this.searchGroup === undefined) setting.find().then(res => { this.searchGroup = res.searchGroup })
})
},
tbPageChange (e) {
this.tb.loading = true
this.tb.page = e
tools.film_get(this.site.key, this.id, this.tb.page).then(res => {
this.tb.list = res.list
this.tb.loading = false
})
},
goWebsite () {
shell.openExternal(this.site.url)
}
},
created () {
this.init()
this.getAllSites()
this.getSearchHistory()
},
mounted () {
window.addEventListener('resize', () => {
if (this.$refs.filmWaterfall && this.view === 'Film') {
this.$refs.filmWaterfall.resize()
this.$refs.filmWaterfall.refresh()
setTimeout(() => {
this.$refs.filmWaterfall.refresh()
}, 500)
}
}, false)
}
}
</script>
<style lang="scss" scoped>
.film{
height: calc(100% - 40px);
width: 100%;
display: flex;
flex-direction: column;
animation: viewFadeIn 1s ease-in both;
.top{
width: 100%;
height: 30px;
display: flex;
justify-content: space-between;
align-items: center;
.search{
width: 200px;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 15px;
svg{
width: 20px;
height: 20px;
stroke-linecap: round;
stroke-linejoin: round;
}
.search-icon{
width: 40px;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
}
.search-box{
width: 160px;
height: 30px;
border-radius: 20px;
border: none;
text-indent: 2px;
font-size: 14px;
&:focus{
outline: none;
border: none;
}
}
}
}
.middle{
height: calc(100% - 40px);
width: 100%;
margin-top: 10px;
padding-bottom: 0px;
border-radius: 5px;
}
}
</style>

View File

@@ -1,16 +1,45 @@
<template>
<div class="frame">
<span class="min" @click="frameClickEvent('min')"></span>
<span class="close" @click="frameClickEvent('close')"></span>
<span class="top" @click="frameClickEvent('top')" title="置顶">
<svg t="1595919317571" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1188" style="width:10px;height:14px"><path d="M43.072 974.72l380.864-301.952 151.936 161.6c0 0 63.424 17.28 67.328-30.72l-3.904-163.584 225.088-259.648 98.048-5.696c0 0 76.928-15.488 21.184-82.752l-275.072-276.928c0 0-74.944-9.6-69.248 59.584l0 75.008L383.552 367.104 225.856 376.64c0 0-57.728 19.2-36.608 69.248l148.16 146.176L43.072 974.72 43.072 974.72z" p-id="1189" :fill="isAlwaysOnTop ? '#555555' : '#ffffff'"></path></svg>
</span>
<span class="min" @click="frameClickEvent('min')" title="最小化">
<svg t="1595917239849" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1155" style="width:8px;height:14px"><path d="M0 479.936C0 444.64 28.448 416 64.064 416L959.936 416C995.328 416 1024 444.736 1024 479.936L1024 544.064C1024 579.392 995.552 608 959.936 608L64.064 608C28.672 608 0 579.264 0 544.064L0 479.936Z" p-id="1156" fill="#ffffff"></path></svg>
</span>
<span class="max" @click="frameClickEvent('max')" title="最大化">
<svg t="1595917343956" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1540" style="width:8px;height:14px"><path d="M416 416 64.064 416C28.448 416 0 444.64 0 479.936L0 544.064C0 579.264 28.672 608 64.064 608L416 608 416 959.936C416 995.552 444.64 1024 479.936 1024L544.064 1024C579.264 1024 608 995.328 608 959.936L608 608 959.936 608C995.552 608 1024 579.36 1024 544.064L1024 479.936C1024 444.736 995.328 416 959.936 416L608 416 608 64.064C608 28.448 579.36 0 544.064 0L479.936 0C444.736 0 416 28.672 416 64.064L416 416Z" p-id="1541" fill="#ffffff"></path></svg>
</span>
<span class="close" @click="frameClickEvent('close')" title="关闭">
<svg t="1595917372551" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1685" style="width:8px;height:14px"><path d="M511.968 376.224 796.096 92.096C833.536 54.624 894.4 54.624 931.84 92.096 969.312 129.568 969.312 190.4 931.84 227.872L647.744 512 931.84 796.096C969.312 833.568 969.312 894.4 931.84 931.872 894.4 969.344 833.536 969.344 796.096 931.872L511.968 647.744 227.84 931.872C190.4 969.344 129.536 969.344 92.096 931.872 54.624 894.4 54.624 833.568 92.096 796.096L376.224 512 92.096 227.872C54.624 190.4 54.624 129.568 92.096 92.096 129.536 54.624 190.4 54.624 227.84 92.096L511.968 376.224Z" p-id="1686" fill="#ffffff"></path></svg>
</span>
</div>
</template>
<script>
const ipc = require('electron').ipcRenderer
const { remote } = require('electron')
export default {
name: 'frame',
data () {
const win = remote.getCurrentWindow()
return {
isAlwaysOnTop: win.isAlwaysOnTop()
}
},
methods: {
frameClickEvent (e) {
ipc.send(e)
const win = remote.getCurrentWindow()
if (e === 'min') {
win.minimize()
}
if (e === 'max') {
win.isMaximized() ? win.unmaximize() : win.maximize()
}
if (e === 'close') {
win.destroy()
}
if (e === 'top') {
this.isAlwaysOnTop = !this.isAlwaysOnTop
win.setAlwaysOnTop(this.isAlwaysOnTop)
}
}
}
}
@@ -20,46 +49,20 @@ export default {
width: 100%;
height: 40px;
display: flex;
justify-content: flex-end;
align-items: center;
user-select: none;
align-items: center;
justify-content: flex-end;
-webkit-app-region: drag;
span{
-webkit-app-region: no-drag;
display: inline-block;
width: 16px;
height: 16px;
border-radius: 50%;
margin-left: 10px;
width: 14px;
height: 14px;
cursor: pointer;
opacity: 0.5;
&:hover{
animation: heartbeat 3s ease-in-out infinite both;
}
@keyframes heartbeat {
from {
transform: scale(1);
transform-origin: center center;
animation-timing-function: ease-out;
}
10% {
opacity: 1;
transform: scale(0.91);
animation-timing-function: ease-in;
}
17% {
transform: scale(0.98);
animation-timing-function: ease-out;
}
33% {
transform: scale(0.87);
animation-timing-function: ease-in;
}
45% {
transform: scale(1);
animation-timing-function: ease-out;
}
}
margin-left: 10px;
border-radius: 50%;
text-align: center;
line-height: 14px;
display: inline-block;
-webkit-app-region: no-drag;
}
}
</style>

356
src/components/History.vue Normal file
View File

@@ -0,0 +1,356 @@
<template>
<div class="listpage" id="history">
<div class="listpage-header" id="history-header">
<el-switch v-model="viewMode" active-text="海报" active-value="picture" inactive-text="列表" inactive-value="list" @change="updateViewMode"></el-switch>
<el-button @click.stop="exportHistory" icon="el-icon-upload2">导出</el-button>
<el-button @click.stop="importHistory" icon="el-icon-download">导入</el-button>
<el-button @click.stop="clearAllHistory" icon="el-icon-delete-solid">清空</el-button>
</div>
<div class="listpage-body" id="history-body">
<div class="show-table" id="history-table" v-show="viewMode === 'list'">
<el-table size="mini" fit height="100%" :data="history" row-key="id" @row-click="detailEvent">
<el-table-column
prop="name"
label="片名">
</el-table-column>
<el-table-column
prop="site"
width="120"
label="片源">
<template slot-scope="scope">
<span>{{ getSiteName(scope.row.site) }}</span>
</template>
</el-table-column>
<el-table-column
prop="index"
width="180"
label="观看至">
<template slot-scope="scope">
<span v-if="scope.row.detail && scope.row.detail.m3u8List && scope.row.detail.m3u8List.length > 1">
{{ scope.row.index + 1 }}({{scope.row.detail.m3u8List.length}})
</span>
</template>
</el-table-column>
<el-table-column v-if="history.some(e => e.time)"
width="150"
label="时间进度">
<template slot-scope="scope">
<span v-if="scope.row.time && scope.row.duration">{{fmtMSS(scope.row.time.toFixed(0))}}/{{fmtMSS(scope.row.duration.toFixed(0))}}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
width="200"
header-align="center"
align="right">
<template slot-scope="scope">
<el-button @click.stop="playEvent(scope.row)" type="text">播放</el-button>
<el-button @click.stop="shareEvent(scope.row)" type="text">分享</el-button>
<el-button @click.stop="downloadEvent(scope.row)" type="text">下载</el-button>
<el-button @click.stop="deleteEvent(scope.row)" type="text">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="show-picture" id="star-picture" v-show="viewMode === 'picture'">
<Waterfall ref="historyWaterfall" :list="history" :gutter="20" :width="240"
:breakpoints="{
1200: { //当屏幕宽度小于等于1200
rowPerView: 4,
},
800: { //当屏幕宽度小于等于800
rowPerView: 3,
},
500: { //当屏幕宽度小于等于500
rowPerView: 2,
}
}"
animationDuration="0.5s"
backgroundColor="rgba(0, 0, 0, 0)">
<template slot="item" slot-scope="props">
<div class="card">
<div class="img">
<img v-if="props.data.detail && props.data.detail.pic" style="width: 100%" :src="props.data.detail.pic" alt="" @load="$refs.historyWaterfall.refresh()" @click="detailEvent(props.data)">
<div class="operate">
<div class="operate-wrap">
<span class="o-play" @click="playEvent(props.data)">播放</span>
<span class="o-share" @click="shareEvent(props.data)">分享</span>
<span class="o-star" @click="downloadEvent(props.data)">下载</span>
<span class="o-star" @click="deleteEvent(props.data)">删除</span>
</div>
</div>
</div>
<div class="name" @click="detailEvent(props.data)">{{props.data.name}}</div>
<div class="info">
<span v-if="props.data.time && props.data.duration">
{{fmtMSS(props.data.time.toFixed(0))}}/{{fmtMSS(props.data.duration.toFixed(0))}}
</span>
<span v-if="props.data.detail && props.data.detail.m3u8List !== undefined && props.data.detail.m3u8List.length > 1">
{{ props.data.index + 1 }}({{props.data.detail.m3u8List.length}})
</span>
</div>
</div>
</template>
</Waterfall>
</div>
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import { history, sites, setting } from '../lib/dexie'
import zy from '../lib/site/tools'
import Sortable from 'sortablejs'
import { remote } from 'electron'
import fs from 'fs'
import Waterfall from 'vue-waterfall-plugin'
const { clipboard } = require('electron')
export default {
name: 'history',
data () {
return {
history: [],
sites: [],
viewMode: setting.historyViewMode
}
},
components: {
Waterfall
},
computed: {
view: {
get () {
return this.$store.getters.getView
},
set (val) {
this.SET_VIEW(val)
}
},
video: {
get () {
return this.$store.getters.getVideo
},
set (val) {
this.SET_VIDEO(val)
}
},
detail: {
get () {
return this.$store.getters.getDetail
},
set (val) {
this.SET_DETAIL(val)
}
},
share: {
get () {
return this.$store.getters.getShare
},
set (val) {
this.SET_SHARE(val)
}
}
},
watch: {
view () {
this.getAllhistory()
this.getAllsites()
if (this.$refs.historyWaterfall) {
this.$refs.historyWaterfall.refresh()
}
}
},
methods: {
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
fmtMSS (s) {
return (s - (s %= 60)) / 60 + (s > 9 ? ':' : ':0') + s
},
detailEvent (e) {
this.detail = {
show: true,
key: e.site,
info: {
id: e.ids,
name: e.name
}
}
},
async playEvent (e) {
const db = await history.find({ site: e.site, ids: e.ids })
if (db) {
this.video = { key: db.site, info: { id: db.ids, name: db.name, index: db.index } }
} else {
this.video = { key: e.site, info: { id: e.ids, name: e.name, index: 0 } }
}
zy.detail(e.site, e.ids).then(detailRes => {
this.video.detail = detailRes
})
this.view = 'Play'
},
shareEvent (e) {
this.share = {
show: true,
key: e.site,
info: e
}
},
downloadEvent (e) {
zy.download(e.site, e.ids).then(res => {
if (res && res.dl && res.dl.dd) {
const text = res.dl.dd._t
if (text) {
const list = text.split('#')
let downloadUrl = ''
for (const i of list) {
const url = encodeURI(i.split('$')[1])
downloadUrl += (url + '\n')
}
clipboard.writeText(downloadUrl)
this.$message.success('『MP4』格式的链接已复制, 快去下载吧!')
} else {
this.$message.warning('没有查询到下载链接.')
}
} else {
var m3u8List = {}
zy.detail(e.site, e.ids).then(res => {
const dd = res.dl.dd
const type = Object.prototype.toString.call(dd)
if (type === '[object Array]') {
for (const i of dd) {
if (i._flag.indexOf('m3u8') >= 0) {
m3u8List = i._t.split('#')
}
}
} else {
m3u8List = dd._t.split('#')
}
const list = [...m3u8List]
let downloadUrl = ''
for (const i of list) {
const url = encodeURI(i.split('$')[1])
downloadUrl += (url + '\n')
}
clipboard.writeText(downloadUrl)
this.$message.success('『M3U8』格式的链接已复制, 快去下载吧!')
})
}
})
},
exportHistory () {
this.getAllhistory()
const arr = [...this.history]
const str = JSON.stringify(arr, null, 2)
const options = {
filters: [
{ name: 'JSON file', extensions: ['json'] }
]
}
remote.dialog.showSaveDialog(options).then(result => {
if (!result.canceled) {
fs.writeFileSync(result.filePath, str)
this.$message.success('已保存成功')
}
}).catch(err => {
this.$message.error(err)
})
},
importHistory () {
const options = {
filters: [
{ name: 'JSON file', extensions: ['json'] }
],
properties: ['openFile', 'multiSelections']
}
remote.dialog.showOpenDialog(options).then(result => {
if (!result.canceled) {
result.filePaths.forEach(file => {
var str = fs.readFileSync(file)
const json = JSON.parse(str)
history.bulkAdd(json).then(res => {
this.$message.success('导入成功')
this.getAllhistory()
})
})
}
})
},
clearAllHistory () {
history.clear().then(res => {
this.history = []
})
},
getAllhistory () {
history.all().then(res => {
this.history = res.reverse()
})
},
getAllsites () {
sites.all().then(res => {
this.sites = res
})
},
getSiteName (key) {
var site = this.sites.find(e => e.key === key)
if (site) {
return site.name
}
},
deleteEvent (e) {
history.remove(e.id).then(res => {
this.getAllhistory()
}).catch(err => {
this.$message.warning('删除历史记录失败, 错误信息: ' + err)
})
},
updateDatabase (data) {
history.clear().then(res => {
var id = length
data.forEach(ele => {
ele.id = id
id -= 1
history.add(ele)
})
})
},
rowDrop () {
const tbody = document.getElementById('history-table').querySelector('.el-table__body-wrapper tbody')
const _this = this
Sortable.create(tbody, {
onEnd ({ newIndex, oldIndex }) {
const currRow = _this.history.splice(oldIndex, 1)[0]
_this.history.splice(newIndex, 0, currRow)
_this.updateDatabase(_this.history)
}
})
},
getViewMode () {
setting.find().then(res => {
this.viewMode = res.historyViewMode
})
},
updateViewMode () {
setting.find().then(res => {
res.historyViewMode = this.viewMode
setting.update(res)
})
}
},
mounted () {
this.rowDrop()
window.addEventListener('resize', () => {
if (this.$refs.historyWaterfall && this.view === 'History') {
this.$refs.historyWaterfall.resize()
this.$refs.historyWaterfall.refresh()
setTimeout(() => {
this.$refs.historyWaterfall.refresh()
}, 500)
}
}, false)
},
created () {
this.getAllhistory()
this.getViewMode()
}
}
</script>

507
src/components/IPTV.vue Normal file
View File

@@ -0,0 +1,507 @@
<template>
<div class="listpage" id="iptv">
<div class="listpage-header" id="iptv-header" v-show="!enableBatchEdit">
<el-switch v-model="enableBatchEdit" active-text="批处理分组"></el-switch>
<el-button @click.stop="exportChannels" icon="el-icon-upload2" >导出</el-button>
<el-button @click.stop="importChannels" icon="el-icon-download">导入</el-button>
<el-button @click="checkAllChannels" icon="el-icon-refresh" :loading="checkAllChannelsLoading">检测{{ this.checkAllChannelsLoading ? this.checkProgress + '/' + this.iptvList.length : '' }}</el-button>
<el-button @click.stop="resetChannelsEvent" icon="el-icon-refresh-left">重置</el-button>
</div>
<div class="listpage-header" id="iptv-header" v-show="enableBatchEdit">
<el-switch v-model="enableBatchEdit" active-text="批处理分组"></el-switch>
<el-input placeholder="新组名" v-model="batchGroupName"></el-input>
<el-switch v-model="batchIsActive" active-text="启用"></el-switch>
<el-button type="primary" icon="el-icon-edit" @click.stop="saveBatchEdit">保存</el-button>
<el-button @click.stop="removeSelectedChannels" icon="el-icon-delete-solid">删除</el-button>
</div>
<div class="listpage-body" id="iptv-table">
<div class="show-table" id="iptv-table">
<el-table
ref="iptvTable"
size="mini" fit height="100%" row-key="id"
:data="filteredTableData"
@row-click="playEvent"
@select="selectionCellClick"
@selection-change="handleSelectionChange"
@sort-change="handleSortChange">>
<el-table-column
type="selection"
v-if="enableBatchEdit">
</el-table-column>
<el-table-column
default-sort="ascending"
prop="name"
label="频道名">
<template #header>
<el-input
placeholder="搜索"
size="mini"
v-model.trim="searchTxt">
<i slot="prefix" class="el-input__icon el-icon-search"></i>
</el-input>
</template>
</el-table-column>
<el-table-column
prop="isActive"
width="120"
align="center"
:filters = "[{text:'启用', value: true}, {text:'停用', value: false}]"
:filter-method="(value, row) => value === row.isActive"
label="启用">
<template slot-scope="scope">
<el-switch
v-model="scope.row.isActive"
@click.native.stop='isActiveChangeEvent(scope.row)'>
</el-switch>
</template>
</el-table-column>
<el-table-column
sortable
:sort-method="(a , b) => sortByLocaleCompare(a.group, b.group)"
prop="group"
label="分组"
:filters="getFilters"
:filter-method="(value, row) => value === row.group"
filter-placement="bottom-end">
<template slot-scope="scope">
<el-button type="text">{{scope.row.group}}</el-button>
</template>
</el-table-column>
<el-table-column
label="状态"
sortable
:sort-by="['status']"
width="120">
<template slot-scope="scope">
<span v-if="scope.row.status === ' '">
<i class="el-icon-loading"></i>
检测中...
</span>
<span v-else>{{scope.row.status}}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
align="right"
:width="200">
<template #header>
<span>总频道数:{{ iptvList.length }}</span>
</template>
<template slot-scope="scope">
<el-button @click.stop="moveToTopEvent(scope.row)" type="text">置顶</el-button>
<!-- 检测时先强制批量检测一遍,如果不强制直接单个检测时第一次不会显示“检测中”-->
<el-button size="mini" v-if="iptvList.every(channel => channel.status)" v-show="!checkAllChannelsLoading" @click.stop="checkSingleChannel(scope.row)" type="text">检测</el-button>
<el-button @click.stop="removeEvent(scope.row)" type="text">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import { iptv, iptvSearch } from '../lib/dexie'
import { iptv as defaultChannels } from '../lib/dexie/initData'
import zy from '../lib/site/tools'
import { remote } from 'electron'
import fs from 'fs'
import Sortable from 'sortablejs'
export default {
name: 'iptv',
data () {
return {
iptvList: [],
searchTxt: '',
searchRecordList: [],
enableBatchEdit: false,
batchGroupName: '',
batchIsActive: true,
shiftDown: false,
selectionBegin: '',
selectionEnd: '',
multipleSelection: [],
checkAllChannelsLoading: false,
checkProgress: 0,
stopFlag: false,
show: {
search: false
}
}
},
computed: {
view: {
get () {
return this.$store.getters.getView
},
set (val) {
this.SET_VIEW(val)
}
},
setting () {
return this.$store.getters.getSetting
},
video: {
get () {
return this.$store.getters.getVideo
},
set (val) {
this.SET_VIDEO(val)
}
},
filteredTableData () {
if (this.searchTxt) {
return this.iptvList.filter(x => x.name.toLowerCase().includes(this.searchTxt.toLowerCase()))
} else {
return this.iptvList
}
},
getFilters () {
const groups = [...new Set(this.iptvList.map(iptv => iptv.group))]
var filters = []
groups.forEach(g => {
var doc = {
text: g,
value: g
}
filters.push(doc)
})
return filters
}
},
watch: {
view () {
if (this.view === 'IPTV') {
this.getChannels()
}
},
enableBatchEdit () {
if (this.checkAllChannelsLoading) {
this.$message.info('正在检测, 请勿操作.')
this.enableBatchEdit = false
}
}
},
methods: {
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
sortByLocaleCompare (a, b) {
return a.localeCompare(b, 'zh')
},
selectionCellClick (selection, row) {
if (this.shiftDown && this.selectionBegin !== '' && selection.includes(row)) {
this.selectionEnd = row.id
const start = Math.min(this.selectionBegin, this.selectionEnd) - 1
const end = Math.max(this.selectionBegin, this.selectionEnd)
const selections = this.iptvList.slice(start, end)
this.$nextTick(() => {
selections.forEach(e => this.$refs.iptvTable.toggleRowSelection(e, true))
})
this.selectionBegin = this.selectionEnd = ''
return
}
if (selection.includes(row)) {
this.selectionBegin = row.id
} else {
this.selectionBegin = ''
}
},
handleSelectionChange (rows) {
this.multipleSelection = rows
},
handleSortChange (column, prop, order) {
if (this.checkAllChannelsLoading) {
this.$message.info('正在检测, 请勿操作.')
this.enableBatchEdit = false
}
this.updateDatabase()
},
saveBatchEdit () {
this.multipleSelection.forEach(ele => {
if (this.batchGroupName) {
ele.group = this.batchGroupName
}
ele.isActive = this.batchIsActive
})
this.updateDatabase()
},
playEvent (e) {
this.video = { iptv: { name: e.name, url: e.url, id: e.id } }
this.view = 'Play'
},
containsearchTxt (i) {
if (this.searchTxt) {
return i.name.toLowerCase().includes(this.searchTxt.toLowerCase())
} else {
return true
}
},
removeEvent (e) {
if (this.checkAllChannelsLoading) {
this.$message.info('正在检测, 请勿操作.')
return false
}
iptv.remove(e.id).then(res => {
this.getChannels()
}).catch(err => {
this.$message.warning('删除频道失败, 错误信息: ' + err)
})
},
exportChannels () {
const options = {
filters: [
{ name: 'm3u file', extensions: ['m3u'] },
{ name: 'JSON file', extensions: ['json'] }
]
}
remote.dialog.showSaveDialog(options).then(result => {
if (!result.canceled) {
if (result.filePath.endsWith('m3u')) {
var writer = require('m3u').extendedWriter()
this.iptvList.forEach(e => {
writer.file(e.url, -1, e.name)
})
fs.writeFileSync(result.filePath, writer.toString())
this.$message.success('已保存成功')
} else {
const arr = [...this.iptvList]
const str = JSON.stringify(arr, null, 2)
fs.writeFileSync(result.filePath, str)
this.$message.success('已保存成功')
}
}
}).catch(err => {
this.$message.error(err)
})
},
importChannels () {
if (this.checkAllChannelsLoading) {
this.$message.info('正在检测, 请勿操作.')
return false
}
const options = {
filters: [
{ name: 'm3u file', extensions: ['m3u', 'm3u8'] },
{ name: 'JSON file', extensions: ['json'] }
],
properties: ['openFile', 'multiSelections']
}
remote.dialog.showOpenDialog(options).then(result => {
if (!result.canceled) {
var docs = this.iptvList
var id = docs.length + 1
result.filePaths.forEach(file => {
if (file.endsWith('m3u') || file.endsWith('m3u8')) {
const parser = require('iptv-playlist-parser')
const playlist = fs.readFileSync(file, { encoding: 'utf-8' })
const result = parser.parse(playlist)
result.items.forEach(ele => {
if (ele.name && ele.url && ele.url.endsWith('.m3u8')) {
var doc = {
id: id,
name: ele.name,
url: ele.url,
isActive: true,
group: this.determineGroup(ele.name)
}
id += 1
docs.push(doc)
}
})
} else {
// Import Json file
var str = fs.readFileSync(file)
const json = JSON.parse(str)
json.forEach(ele => {
if (ele.name && ele.url && ele.url.endsWith('.m3u8')) {
var doc = {
id: id,
name: ele.name,
url: ele.url,
isActive: ele.isActive === undefined ? true : ele.isActive,
group: this.determineGroup(ele.name)
}
id += 1
docs.push(doc)
}
})
}
})
// 获取name不重复的列表
// const uniqueList = [...new Map(docs.map(item => [item.name, item])).values()]
iptv.clear().then(res => {
iptv.bulkAdd(docs).then(e => { // 支持导入同名频道,群里反馈
this.getChannels()
this.$message.success('导入成功')
})
})
}
})
},
determineGroup (name) {
if (name.toLowerCase().includes('cctv') && (name.includes('蓝光') || name.includes('高清'))) {
return '央视高清'
} else if (name.toLowerCase().includes('cctv')) {
return '央视'
} else if (name.includes('卫视')) {
return '卫视'
} else if (name.includes('香港') || name.includes('澳门') || name.includes('台湾') || name.includes('凤凰')) {
return '港澳台'
} else if (name.includes('高清') || name.includes('蓝光') || name.includes('1080P')) {
return '高清'
} else {
return '其他'
}
},
resetChannelsEvent () {
this.stopFlag = true
if (this.checkAllChannelsLoading) {
this.$message.info('部分检测还未完全终止, 请稍等...')
return
}
iptv.clear().then(iptv.bulkAdd(defaultChannels).then(this.getChannels()))
},
removeSelectedChannels () {
this.multipleSelection.forEach(e => iptv.remove(e.id))
this.$refs.iptvTable.clearFilter()
this.getChannels()
this.updateDatabase()
this.enableBatchEdit = false
},
getChannels () {
iptv.all().then(res => {
res.forEach(ele => {
if (ele.isActive === undefined) {
ele.isActive = true
}
})
this.iptvList = res
})
},
getSearchRecordList () {
iptvSearch.all().then(res => {
this.searchRecordList = res.reverse()
})
},
clearSearch () {
iptvSearch.clear().then(res => {
this.getSearchRecordList()
})
},
searchEvent (wd) {
this.searchTxt = wd
this.show.search = false
if (wd) {
iptvSearch.find({ keywords: wd }).then(res => {
if (!res) {
iptvSearch.add({ keywords: wd })
}
this.getSearchRecordList()
})
}
},
moveToTopEvent (i) {
if (this.checkAllChannelsLoading) {
this.$message.info('正在检测, 请勿操作.')
return false
}
this.iptvList.sort(function (x, y) { return (x.name === i.name && x.url === i.url) ? -1 : (y.name === i.name && y.url === i.url) ? 1 : 0 })
this.updateDatabase()
},
syncTableData () {
if (this.$refs.iptvTable.tableData) {
this.iptvList = this.$refs.iptvTable.tableData
}
},
updateDatabase () {
this.syncTableData()
iptv.clear().then(res => {
this.resetId(this.iptvList)
iptv.bulkAdd(this.iptvList)
})
},
resetId (inArray) {
var id = 1
inArray.forEach(ele => {
ele.id = id
id += 1
})
},
rowDrop () {
if (this.checkAllChannelsLoading) {
this.$message.info('正在检测, 请勿操作.')
return false
}
const tbody = document.getElementById('iptv-table').querySelector('.el-table__body-wrapper tbody')
const _this = this
Sortable.create(tbody, {
onEnd ({ newIndex, oldIndex }) {
const currRow = _this.iptvList.splice(oldIndex, 1)[0]
_this.iptvList.splice(newIndex, 0, currRow)
_this.updateDatabase()
}
})
},
isActiveChangeEvent (row) {
iptv.remove(row.id)
iptv.add(row)
},
async checkAllChannels () {
this.checkAllChannelsLoading = true
this.stopFlag = false
this.checkProgress = 0
const uncheckedList = this.iptvList.filter(e => e.status === undefined || e.status === ' ') // 未检测过的优先
const other = this.iptvList.filter(e => !uncheckedList.includes(e))
await this.checkChannelList(uncheckedList)
await this.checkChannelList(other).then(res => {
this.checkAllChannelsLoading = false
this.getChannels()
})
},
async checkChannelList (channelList) {
var siteList = {}
channelList.forEach(channel => {
const site = channel.url.split('/')[2]
if (siteList[site]) {
siteList[site].push(channel)
} else {
siteList[site] = [channel]
}
})
await Promise.all(Object.values(siteList).map(site => this.checkSingleSite(site)))
},
async checkSingleSite (channelArray) {
for (const c of channelArray) {
if (this.stopFlag) return false
await this.checkSingleChannel(c)
}
},
async checkSingleChannel (row) {
row.status = ' '
if (this.stopFlag) {
this.checkProgress += 1
return row.status
}
const flag = await zy.checkChannel(row.url)
this.checkProgress += 1
if (flag) {
row.status = '可用'
} else {
row.status = '失效'
row.isActive = false
}
iptv.remove(row.id)
iptv.add(row)
return row.status
}
},
mounted () {
this.rowDrop()
addEventListener('keydown', code => { if (code.keyCode === 16) this.shiftDown = true })
addEventListener('keyup', code => { if (code.keyCode === 16) this.shiftDown = false })
},
created () {
this.getChannels()
this.getSearchRecordList()
}
}
</script>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,363 @@
<template>
<div class="listpage" id="recommendataions">
<div class="listpage-header" id="recommendataions-header">
<el-switch v-model="viewMode" active-text="海报" active-value="picture" inactive-text="列表" inactive-value="list" @change="updateViewMode"></el-switch>
<el-button type="text">视频数{{ recommendations.length }}</el-button>
<el-select v-model="selectedAreas" size="small" multiple collapse-tags placeholder="地区" popper-class="popper" :popper-append-to-body="false">
<el-option
v-for="item in areas"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
<el-select v-model="selectedTypes" size="small" multiple collapse-tags placeholder="类型" popper-class="popper" :popper-append-to-body="false">
<el-option
v-for="item in types"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
<el-select v-model="sortKeyword" size="small" placeholder="排序" popper-class="popper" :popper-append-to-body="false">
<el-option
v-for="item in sortKeywords"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
<el-button :loading="loading" @click.stop="updateEvent" icon="el-icon-refresh">更新推荐</el-button>
</div>
<div class="listpage-body" id="recommendataions-body" >
<div class="show-table" id="star-table" v-show="viewMode === 'list'">
<el-table size="mini" fit height="100%" row-key="id"
ref="recommendataionsTable"
:data="filteredRecommendations"
@row-click="detailEvent">
<el-table-column
prop="name"
label="片名">
</el-table-column>
<el-table-column
prop="detail.area"
label="地区"
width="100">
</el-table-column>
<el-table-column
prop="detail.type"
label="类型"
width="100">
</el-table-column>
<el-table-column
prop="detail.year"
label="上映"
width="100"
align="center">
</el-table-column>
<el-table-column v-if="filteredRecommendations.some(e => e.rate)"
prop="rate"
align="center"
width="100"
label="豆瓣评分">
</el-table-column>
<el-table-column v-if="filteredRecommendations.some(e => e.detail.note)"
prop="detail.note"
label="备注">
</el-table-column>
<el-table-column
label="操作"
header-align="center"
align="right"
width="200">
<template slot-scope="scope">
<el-button @click.stop="playEvent(scope.row)" type="text">播放</el-button>
<el-button @click.stop="shareEvent(scope.row)" type="text">分享</el-button>
<el-button @click.stop="downloadEvent(scope.row)" type="text">下载</el-button>
<el-button @click.stop="deleteEvent(scope.row)" type="text">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="show-picture" id="star-picture" v-show="viewMode === 'picture'">
<Waterfall ref="recommendataionsWaterfall" :list="filteredRecommendations" :gutter="20" :width="240"
:breakpoints="{
1200: { //当屏幕宽度小于等于1200
rowPerView: 4,
},
800: { //当屏幕宽度小于等于800
rowPerView: 3,
},
500: { //当屏幕宽度小于等于500
rowPerView: 2,
}
}"
animationDuration="0.5s"
backgroundColor="rgba(0, 0, 0, 0)">
<template slot="item" slot-scope="props">
<div class="card">
<div class="img">
<div class="rate" v-if="props.data.rate && props.data.rate !== '暂无评分'">
<span>{{props.data.rate}}</span>
</div>
<img style="width: 100%" :src="props.data.detail.pic" alt="" @load="$refs.recommendataionsWaterfall.refresh()" @click="detailEvent(props.data)">
<div class="operate">
<div class="operate-wrap">
<span class="o-play" @click="playEvent(props.data)">播放</span>
<span class="o-share" @click="shareEvent(props.data)">分享</span>
<span class="o-star" @click="downloadEvent(props.data)">下载</span>
<span class="o-star" @click="deleteEvent(props.data)">删除</span>
</div>
</div>
</div>
<div class="name" @click="detailEvent(props.data)">{{props.data.name}}</div>
<div class="info">
<span>{{props.data.detail.area}}</span>
<span>{{props.data.detail.year}}</span>
<span>{{props.data.detail.note}}</span>
<span>{{props.data.detail.type}}</span>
</div>
</div>
</template>
</Waterfall>
</div>
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import { history, recommendation, setting } from '../lib/dexie'
import zy from '../lib/site/tools'
import Waterfall from 'vue-waterfall-plugin'
const { clipboard } = require('electron')
export default {
name: 'recommendations',
data () {
return {
recommendations: [],
sites: [],
viewMode: 'picture',
loading: false,
types: [],
selectedTypes: [],
areas: [],
selectedAreas: [],
sortKeyword: '',
sortKeywords: ['上映', '评分', '默认']
}
},
components: {
Waterfall
},
computed: {
view: {
get () {
return this.$store.getters.getView
},
set (val) {
this.SET_VIEW(val)
}
},
video: {
get () {
return this.$store.getters.getVideo
},
set (val) {
this.SET_VIDEO(val)
}
},
detail: {
get () {
return this.$store.getters.getDetail
},
set (val) {
this.SET_DETAIL(val)
}
},
share: {
get () {
return this.$store.getters.getShare
},
set (val) {
this.SET_SHARE(val)
}
},
filteredRecommendations () {
var filteredData = this.recommendations.filter(x => (this.selectedAreas.length === 0) || this.selectedAreas.includes(x.detail.area))
filteredData = filteredData.filter(x => (this.selectedTypes.length === 0) || this.selectedTypes.includes(x.detail.type))
return filteredData
}
},
watch: {
view () {
if (this.view === 'Recommendation') {
this.getRecommendations()
if (this.$refs.recommendataionsWaterfall) {
this.$refs.recommendataionsWaterfall.refresh()
}
}
},
sortKeyword () {
switch (this.sortKeyword) {
case '上映':
this.recommendations = this.recommendations.sort(function (a, b) {
return b.detail.year - a.detail.year
})
break
case '评分':
this.recommendations.sort(function (a, b) {
return b.rate - a.rate
})
break
case '默认':
this.recommendations.sort(function (a, b) {
return b.id - a.id
})
break
default:
break
}
}
},
methods: {
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
detailEvent (e) {
this.detail = {
show: true,
key: e.key,
info: {
id: e.ids,
name: e.name
}
}
},
updateEvent () {
const url = 'https://raw.githubusercontent.com/Hunlongyu/ZY-Player/master/src/lib/dexie/iniData/Recommendations.json'
this.loading = true
const axios = require('axios')
axios.get(url).then(res => {
if (res.status === 200) {
if (res.data.length > 0) {
this.recommendations = res.data.sort(function (a, b) {
return b.detail.year - a.detail.year
})
recommendation.clear().then(recommendation.bulkAdd(this.recommendations))
this.getFilterData()
this.$message.success('更新推荐成功')
}
}
this.loading = false
}).catch(error => {
this.loading = false
this.$message.error('更新推荐失败. ' + error)
})
},
async playEvent (e) {
const db = await history.find({ site: e.key, ids: e.ids })
if (db) {
this.video = { key: e.key, info: { id: db.ids, name: db.name, index: db.index }, detail: db.detail }
} else {
this.video = { key: e.key, info: { id: e.ids, name: e.name, index: 0 }, detail: e.detail }
}
this.view = 'Play'
},
deleteEvent (e) {
recommendation.remove(e.id).then(res => {
if (res) {
this.$message.warning('删除失败')
} else {
this.$message.success('删除成功')
}
this.getRecommendations()
})
},
shareEvent (e) {
this.share = {
show: true,
key: e.key,
info: e
}
},
downloadEvent (e) {
zy.download(e.key, e.ids).then(res => {
if (res && res.dl && res.dl.dd) {
const text = res.dl.dd._t
if (text) {
const list = text.split('#')
let downloadUrl = ''
for (const i of list) {
const url = encodeURI(i.split('$')[1])
downloadUrl += (url + '\n')
}
clipboard.writeText(downloadUrl)
this.$message.success('『MP4』格式的链接已复制, 快去下载吧!')
} else {
this.$message.warning('没有查询到下载链接.')
}
} else {
var m3u8List = {}
zy.detail(e.key, e.ids).then(res => {
const dd = res.dl.dd
const type = Object.prototype.toString.call(dd)
if (type === '[object Array]') {
for (const i of dd) {
if (i._flag.indexOf('m3u8') >= 0) {
m3u8List = i._t.split('#')
}
}
} else {
m3u8List = dd._t.split('#')
}
const list = [...m3u8List]
let downloadUrl = ''
for (const i of list) {
const url = encodeURI(i.split('$')[1])
downloadUrl += (url + '\n')
}
clipboard.writeText(downloadUrl)
this.$message.success('『M3U8』格式的链接已复制, 快去下载吧!')
})
}
})
},
getRecommendations () {
recommendation.all().then(res => {
this.recommendations = res.sort(function (a, b) {
return b.id - a.id
})
this.getFilterData()
})
},
getFilterData () {
this.types = [...new Set(this.recommendations.map(ele => ele.detail.type))].filter(x => x)
this.areas = [...new Set(this.recommendations.map(ele => ele.detail.area))].filter(x => x)
},
getViewMode () {
setting.find().then(res => {
this.viewMode = res.recommendationViewMode
})
},
updateViewMode () {
setting.find().then(res => {
res.recommendationViewMode = this.viewMode
setting.update(res)
})
}
},
created () {
this.getRecommendations()
this.getViewMode()
},
mounted () {
window.addEventListener('resize', () => {
if (this.$refs.recommendataionsWaterfall && this.view === 'Recommendation') {
this.$refs.recommendataionsWaterfall.resize()
this.$refs.recommendataionsWaterfall.refresh()
setTimeout(() => {
this.$refs.recommendataionsWaterfall.refresh()
}, 500)
}
}, false)
}
}
</script>

View File

@@ -1,32 +1,105 @@
<template>
<div class="setting">
<div class="setting-box zy-scroll" v-if="show.setting">
<div class="logo"><img src="@/assets/image/logo.png"></div>
<div class="setting-box zy-scroll">
<div class="logo"><img src="@/assets/image/logo.png" alt=""></div>
<div class="info">
<a @click="linkOpen('http://zyplayer.fun/')">{{$t('website')}}</a>
<a @click="linkOpen('http://zyplayer.fun/')">官网</a>
<a @click="linkOpen('https://github.com/Hunlongyu/ZY-Player')">Github</a>
<a @click="linkOpen('https://github.com/Hunlongyu/ZY-Player/issues')">v{{pkg.version}} {{$t('issues')}}</a>
<a @click="linkOpen('https://github.com/Hunlongyu/ZY-Player/issues')">当前版本v{{pkg.version}} 反馈</a>
<a style="color:#38dd77" @click="quitAndInstall()" v-show="latestVersion !== pkg.version" >最新版本v{{latestVersion}}</a>
</div>
<div class="change">
<div class="zy-select" @mouseleave="show.language = false">
<div class="vs-placeholder" @click="show.language = true">{{$t('language')}}</div>
<div class="vs-options" v-show="show.language">
<ul>
<li :class="s.language === i.key ? 'active' : ''" v-for="(i, j) in languages" :key="j" @click="languageClick(i.key)">{{ i.name }}</li>
</ul>
<div class="view">
<div class="title">视图</div>
<div class="view-box">
<div class="zy-select" @mouseleave="show.view = false">
<div class="vs-placeholder" @click="show.view = true">默认视图</div>
<div class="vs-options" v-show="show.view">
<ul class="zy-scroll">
<li :class="d.view === 'picture' ? 'active' : ''" @click="changeView('picture')">海报</li>
<li :class="d.view === 'table' ? 'active' : ''" @click="changeView('table')">列表</li>
</ul>
</div>
</div>
</div>
<div class="zy-select" @mouseleave="show.site = false">
<div class="vs-placeholder" @click="show.site = true">{{$t('default_site')}}</div>
<div class="vs-options" v-show="show.site">
<ul>
<li :class="s.site === i.key ? 'active' : ''" v-for="(i, j) in sites" :key="j" @click="siteClick(i.key)">{{ i.name }}</li>
</ul>
</div>
<div class="shortcut">
<div class="title">快捷键</div>
<div class="shortcut-box">
<div class="zy-select" @mouseleave="show.shortcut = false">
<div class="vs-placeholder" @click="show.shortcut = true">快捷键</div>
<div class="vs-options" v-show="show.shortcut">
<ul class="zy-scroll">
<li :class="d.shortcut === true ? 'active' : ''" @click="changeShortcut(true)">开启</li>
<li :class="d.shortcut === false ? 'active' : ''" @click="changeShortcut(false)">关闭</li>
</ul>
</div>
</div>
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="expShortcut">导出</div>
</div>
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="impShortcut">导入</div>
</div>
</div>
</div>
<div class="shortcut">
<div class="title">缓存</div>
<div class="shortcut-box">
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="clearCache">清理视频缓存</div>
</div>
</div>
</div>
<div class="site">
<div class="title">定位时间设置</div>
<div class="zy-input">
/右方向键:<input style="width:50px" type="number" v-model = "d.forwardTimeInSec" @change="updateSettingEvent">
</div>
</div>
<div class='site'>
<div class="title">第三方播放</div>
<div class="site-box">
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="selectLocalPlayer">选择本地播放器</div>
</div>
<div class="zy-select" @click = "show.editPlayerPath = true">
<div class="vs-placeholder vs-noAfter" v-show = "show.editPlayerPath == false">
<label>编辑</label>
</div>
<input class="zy-input" v-show = "show.editPlayerPath == true" v-model = "d.externalPlayer"
@blur= "updateSettingEvent"
@keyup.enter = "updateSettingEvent">
</div>
</div>
</div>
<div class="site">
<div class="title">源管理</div>
<div class="site-box">
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="editSitesEvent">编辑源</div>
</div>
<div class="zy-input" @click="toggleExcludeRootClasses">
<input type="checkbox" v-model = "d.excludeRootClasses" @change="updateSettingEvent"> 屏蔽主分类
</div>
</div>
</div>
<div class="site">
<div class="title">网络</div>
<div class="site-box">
<div class="zy-select" @mouseleave="show.proxy = false">
<div class="vs-placeholder" @click="show.proxy = true">代理设置</div>
<div class="vs-options" v-if="show.proxy">
<ul class="zy-scroll">
<li :class="d.proxy.type === 'none' ? 'active' : ''" @click="changeProxyType('none')">不使用代理</li>
<!-- <li :class="d.proxy.type === 'system' ? 'active' : ''" @click="changeProxyType('system')">使用系统代理</li> -->
<li :class="d.proxy.type === 'manual' ? 'active' : ''" @click="changeProxyType('manual')">手动指定代理</li>
</ul>
</div>
</div>
</div>
</div>
<div class="theme">
<div class="title">{{$t('theme')}}</div>
<div class="title">主题</div>
<div class="theme-box">
<div @click="changeTheme('light')" class="theme-item light">
<div class="theme-image">
@@ -54,125 +127,365 @@
</div>
</div>
</div>
<!-- <div class="qrcode">
<div class="title">{{$t('donate')}}</div>
<div class="qrcode">
<div class="title">请作者吃辣条</div>
<div class="qrcode-box">
<img class="qrcode-item" src="../assets/image/alipay.png">
<img class="qrcode-item" src="../assets/image/wepay.jpg">
<img class="qrcode-item" src="../assets/image/wepay-hunlongyu.png">
<img class="qrcode-item" src="../assets/image/wepay_cuiocean.jpg">
</div>
</div> -->
</div>
<div class="clearDB">
<span @click="clearDBEvent" class="clearBtn">{{$t('clearDB')}}</span>
<span class="clearTips">{{$t('clearTips')}}</span>
<span @click="clearDBEvent" class="clearBtn">软件重置</span>
<span @click="changePasswordEvent" class="clearBtn">设置密码</span>
<div class="clearTips">如果新安装用户, 无法显示资源, 请点击软件重置. 如非必要, 切勿点击. 会清空用户数据, 恢复默认设置. 点击即软件重置, 并关闭软件.</div>
</div>
<div class="Tips">
<span>所有资源来自网上, 该软件不参与任何制作, 上传, 储存等内容, 禁止传播违法资源. 该软件仅供学习参考, 请于安装后24小时内删除.</span>
</div>
</div>
<div> <!-- 输入密码页面 -->
<el-dialog :visible.sync="show.checkPasswordDialog" v-if='show.checkPasswordDialog' :append-to-body="true" @close="closeDialog" width="300px">
<el-form label-width="75px" label-position="left">
<el-form-item label="当前密码" prop='name'>
<el-input v-model="inputPassword" placeholder="请输入您的当前密码" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="checkPasswordEvent">确定</el-button>
</span>
</el-dialog>
</div>
<div> <!-- 修改密码页面 -->
<el-dialog :visible.sync="show.changePasswordDialog" v-if='show.changePasswordDialog' :append-to-body="true" @close="closeDialog" width="300px">
<el-form label-width="75px" label-position="left">
<el-form-item label="新密码" prop='name'>
<el-input v-model="inputPassword" placeholder="请输入您的新密码" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="confirmedChangePasswordEvent">确定</el-button>
</span>
</el-dialog>
</div>
<div> <!-- 代理设置界面 -->
<el-dialog :visible.sync="show.proxyDialog" :append-to-body="true" @close="closeDialog" width="400px">
<el-form label-width="50px" label-position="left" size="small">
<el-form-item label="协议: " prop='scheme'>
<el-col :span="15">
<el-select v-model="proxy.scheme" placeholder="请选择协议类型">
<el-option label="http" value="http"></el-option>
<el-option label="socks5" value="socks5"></el-option>
</el-select>
</el-col>
</el-form-item>
<el-form-item label="地址: " prop='url'>
<el-col :span="15">
<el-input v-model="proxy.url" placeholder="地址" />
</el-col>
<el-col class="line" :span="2" style="text-align: center;">:</el-col>
<el-col :span="7">
<el-input v-model="proxy.port" placeholder="端口" width="80px" />
</el-col>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="proxyConfirm">确定</el-button>
</span>
</el-dialog>
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import setting from '../lib/dexie/setting'
import { sites } from '../lib/site/sites'
import db from '../lib/dexie/index'
import '../lib/cloud/index.js'
import { shell } from 'electron'
import pkg from '../../package.json'
const ipc = require('electron').ipcRenderer
import { setting, sites, shortcut } from '../lib/dexie'
import { sites as defaultSites } from '../lib/dexie/initData'
import { shell, clipboard, remote, ipcRenderer } from 'electron'
import db from '../lib/dexie/dexie'
import zy from '../lib/site/tools'
export default {
name: 'setting',
data () {
return {
pkg: pkg,
s: {},
languages: [
{
key: 'zhCn',
name: '中文'
},
{
key: 'en',
name: 'English'
}
],
sites: sites,
shortcutList: [],
show: {
setting: false,
language: false,
site: false
site: false,
shortcut: false,
view: false,
editPlayerPath: false,
checkPasswordDialog: false,
changePasswordDialog: false,
proxy: false,
proxyDialog: false
},
d: { },
latestVersion: pkg.version,
inputPassword: '',
action: '',
proxy: {
type: '',
scheme: '',
url: '',
port: ''
}
}
},
computed: {
theme: {
view: {
get () {
return this.$store.getters.getTheme
return this.$store.getters.getView
},
set (val) {
this.SET_THEME(val)
this.SET_VIEW(val)
}
},
language: {
setting: {
get () {
return this.$store.getters.getLanguage
return this.$store.getters.getSetting
},
set (val) {
this.SET_LANGUAGE(val)
}
},
site: {
get () {
return this.$store.getters.getSite
},
set (val) {
this.SET_SITE(val)
this.SET_SETTING(val)
}
}
},
methods: {
...mapMutations(['SET_THEME', 'SET_LANGUAGE', 'SET_SITE']),
...mapMutations(['SET_SETTING', 'SET_VIEW']),
linkOpen (e) {
shell.openExternal(e)
},
languageClick (e) {
this.language = e
this.show.language = false
this.$i18n.locale = e
this.s.language = e
setting.update(this.s).then(res => {
this.$m.success(this.$t('set_success'))
getSetting () {
setting.find().then(res => {
this.d = res
this.setting = this.d
})
},
siteClick (e) {
this.site = e
this.show.site = false
this.s.site = e
setting.update(this.s).then(res => {
this.$m.success(this.$t('set_success'))
getSites () {
sites.all().then(res => {
if (res.length <= 0) {
this.$message.warning('检测到视频源未能正常加载, 即将重置源.')
sites.clear().then(sites.bulkAdd(defaultSites).then(this.getSites()))
}
})
},
getShortcut () {
shortcut.all().then(res => {
this.shortcutList = res
})
},
changeView (e) {
this.d.view = e
this.updateSettingEvent()
this.show.view = false
},
async clearCache () {
const win = remote.getCurrentWindow()
const ses = win.webContents.session
const size = await ses.getCacheSize() / 1024 / 1024
const mb = size.toFixed(2)
await ses.clearCache()
this.$message.success(`清除缓存成功, 共清理 ${mb} MB`)
},
updateSettingEvent () {
this.show.editPlayerPath = false
this.setting = this.d
setting.update(this.d)
},
toggleExcludeR18Films () {
this.d.excludeR18Films = !this.d.excludeR18Films
this.updateSettingEvent()
},
toggleExcludeRootClasses () {
this.d.excludeRootClasses = !this.d.excludeRootClasses
this.updateSettingEvent()
},
selectLocalPlayer () {
const options = {
filters: [
{ name: 'Executable file', extensions: ['exe'] },
{ name: 'All types', extensions: ['*'] }
],
properties: ['openFile']
}
remote.dialog.showOpenDialog(options).then(result => {
if (!result.canceled) {
var playerPath = result.filePaths[0].replace(/\\/g, '/')
this.$message.success('设定第三方播放器路径为:' + result.filePaths[0])
this.d.externalPlayer = playerPath
this.updateSettingEvent()
}
}).catch(err => {
this.$message.error(err)
})
},
resetLocalPlayer () {
this.d.externalPlayer = ''
setting.update(this.d).then(res => {
this.updateSettingEvent()
this.$message.success('重置第三方播放器成功')
})
},
updatePlayerPath () {
this.$message.success('设定第三方播放器路径为:' + this.d.externalPlayer)
this.show.editPlayerPath = false
this.updateSettingEvent()
},
editSitesEvent () {
if (this.d.password) {
this.action = 'EditSites'
this.show.checkPasswordDialog = true
} else {
this.view = 'EditSites'
}
},
async closeDialog () {
this.show.checkPasswordDialog = false
this.show.changePasswordDialog = false
if (this.show.proxyDialog) {
this.show.proxyDialog = false
this.setting.proxy.type = 'none'
await this.updateSettingEvent()
this.$message.info('取消使用代理')
zy.proxy()
}
this.inputPassword = ''
},
checkPasswordEvent () {
if (this.inputPassword === this.d.password) {
this.closeDialog()
if (this.action === 'EditSites') {
this.view = 'EditSites'
} else if (this.action === 'ChangePassword') {
this.show.changePasswordDialog = true
} else if (this.action === 'CleanDB') {
this.clearDB()
}
} else {
this.$message.error('您输入的密码错误,请重试')
}
},
changePasswordEvent () {
if (this.d.password) {
this.action = 'ChangePassword'
this.show.checkPasswordDialog = true
} else {
this.show.changePasswordDialog = true
}
},
confirmedChangePasswordEvent () {
this.d.password = this.inputPassword
this.updateSettingEvent()
this.closeDialog()
},
changeTheme (e) {
this.theme = e
this.s.theme = e
setting.update(this.s).then(res => {
this.$m.success(this.$t('set_success'))
this.d.theme = e
this.updateSettingEvent()
},
changeShortcut (e) {
this.d.shortcut = e
this.updateSettingEvent()
this.show.shortcut = false
},
expShortcut () {
const arr = [...this.shortcutList]
const str = JSON.stringify(arr, null, 2)
clipboard.writeText(str)
this.$message.success('已复制到剪贴板')
},
impShortcut () {
const str = clipboard.readText()
const json = JSON.parse(str)
shortcut.clear().then(res => {
this.$message.info('已清空原数据')
shortcut.add(json).then(e => {
this.$message.success('已添加成功')
this.getSites()
})
})
},
async changeProxyType (e) {
this.d.proxy.type = e
if (e === 'manual') {
this.show.proxyDialog = true
this.proxy.scheme = this.setting.proxy.scheme
this.proxy.url = this.setting.proxy.url
this.proxy.port = this.setting.proxy.port
}
await this.updateSettingEvent()
this.show.proxy = false
zy.proxy()
},
async proxyConfirm () {
this.d.proxy.scheme = this.proxy.scheme
this.d.proxy.url = this.proxy.url
this.d.proxy.port = this.proxy.port
await this.updateSettingEvent()
this.show.proxyDialog = false
zy.proxy()
this.$message.info('开始使用代理')
},
clearDBEvent () {
if (this.d.password) {
this.action = 'CleanDB'
this.show.checkPasswordDialog = true
} else {
this.clearDB()
}
},
clearDB () {
db.delete().then(res => {
this.$m.success(this.$t('set_success'))
ipc.send('close')
this.$message.success('重置成功')
const win = remote.getCurrentWindow()
win.destroy()
})
},
openDoc (e) {
if (e === 'sites') {
this.linkOpen('http://zyplayer.fun/doc/sites/')
return false
}
if (e === 'shortcut') {
this.linkOpen('http://zyplayer.fun/doc/shortcut/')
return false
}
},
getLatestVersion () {
ipcRenderer.send('checkForUpdate')
ipcRenderer.on('update-available', (e, info) => {
this.latestVersion = info.version
})
ipcRenderer.on('update-error', () => {
this.$message.warning = '更新出错.'
})
ipcRenderer.on('update-downloaded', () => {
this.$message.info = '下载完毕, 退出安装'
})
},
quitAndInstall () {
this.$message.success('已开始下载更新,下载完毕后,将自动退出安装。')
ipcRenderer.send('quitAndInstall')
},
createContextMenu () {
const { Menu, MenuItem } = remote
const menu = new Menu()
menu.append(new MenuItem({ label: '快速复制', role: 'copy' }))
menu.append(new MenuItem({ label: '快速粘贴', role: 'paste' }))
menu.append(new MenuItem({ label: '编辑', role: 'editMenu' }))
window.addEventListener('contextmenu', e => {
e.preventDefault()
menu.popup(remote.getCurrentWindow())
})
}
},
created () {
setting.find().then(res => {
this.s = res
this.theme = res.theme
this.$i18n.locale = this.s.language
this.show.setting = true
})
this.getSites()
this.getSetting()
this.getShortcut()
this.getLatestVersion()
this.createContextMenu()
}
}
</script>
@@ -180,16 +493,16 @@ export default {
.setting{
height: calc(100% - 40px);
width: 100%;
border-radius: 5px;
padding: 20px 0;
.setting-box{
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
border-radius: 5px;
overflow-y: auto;
}
.logo{
.logo{
margin-top: 10px;
width: 100%;
text-align: center;
@@ -209,14 +522,37 @@ export default {
cursor: pointer;
}
}
.change{
.view{
width: 100%;
display: flex;
justify-content: flex-start;
padding-left: 20px;
margin-top: 40px;
.zy-select{
margin-right: 20px;
padding: 20px;
margin-top: 20px;
.view-box{
margin-top: 10px;
.zy-select{
margin-right: 20px;
}
}
}
.site{
width: 100%;
padding: 20px;
margin-top: 20px;
.site-box{
margin-top: 10px;
.zy-select{
margin-right: 20px;
}
}
}
.shortcut{
width: 100%;
padding: 20px;
margin-top: 20px;
.shortcut-box{
margin-top: 10px;
.zy-select{
margin-right: 20px;
}
}
}
.theme{
@@ -225,6 +561,7 @@ export default {
margin-top: 20px;
.theme-box{
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
margin-top: 10px;
.theme-item{
@@ -280,9 +617,9 @@ export default {
line-height: 32px;
}
.clearTips{
margin: 10px 0 0 20px;
font-size: 12px;
color: #ff000088;
margin-left: 10px;
}
}
.Tips{

View File

@@ -1,15 +1,15 @@
<template>
<div class="share" id="share" @click="shareClickEvent">
<div class="share" id="share" @click="shareClickEvent" v-on-clickaway="shareClickEvent">
<div class="left">
<img :src="this.card.img" alt="">
<img :src="pic" alt="" @load="picLoadEvent">
</div>
<div class="right">
<div class="title">{{ card.name }}</div>
<qrcode-vue id="qr" :value="value" :size="160" level="L" />
<div class="right" id="right">
<div class="title">{{ share.info.name }}</div>
<qrcode-vue id="qr" :value="link" :size="160" level="L" />
<div class="tips">
<p>{{$t('qr_tips')}}</p>
<p>长按二维码识别播放</p>
<p><img src="@/assets/image/logo.png"></p>
<p class="zy">{{$t('zy_tips')}}</p>
<p class="zy">ZY Player技术支持严禁传播违法资源</p>
</div>
</div>
<div class="share-mask" v-show="loading">
@@ -19,21 +19,19 @@
</template>
<script>
import { mapMutations } from 'vuex'
import tools from '../lib/site/tools'
import QrcodeVue from 'qrcode.vue'
import html2canvas from 'html2canvas'
import zy from '../lib/site/tools'
import { directive as onClickaway } from 'vue-clickaway'
const { clipboard, nativeImage } = require('electron')
export default {
name: 'share',
data () {
return {
card: {
img: '',
name: '',
png: ''
},
value: '',
loading: true
pic: '',
png: '',
link: '',
loading: false
}
},
components: {
@@ -52,46 +50,59 @@ export default {
watch: {
share: {
handler () {
this.getDetail()
this.getDetail(
this.loading = true
)
},
deep: true
}
},
directives: {
onClickaway: onClickaway
},
methods: {
...mapMutations(['SET_SHARE']),
getDetail () {
this.loading = true
tools.detail_get(this.share.v.site, this.share.v.detail).then(res => {
const info = res.info
const parser = new DOMParser()
const html = parser.parseFromString(info, 'text/html')
const img = html.querySelector('img').src
this.card.img = img
this.card.name = this.share.v.name
const urls = res.m3u8_urls
const url = urls[this.share.v.index].split('$')[1]
this.value = 'http://zyplayer.fun/player/player.html?url=' + url + '&title=' + this.share.v.name
this.loading = false
this.$nextTick(() => {
const dom = document.getElementById('share')
html2canvas(dom, { allowTaint: true, useCORS: true }).then(res => {
const png = res.toDataURL('image/png')
const p = nativeImage.createFromDataURL(png)
clipboard.writeImage(p)
this.$m.success(this.$t('share_tips'))
this.share.show = true
})
})
})
},
shareClickEvent () {
this.share = {
show: false,
v: {}
info: {}
}
},
getDetail () {
this.loading = true
const id = this.share.info.ids || this.share.info.id
zy.detail(this.share.key, id).then(res => {
if (res) {
this.pic = res.pic
var m3u8List = {}
const dd = res.dl.dd
const type = Object.prototype.toString.call(dd)
if (type === '[object Array]') {
for (const i of dd) {
if (i._flag.indexOf('m3u8') >= 0) {
m3u8List = i._t.split('#')
}
}
} else {
m3u8List = dd._t.split('#')
}
const url = m3u8List[1]
this.link = 'http://zyplayer.fun/player/player.html?url=' + url + '&title=' + this.share.info.name
}
this.loading = false
})
},
picLoadEvent () {
const dom = document.getElementById('share')
html2canvas(dom, { useCORS: true, allowTaint: true }).then(res => {
const png = res.toDataURL('image/png')
const p = nativeImage.createFromDataURL(png)
clipboard.writeImage(p)
this.$message.success('已复制到剪贴板,快去分享吧~ 严禁传播违法资源!!!')
})
}
},
created () {
mounted () {
this.getDetail()
}
}
@@ -107,8 +118,8 @@ export default {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px;
z-index: 888;
padding: 0px;
z-index: 999;
.left, .right{
width: 50%;
height: 100%;
@@ -124,6 +135,7 @@ export default {
}
}
.right{
padding: 10px;
.title{
font-size: 18px;
margin-bottom: 10px;

View File

@@ -1,55 +1,158 @@
<template>
<div class="star">
<div class="zy-table">
<div class="tHead">
<span class="name">{{$t('videoName')}}</span>
<span class="type">{{$t('type')}}</span>
<span class="time">{{$t('time')}}</span>
<span class="from">{{$t('from')}}</span>
<span class="operate" style="width: 220px">{{$t('operate')}}</span>
<div class="listpage" id="star">
<div class="listpage-header" id="star-header">
<el-switch v-model="viewMode" active-text="海报" active-value="picture" inactive-text="列表" inactive-value="list" @change="updateViewMode"></el-switch>
<el-button @click.stop="exportFavoritesEvent" icon="el-icon-upload2">导出</el-button>
<el-button @click.stop="importFavoritesEvent" icon="el-icon-download">导入</el-button>
<el-button @click.stop="clearFavoritesEvent" icon="el-icon-delete-solid">清空</el-button>
<el-button @click.stop="updateAllEvent" icon="el-icon-refresh">同步所有收藏</el-button>
</div>
<div class="listpage-body" id="star-body">
<div class="show-table" id="star-table" v-show="viewMode === 'list'">
<el-table size="mini" fit height="100%" row-key="id"
ref="starTable"
:data="list"
:cell-class-name="checkUpdate"
@row-click="detailEvent"
@sort-change="handleSortChange">
<el-table-column
sortable
:sort-method="(a , b) => sortByLocaleCompare(a.name, b.name)"
prop="name"
label="片名">
</el-table-column>
<el-table-column
prop="site.name"
width="120"
label="源站">
<template slot-scope="scope">
<span>{{ getSiteName(scope.row) }}</span>
</template>
</el-table-column>
<el-table-column
sortable
:sort-method="(a , b) => sortByLocaleCompare(a.detail.type, b.detail.type)"
prop="detail.type"
label="类型"
width="100">
</el-table-column>
<el-table-column
sortable
:sort-by="['detail.year', 'name']"
prop="detail.year"
label="上映"
width="100">
</el-table-column>
<el-table-column v-if="list.some(e => e.detail.note)"
prop="detail.note"
width="120"
label="备注">
</el-table-column>
<el-table-column v-if="list.some(e => e.rate && e.rate !== '暂无评分')"
sortable
sort-by="rate"
prop="rate"
width="120"
align="center"
label="豆瓣评分">
</el-table-column>
<el-table-column v-if="list.some(e => e.index >= 0)"
prop="index"
width="120"
label="观看至">
<template slot-scope="scope">
<span>{{ getHistoryNote(scope.row.index) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
header-align="center"
align="right"
width="200">
<template slot-scope="scope">
<el-button @click.stop="playEvent(scope.row)" type="text">播放</el-button>
<el-button @click.stop="shareEvent(scope.row)" type="text">分享</el-button>
<el-button @click.stop="downloadEvent(scope.row)" type="text">下载</el-button>
<el-button @click.stop="deleteEvent(scope.row)" type="text">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="tBody zy-scroll">
<ul v-show="!loading">
<li v-for="(i, j) in data" :key="j" @click="detailEvent(i)">
<span class="name">{{i.name}}</span>
<span class="type">{{i.type}}</span>
<span class="time">{{i.time}}</span>
<span class="from">{{i.site | ftSite}}</span>
<span class="operate" style="width: 220px">
<span class="btn" @click.stop="playEvent(i)">{{$t('play')}}</span>
<span class="btn" @click.stop="deleteEvent(i)">{{$t('delete')}}</span>
<span class="btn" @click.stop="shareEvent(i)">{{$t('share')}}</span>
<span class="btn" @click.stop="updateEvent(i)">{{$t('sync')}}</span>
<span class="btn" @click.stop="downloadEvent(i)">{{$t('download')}}</span>
</span>
</li>
</ul>
<div class="tBody-mask" v-show="loading">
<div class="loader"></div>
</div>
</div>
<div class="tFooter">
<span class="tFooter-span">{{data.length}} {{$t('total')}}</span>
<div class="show-picture" id="star-picture" v-show="viewMode === 'picture'">
<Waterfall ref="starWaterfall" :list="list" :gutter="20" :width="240"
:breakpoints="{
1200: { //当屏幕宽度小于等于1200
rowPerView: 4,
},
800: { //当屏幕宽度小于等于800
rowPerView: 3,
},
500: { //当屏幕宽度小于等于500
rowPerView: 2,
}
}"
animationEffect="fadeIn"
backgroundColor="rgba(0, 0, 0, 0)">
<template slot="item" slot-scope="props">
<div class="card">
<div class="img">
<div class="rate" v-if="props.data.rate && props.data.rate !== '暂无评分'">
<span>{{props.data.rate}}分</span>
</div>
<div class="update" v-if="props.data.hasUpdate">
<span>有更新</span>
</div>
<div class="progress" v-if="props.data.index && props.data.detail && props.data.detail.m3u8List !== undefined && props.data.detail.m3u8List.length > 1">
<span>
看至第{{ props.data.index + 1 }}集
</span>
</div>
<img style="width: 100%" :src="props.data.detail.pic" alt="" @load="$refs.starWaterfall.refresh()" @click="detailEvent(props.data)">
<div class="operate">
<div class="operate-wrap">
<span class="o-play" @click="playEvent(props.data)">播放</span>
<span class="o-share" @click="shareEvent(props.data)">分享</span>
<span class="o-star" @click="downloadEvent(props.data)">下载</span>
<span class="o-star" @click="deleteEvent(props.data)">删除</span>
</div>
</div>
</div>
<div class="name" @click="detailEvent(props.data)">{{props.data.name}}</div>
<div class="info">
<span>{{props.data.detail.area}}</span>
<span>{{props.data.detail.year}}</span>
<span>{{props.data.detail.note}}</span>
<span>{{props.data.detail.type}}</span>
</div>
</div>
</template>
</Waterfall>
</div>
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import tools from '../lib/site/tools'
import video from '../lib/dexie/video'
import { sites, getSite } from '../lib/site/sites'
import { star, sites, setting } from '../lib/dexie'
import zy from '../lib/site/tools'
import { remote } from 'electron'
import fs from 'fs'
import Sortable from 'sortablejs'
import Waterfall from 'vue-waterfall-plugin'
const { clipboard } = require('electron')
export default {
name: 'star',
data () {
return {
sites: sites,
data: [],
loading: true,
checkFlag: false
list: [],
sites: [],
viewMode: 'picture',
numNoUpdate: 0
}
},
components: {
Waterfall
},
computed: {
view: {
get () {
@@ -59,14 +162,6 @@ export default {
this.SET_VIEW(val)
}
},
detail: {
get () {
return this.$store.getters.getDetail
},
set (val) {
this.SET_DETAIL(val)
}
},
video: {
get () {
return this.$store.getters.getVideo
@@ -75,6 +170,14 @@ export default {
this.SET_VIDEO(val)
}
},
detail: {
get () {
return this.$store.getters.getDetail
},
set (val) {
this.SET_DETAIL(val)
}
},
share: {
get () {
return this.$store.getters.getShare
@@ -84,105 +187,321 @@ export default {
}
}
},
filters: {
ftSite (e) {
const name = getSite(e).name
return name
}
},
watch: {
view () {
this.getAllStar()
if (this.view === 'Star') {
this.getAllsites()
this.getFavorites()
if (this.$refs.starWaterfall) {
this.$refs.starWaterfall.refresh()
}
}
},
numNoUpdate () {
// 如果所有收藏都没有更新的话
if (this.numNoUpdate === this.list.length) {
this.numNoUpdate = 0
this.$message.warning('未查询到任何更新')
}
}
},
methods: {
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
handleSortChange (column, prop, order) {
this.updateDatabase()
},
sortByLocaleCompare (a, b) {
return a.localeCompare(b, 'zh')
},
detailEvent (e) {
this.detail = {
show: true,
v: e
key: e.key,
info: {
id: e.ids,
name: e.name
}
}
if (e.hasUpdate) {
this.clearHasUpdateFlag(e)
}
},
playEvent (e) {
this.video = e
async playEvent (e) {
if (e.index) {
this.video = { key: e.key, info: { id: e.ids, name: e.name, index: e.index }, detail: e.detail }
} else {
this.video = { key: e.key, info: { id: e.ids, name: e.name, index: 0 }, detail: e.detail }
}
if (e.hasUpdate) {
this.clearHasUpdateFlag(e)
}
this.view = 'Play'
},
deleteEvent (e) {
video.remove(e.id).then(res => {
star.remove(e.id).then(res => {
if (res) {
this.$m.warning(this.$t('delete_failed'))
this.$message.warning('删除失败')
} else {
this.$m.success(this.$t('delete_success'))
this.$message.success('删除成功')
}
this.getAllStar()
this.getFavorites()
})
},
shareEvent (e) {
this.share = {
show: true,
v: e
key: e.key,
info: e
}
},
checkUpdate ({ row, rowIndex }) {
if (this.list[rowIndex].hasUpdate) {
return 'highlight'
}
},
async clearHasUpdateFlag (e) {
const db = await star.find({ id: e.id })
if (db) {
db.hasUpdate = false
star.update(e.id, db)
this.getFavorites()
}
},
updateEvent (e) {
tools.detail_get(e.site, e.detail).then(res => {
const nameOne = e.name.replace(/\s*/g, '')
const nameTwo = res.name.replace(/\s*/g, '')
if (nameOne === nameTwo) {
this.$m.info(this.$t('async_failed'))
zy.detail(e.key, e.ids).then(detailRes => {
var doc = {
id: e.id,
key: e.key,
ids: e.ids,
site: e.site,
name: e.name,
detail: detailRes,
index: e.index
}
star.get(e.id).then(resStar => {
if (!e.hasUpdate && e.detail.last !== detailRes.last) {
doc.hasUpdate = true
var msg = `同步"${e.name}"成功, 检查到更新。`
this.$message.success(msg)
} else {
this.numNoUpdate += 1
}
star.update(e.id, doc)
this.getFavorites()
})
}).catch(err => {
var msg = `同步"${e.name}"失败, 请重试`
this.$message.warning(msg, err)
})
},
updateAllEvent () {
this.numNoUpdate = 0
this.list.forEach(e => {
this.updateEvent(e)
})
},
downloadEvent (e) {
zy.download(e.key, e.ids).then(res => {
if (res && res.dl && res.dl.dd) {
const text = res.dl.dd._t
if (text) {
const list = text.split('#')
let downloadUrl = ''
for (const i of list) {
const url = encodeURI(i.split('$')[1])
downloadUrl += (url + '\n')
}
clipboard.writeText(downloadUrl)
this.$message.success('『MP4』格式的链接已复制, 快去下载吧!')
} else {
this.$message.warning('没有查询到下载链接.')
}
} else {
const h = e
h.name = res.name
video.update(h.id, h).then(res => {
this.$m.success(this.$t('async_success'))
var m3u8List = {}
zy.detail(e.key, e.ids).then(res => {
const dd = res.dl.dd
const type = Object.prototype.toString.call(dd)
if (type === '[object Array]') {
for (const i of dd) {
if (i._flag.indexOf('m3u8') >= 0) {
m3u8List = i._t.split('#')
}
}
} else {
m3u8List = dd._t.split('#')
}
const list = [...m3u8List]
let downloadUrl = ''
for (const i of list) {
const url = encodeURI(i.split('$')[1])
downloadUrl += (url + '\n')
}
clipboard.writeText(downloadUrl)
this.$message.success('『M3U8』格式的链接已复制, 快去下载吧!')
})
}
})
},
downloadEvent (e) {
tools.detail_get(e.site, e.detail).then(res => {
if (res.mp4_urls.length > 0) {
const urls = [...res.mp4_urls]
let txt = `${e.name}\n`
for (const i of urls) {
const name = i.split('$')[0]
const url = encodeURI(i.split('$')[1])
txt += (name + ': ' + url + '\n')
}
clipboard.writeText(txt)
this.$m.success('〖MP4〗: ' + this.$t('copy_success'))
return false
getSiteName (row) {
if (row.site) {
return row.site.name
} else {
var site = this.sites.find(e => e.key === row.key)
if (site) {
return site.name
}
if (res.m3u8_urls.length > 0) {
const urls = [...res.m3u8_urls]
let txt = `${e.name}\n`
for (const i of urls) {
const name = i.split('$')[0]
const url = encodeURI(i.split('$')[1])
txt += (name + ': ' + url + '\n')
}
clipboard.writeText(txt)
this.$m.success('〖M3U8〗: ' + this.$t('copy_success'))
}
},
getHistoryNote (index) {
if (index !== null && index !== undefined) {
return `第${index + 1}`
} else {
return ''
}
},
getFavorites () {
star.all().then(res => {
this.list = res.sort(function (a, b) {
return b.id - a.id
})
})
},
getAllsites () {
sites.all().then(res => {
this.sites = res
})
},
exportFavoritesEvent () {
const arr = [...this.list]
const str = JSON.stringify(arr, null, 2)
const options = {
filters: [
{ name: 'JSON file', extensions: ['json'] },
{ name: 'Normal text file', extensions: ['txt'] },
{ name: 'All types', extensions: ['*'] }
]
}
remote.dialog.showSaveDialog(options).then(result => {
if (!result.canceled) {
fs.writeFileSync(result.filePath, str)
this.$message.success('导出收藏成功')
}
}).catch(err => {
this.$message.error(err)
})
},
importFavoritesEvent () {
const options = {
filters: [
{ name: 'JSON file', extensions: ['json'] },
{ name: 'Normal text file', extensions: ['txt'] },
{ name: 'All types', extensions: ['*'] }
],
properties: ['openFile', 'multiSelections']
}
remote.dialog.showOpenDialog(options).then(result => {
if (!result.canceled) {
var starList = Array.from(this.list)
var id = this.list.length + 1
result.filePaths.forEach(file => {
var str = fs.readFileSync(file)
const json = JSON.parse(str)
json.reverse().forEach(ele => {
const starExists = starList.some(x => x.key === ele.key && x.ids === ele.ids)
if (!starExists) {
var doc = {
id: id,
key: ele.key,
ids: ele.ids,
site: ele.site === undefined ? ele.site = this.sites.find(x => x.key === ele.key) : ele.site,
name: ele.name,
hasUpdate: ele.hasUpdate,
index: ele.index,
rate: ele.rate,
detail: ele.detail === undefined ? {
director: ele.director,
actor: ele.actor,
type: ele.type,
area: ele.area,
lang: ele.lang,
year: ele.year,
last: ele.last,
note: ele.note
} : ele.detail
}
id += 1
starList.push(doc)
}
})
})
star.clear().then(star.bulkAdd(starList).then(res => {
this.getFavorites()
this.$message.success('导入收藏成功')
}))
}
}).catch(err => {
this.$message.error(err)
})
},
clearFavoritesEvent () {
star.clear().then(e => {
this.getFavorites()
})
},
syncTableData () {
if (this.$refs.starTable.tableData && this.$refs.starTable.tableData.length === this.list.length) {
this.list = this.$refs.starTable.tableData
}
},
updateDatabase () {
this.syncTableData()
star.clear().then(res => {
var id = this.list.length
this.list.forEach(ele => {
ele.id = id
id -= 1
})
star.bulkAdd(this.list)
})
},
rowDrop () {
const tbody = document.getElementById('star-table').querySelector('.el-table__body-wrapper tbody')
const _this = this
Sortable.create(tbody, {
onEnd ({ newIndex, oldIndex }) {
const currRow = _this.list.splice(oldIndex, 1)[0]
_this.list.splice(newIndex, 0, currRow)
_this.updateDatabase()
}
})
},
getAllStar () {
video.all().then(res => {
this.data = res.reverse()
this.loading = false
getViewMode () {
setting.find().then(res => {
this.viewMode = res.starViewMode
})
},
updateViewMode () {
setting.find().then(res => {
res.starViewMode = this.viewMode
setting.update(res)
})
}
},
created () {
this.getAllStar()
this.getFavorites()
this.getViewMode()
},
mounted () {
this.rowDrop()
window.addEventListener('resize', () => {
if (this.$refs.starWaterfall && this.view === 'Star') {
this.$refs.starWaterfall.resize()
this.$refs.starWaterfall.refresh()
setTimeout(() => {
this.$refs.starWaterfall.refresh()
}, 500)
}
}, false)
}
}
</script>
<style lang="scss" scoped>
.star{
height: calc(100% - 40px);
width: 100%;
display: flex;
flex-direction: column;
border-radius: 5px;
}
</style>

View File

@@ -1,22 +1,29 @@
import Vue from 'vue'
import Aside from './Aside'
import Detail from './Detail'
import Film from './Film'
import Frame from './Frame'
import Film from './Film'
import Play from './Play'
import Setting from './Setting'
import Share from './Share'
import Star from './Star'
import Setting from './Setting'
import Detail from './Detail'
import Share from './Share'
import History from './History'
import EditSites from './EditSites'
import IPTV from './IPTV'
import Recommendation from './Recommendation'
export default {
registerComponents () {
Vue.component('Aside', Aside)
Vue.component('Detail', Detail)
Vue.component('Film', Film)
Vue.component('Frame', Frame)
Vue.component('Film', Film)
Vue.component('Play', Play)
Vue.component('Setting', Setting)
Vue.component('Share', Share)
Vue.component('Star', Star)
Vue.component('Setting', Setting)
Vue.component('Detail', Detail)
Vue.component('Share', Share)
Vue.component('History', History)
Vue.component('EditSites', EditSites)
Vue.component('IPTV', IPTV)
Vue.component('Recommendation', Recommendation)
}
}

View File

@@ -1,44 +0,0 @@
const os = require('os')
const macaddress = require('macaddress')
const AV = require('leancloud-storage')
macaddress.one((err, mac) => {
if (err) {
return false
}
AV.init({
appId: 'X6TRIcMjgOG7EJ0t1l5r9In1-gzGzoHsz',
appKey: 'JmkGF9UqkWGQNYDcJ2g1QV1b',
serverURL: 'https://x6tricmj.lc-cn-n1-shared.com'
})
const system = os.hostname() + ' ' + os.type() + ' ' + os.arch()
const query = new AV.Query('ZYPlayer')
query.equalTo('os', system)
query.equalTo('mac', mac)
query.find().then(res => {
// 存储新用户数据
if (res.length === 0) {
const ZYPlayer = AV.Object.extend('ZYPlayer')
const zyPlayer = new ZYPlayer()
zyPlayer.set('os', system)
zyPlayer.set('mac', mac)
zyPlayer.set('times', 1)
zyPlayer.save()
return false
}
// 统计启动次数
if (res.length === 1) {
const id = res[0].id
const times = AV.Object.createWithoutData('ZYPlayer', id)
times.increment('times', 1)
times.save()
return false
}
// 清除冗余数据
if (res.length > 1) {
const arr = res
arr.shift()
AV.Object.destroyAll(arr)
}
})
})

29
src/lib/dexie/dexie.js Normal file
View File

@@ -0,0 +1,29 @@
import Dexie from 'dexie'
import { setting, sites, localKey, iptv, recommendations } from './initData'
const db = new Dexie('zy')
db.version(4).stores({
search: '++id, keywords',
iptvSearch: '++id, keywords',
setting: 'id, theme, site, shortcut, view, externalPlayer, searchGroup, excludeRootClasses, excludeR18Films, forwardTimeInSec, starViewMode, recommandationViewMode, password, proxy',
shortcut: 'name, key, desc',
star: '++id, [key+ids], site, name, detail, index, rate, hasUpdate',
recommendation: '++id, [key+ids], site, name, detail, index, rate, hasUpdate',
sites: '++id, key, name, api, download, isActive, group',
history: '++id, [site+ids], name, type, year, index, time, duration, detail',
mini: 'id, mode, site, ids, name, index, time, url',
iptv: '++id, name, url, group, isActive'
})
db.on('populate', () => {
db.setting.bulkAdd(setting)
db.sites.bulkAdd(sites)
db.shortcut.bulkAdd(localKey)
db.iptv.bulkAdd(iptv)
db.recommendation.bulkAdd(recommendations)
})
db.open()
export default db

View File

@@ -1,11 +1,14 @@
import db from './index'
import db from './dexie'
const { history } = db
export default {
async add (doc) {
return await history.add(doc)
},
async bulkAdd (doc) {
return await history.bulkAdd(doc)
},
async find (doc) {
return await history.get(doc)
return await history.where(doc).first()
},
async update (id, docs) {
return await history.update(id, docs)

View File

@@ -1,33 +1,23 @@
import Dexie from 'dexie'
import history from './history'
import mini from './mini'
import setting from './setting'
import shortcut from './shortcut'
import star from './star'
import sites from './sites'
import search from './search'
import iptvSearch from './iptvSearch'
import iptv from './iptv'
import recommendation from './recommendation'
const db = new Dexie('zy')
db.version(1).stores({
theme: '++id, theme',
site: '++id, site',
video: '++id, name, type, time, detail, urls, index'
})
db.version(2).stores({
setting: 'id, theme, site, language, cloud, cloudKey',
video: '++id, site, name, type, time, detail, index',
history: '++id, site, name, type, time, detail, index, currentTime',
mini: 'id, site, name, type, time, detail, index, currentTime'
})
const initData = [{
id: 0,
theme: 'light',
site: 'zuidazy',
language: 'zhCn',
cloud: false,
cloudKey: ''
}]
db.on('populate', () => {
db.setting.bulkAdd(initData)
})
db.open()
export default db
export {
history,
mini,
setting,
shortcut,
star,
sites,
iptv,
search,
iptvSearch,
recommendation
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,272 @@
[
{
"id": 1,
"key": "mahuazy",
"name": "麻花资源",
"api": "https://www.mhapi123.com/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 2,
"key": "niuniucj",
"name": "牛牛资源",
"api": "http://v.niuniucj.com/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 3,
"key": "88zyw",
"name": "88 影视资源站",
"api": "http://www.88zyw.net/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 4,
"key": "apibdzy",
"name": "百度云资源",
"api": "https://api.apibdzy.com/api.php/provide/vod/at/xml",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 5,
"key": "mbo",
"name": "秒播资源",
"api": "http://caiji.mb77.vip/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 6,
"key": "zuidazy",
"name": "最大资源网",
"api": "http://www.zdziyuan.com/inc/api.php",
"download": "http://www.zdziyuan.com/inc/apidown.php",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 7,
"key": "123ku",
"name": "123 资源",
"api": "http://cj.123ku2.com:12315/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 8,
"key": "okzy",
"name": "OK 资源网",
"api": "http://cj.okzy.tv/inc/api.php",
"download": "http://cj.okzy.tv/inc/apidown.php",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 9,
"key": "kuyunzy",
"name": "酷云资源",
"api": "http://caiji.kuyun98.com/inc/ldg_api.php",
"download": "http://caiji.kuyun98.com/inc/apidown.php",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 10,
"key": "kubozy",
"name": "酷播资源",
"api": "http://api.kbzyapi.com/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 11,
"key": "yongjiuzy",
"name": "永久资源",
"api": "http://cj.yongjiuzyw.com/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 12,
"key": "rrzy",
"name": "人人资源",
"api": "https://www.rrzyw.cc/api.php/provide/vod/from/rrm3u8/at/xml/",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 13,
"key": "bbkdj",
"name": "步步高顶尖资源网",
"api": "http://api.bbkdj.com/api",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 14,
"key": "solezy",
"name": "搜乐资源网",
"api": "https://www.caijizy.vip/api.php/provide/vod/at/xml/",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 15,
"key": "zuixinzy",
"name": "最新资源",
"api": "http://api.zuixinapi.com/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 16,
"key": "605zy",
"name": "605资源",
"api": "http://www.605zy.net/inc/seacmsapi.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 17,
"key": "subo988",
"name": "速播资源站",
"api": "https://www.subo988.com/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 18,
"key": "1886zy",
"name": "1886 资源",
"api": "http://cj.1886zy.co/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 19,
"key": "doubanzy",
"name": "豆瓣电影资源",
"api": "http://v.1988cj.com/inc/api.php",
"download": "http://v.1988cj.com/inc/apidown.php",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 20,
"key": "135zy",
"name": "135 资源网",
"api": "http://cj.zycjw1.com/inc/api.php",
"download": "http://cj.zycjw1.com/inc/apidown.php",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 21,
"key": "mgtvzy",
"name": "芒果 TV 资源网",
"api": "https://api.shijiapi.com/api.php/provide/vod/at/xml/",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 22,
"key": "209zy",
"name": "209 资源",
"api": "http://cj.1156zy.com/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 23,
"key": "kkzy",
"name": "快快资源",
"api": "https://api.kkzy.tv/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 24,
"key": "wolongzy",
"name": "卧龙资源",
"api": "http://cj.wlzy.tv/inc/api_mac.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 25,
"key": "mokazy",
"name": "魔卡资源网",
"api": "https://cj.heiyap.com/api.php/provide/vod/at/xml/",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 26,
"key": "158zy",
"name": "壹伍捌资源网",
"api": "http://cj.158zyz.net:158/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 27,
"key": "kyzy",
"name": "快影资源站",
"api": "https://www.kyzy.tv/api.php/kyyun/vod/at/xml/",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
}
]

136
src/lib/dexie/initData.js Normal file
View File

@@ -0,0 +1,136 @@
const setting = [
{
id: 0,
theme: 'light',
shortcut: true,
view: 'picture',
externalPlayer: '',
searchGroup: '全站',
excludeRootClasses: true,
excludeR18Films: true,
forwardTimeInSec: 5,
starViewMode: 'picture',
recommendationViewMode: 'picture',
historyViewMode: 'picture',
password: '',
proxy: {
type: 'none',
scheme: '',
url: '',
port: ''
}
}
]
const localKey = [
{
name: 'playAndPause',
desc: '播放或暂停',
key: 'space'
},
{
name: 'forward',
desc: '快进',
key: 'right'
},
{
name: 'back',
desc: '快退',
key: 'left'
},
{
name: 'volumeUp',
desc: '音量调高',
key: 'up'
},
{
name: 'volumeDown',
desc: '音量调低',
key: 'down'
},
{
name: 'mute',
desc: '静音',
key: 'm'
},
{
name: 'top',
desc: '置顶或退出置顶',
key: 't'
},
{
name: 'fullscreen',
desc: '进入或退出全屏',
key: 'f'
},
{
name: 'escape',
desc: '退出全屏',
key: 'esc'
},
{
name: 'next',
desc: '下一集',
key: 'alt+right'
},
{
name: 'prev',
desc: '上一集',
key: 'alt+left'
},
{
name: 'home',
desc: '跳到视频开始位置',
key: 'home'
},
{
name: 'end',
desc: '跳到视频结束位置',
key: 'end'
},
{
name: 'opacityUp',
desc: '透明度调高',
key: 'alt+up'
},
{
name: 'opacityDown',
desc: '透明度调低',
key: 'alt+down'
},
{
name: 'playbackRateUp',
desc: '播放倍速加快',
key: 'pageup'
},
{
name: 'playbackRateDown',
desc: '播放倍速减慢',
key: 'pagedown'
},
{
name: 'mini',
desc: '进入或退出mini模式',
key: 'alt+m'
}
]
const getSite = (key) => {
for (const i of sites) {
if (key === i.key) {
return i
}
}
}
const sites = require('./iniData/Sites.json')
const iptv = require('./iniData/Iptv.json')
const recommendations = require('./iniData/Recommendations.json')
export {
setting,
sites,
iptv,
recommendations,
localKey,
getSite
}

25
src/lib/dexie/iptv.js Normal file
View File

@@ -0,0 +1,25 @@
import db from './dexie'
const { iptv } = db
export default {
async all () {
return await iptv.toArray()
},
async clear () {
return await iptv.clear()
},
async add (doc) {
return await iptv.add(doc)
},
async bulkAdd (doc) {
return await iptv.bulkAdd(doc)
},
async find (doc) {
return await iptv.get(doc)
},
async update (id, docs) {
return await iptv.update(id, docs)
},
async remove (id) {
return await iptv.delete(id)
}
}

View File

@@ -0,0 +1,22 @@
import db from './dexie'
const { iptvSearch } = db
export default {
async add (doc) {
return await iptvSearch.add(doc)
},
async find (doc) {
return await iptvSearch.get(doc)
},
async update (id, docs) {
return await iptvSearch.update(id, docs)
},
async all () {
return await iptvSearch.toArray()
},
async remove (id) {
return await iptvSearch.delete(id)
},
async clear () {
return await iptvSearch.clear()
}
}

View File

@@ -1,4 +1,4 @@
import db from './index'
import db from './dexie'
const { mini } = db
export default {
async add (doc) {

View File

@@ -0,0 +1,28 @@
import db from './dexie'
const { recommendation } = db
export default {
async add (doc) {
return await recommendation.add(doc)
},
async bulkAdd (doc) {
return await recommendation.bulkAdd(doc)
},
async find (doc) {
return await recommendation.where(doc).first()
},
async update (id, docs) {
return await recommendation.update(id, docs)
},
async all () {
return await recommendation.toArray()
},
async remove (id) {
return await recommendation.delete(id)
},
async get (id) {
return await recommendation.get(id)
},
async clear () {
return await recommendation.clear()
}
}

22
src/lib/dexie/search.js Normal file
View File

@@ -0,0 +1,22 @@
import db from './dexie'
const { search } = db
export default {
async add (doc) {
return await search.add(doc)
},
async find (doc) {
return await search.get(doc)
},
async update (id, docs) {
return await search.update(id, docs)
},
async all () {
return await search.toArray()
},
async remove (id) {
return await search.delete(id)
},
async clear () {
return await search.clear()
}
}

View File

@@ -1,5 +1,6 @@
import db from './index'
import db from './dexie'
const { setting } = db
export default {
async find () {
return await setting.get({ id: 0 })

14
src/lib/dexie/shortcut.js Normal file
View File

@@ -0,0 +1,14 @@
import db from './dexie'
const { shortcut } = db
export default {
async all () {
return await shortcut.toArray()
},
async clear () {
return await shortcut.clear()
},
async add (doc) {
return await shortcut.bulkAdd(doc)
}
}

22
src/lib/dexie/sites.js Normal file
View File

@@ -0,0 +1,22 @@
import db from './dexie'
const { sites } = db
export default {
async all () {
return await sites.toArray()
},
async clear () {
return await sites.clear()
},
async bulkAdd (doc) {
return await sites.bulkAdd(doc)
},
async find (doc) {
return await sites.get(doc)
},
async add (doc) {
return await sites.add(doc)
},
async remove (id) {
return await sites.delete(id)
}
}

28
src/lib/dexie/star.js Normal file
View File

@@ -0,0 +1,28 @@
import db from './dexie'
const { star } = db
export default {
async add (doc) {
return await star.add(doc)
},
async bulkAdd (doc) {
return await star.bulkAdd(doc)
},
async find (doc) {
return await star.where(doc).first()
},
async update (id, docs) {
return await star.update(id, docs)
},
async all () {
return await star.toArray()
},
async remove (id) {
return await star.delete(id)
},
async get (id) {
return await star.get(id)
},
async clear () {
return await star.clear()
}
}

View File

@@ -1,19 +0,0 @@
import db from './index'
const { video } = db
export default {
async add (doc) {
return await video.add(doc)
},
async find (doc) {
return await video.get(doc)
},
async update (id, docs) {
return await video.update(id, docs)
},
async all () {
return await video.toArray()
},
async remove (id) {
return await video.delete(id)
}
}

View File

@@ -1,6 +1,19 @@
import Vue from 'vue'
import { Message, Pagination } from 'element-ui'
Vue.use(Pagination)
Vue.prototype.$m = Message
import { Message, Button, Table, TableColumn, Tag, Input, Dialog, Form, FormItem, Switch, Select, Option, Checkbox, Autocomplete, Col } from 'element-ui'
import Plugin from 'v-fit-columns'
Vue.use(Button)
Vue.use(Col)
Vue.use(Table)
Vue.use(TableColumn)
Vue.use(Tag)
Vue.use(Input)
Vue.use(Dialog)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Switch)
Vue.use(Plugin)
Vue.use(Select)
Vue.use(Option)
Vue.use(Checkbox)
Vue.use(Autocomplete)
Vue.prototype.$message = Message

317
src/lib/site/onlineVideo.js Normal file
View File

@@ -0,0 +1,317 @@
import open from 'open'
import axios from 'axios'
import cheerio from 'cheerio'
const onlineVideo = {
playVideoOnline (selectedOnlineSite, videoName, videoIndex) {
switch (selectedOnlineSite) {
case '哔嘀':
onlineVideo.playVideoOnBde4(videoName, videoIndex)
break
case '1080影视':
onlineVideo.playVideoOnK1080(videoName, videoIndex)
break
case '素白白':
onlineVideo.playVideoOnSubaibai(videoName, videoIndex)
break
case '哆咪动漫':
onlineVideo.playVideoOndmdm2020(videoName, videoIndex)
break
case '樱花动漫':
onlineVideo.playVideoOnYhdm(videoName, videoIndex)
break
case '简影':
onlineVideo.playVideoOnSyrme(videoName, videoIndex)
break
case '极品':
onlineVideo.playVideoOnJpysvip(videoName, videoIndex)
break
case '喜欢看':
onlineVideo.playVideoOnXhkan(videoName, videoIndex)
break
default:
this.$message.console.error(`不支持该网站:${this.selectedOnlineSite}`)
}
},
playVideoOnBde4 (videoName, videoIndex) {
videoName = videoName.replace(/\s/g, '')
var url = `https://bde4.com/search/${videoName}`
axios.get(url).then(res => {
const $ = cheerio.load(res.data)
var e = $('div.search-list')
var searchResult = $(e).find('div>div>div>div>a').toArray()
// 获取第一个搜索结果的视频链接
var detailPageLink = $(searchResult[0]).attr('href')
// 获取第一个搜索结果的title
var title = $(searchResult[0]).attr('title')
if (title === null || title === undefined || !title.replace(/\s/g, '').includes(videoName)) {
// 如果第一个搜索结果不符合,打开搜索页面
open(url)
} else {
var detailPageFullLink = 'https://bde4.com/' + detailPageLink
// 解析详情页面
axios.get(detailPageFullLink).then(res => {
const $ = cheerio.load(res.data)
var e = $('div.info1')
var videoList = $(e).find('a').toArray()
var videoFullLink = detailPageFullLink
// 获取index视频链接
if (videoIndex < videoList.length) {
var indexVideoLink = $(videoList[videoIndex]).attr('href')
if (indexVideoLink.includes('.htm')) {
videoFullLink = 'https://bde4.com' + indexVideoLink
}
}
open(videoFullLink)
})
}
})
},
playVideoOnK1080 (videoName, videoIndex) {
videoName = videoName.replace(/\s/g, '')
var url = `https://k1080.net/vodsearch123/-------------.html?wd=${videoName}&submit=`
axios.get(url).then(res => {
const $ = cheerio.load(res.data)
var e = $('#searchList')
var searchResult = $(e).find('li>div>a').toArray()
// 获取第一个搜索结果的视频链接
var detailPageLink = $(searchResult[0]).attr('href')
// 获取第一个搜索结果的title
var title = $(searchResult[0]).attr('title')
if (title === null || title === undefined || !title.replace(/\s/g, '').includes(videoName)) {
// 如果第一个搜索结果不符合,打开搜索页面
open(url)
} else {
// 解析详情页面
var detailPageFullLink = 'https://k1080.net' + detailPageLink
axios.get(detailPageFullLink).then(res2 => {
const $ = cheerio.load(res2.data)
// 获取playlist1
var e = $('#playlist1')
// 获取所有视频链接
var videoList = $(e).find('div>ul>li>a').toArray()
var videoFullLink = detailPageFullLink
// 获取index视频链接
if (videoIndex < videoList.length) {
var indexVideoLink = $(videoList[videoIndex]).attr('href')
if (indexVideoLink.includes('.htm')) {
videoFullLink = 'https://k1080.net' + indexVideoLink
}
}
open(videoFullLink)
})
}
})
},
playVideoOnSubaibai (videoName, videoIndex) {
videoName = videoName.replace(/\s/g, '')
var url = `https://www.subaibai.com/xssearch?q=${videoName}`
axios.get(url).then(res => {
const $ = cheerio.load(res.data)
var e = $('div.search_list')
var searchResult = $(e).find('div>ul>li>h3>a').toArray()
// 获取第一个搜索结果的视频链接
var detailPageLink = $(searchResult[0]).attr('href')
// 获取第一个搜索结果的title
var title = $(searchResult[0]).text()
if (title === null || title === undefined || !title.replace(/\s/g, '').includes(videoName)) {
// 如果第一个搜索结果不符合,打开搜索页面
open(url)
} else {
// 解析详情页面
var detailPageFullLink = detailPageLink
axios.get(detailPageFullLink).then(res2 => {
const $ = cheerio.load(res2.data)
// 获取playlist1
var e = $('div.paly_list_btn')
// 获取所有视频链接
var videoList = $(e).find('a').toArray()
// 获取index视频链接
var videoFullLink = detailPageFullLink
if (videoIndex < videoList.length) {
var indexVideoLink = $(videoList[videoIndex]).attr('href')
if (indexVideoLink.includes('.htm')) {
videoFullLink = indexVideoLink
}
}
open(videoFullLink)
})
}
})
},
playVideoOnYhdm (videoName, videoIndex) {
videoName = videoName.replace(/\s/g, '')
var url = `http://www.yhdm.tv/search/${videoName}`
axios.get(url).then(res => {
const $ = cheerio.load(res.data)
var e = $('div.lpic')
var searchResult = $(e).find('div>ul>li>h2>a').toArray()
// 获取第一个搜索结果的视频链接
var detailPageLink = $(searchResult[0]).attr('href')
// 获取第一个搜索结果的title
var title = $(searchResult[0]).attr('title')
if (title === null || title === undefined || !title.replace(/\s/g, '').includes(videoName)) {
// 如果第一个搜索结果不符合,打开搜索页面
open(url)
} else {
// 解析详情页面
var detailPageFullLink = 'http://www.yhdm.tv/' + detailPageLink
axios.get(detailPageFullLink).then(res2 => {
const $ = cheerio.load(res2.data)
// 获取playlist1
var e = $('div.movurl')
// 获取所有视频链接
var videoList = $(e).find('div>ul>li>a').toArray()
// 获取index视频链接
var videoFullLink = detailPageFullLink
if (videoIndex < videoList.length) {
var indexVideoLink = $(videoList[videoIndex]).attr('href')
if (indexVideoLink.includes('.htm')) {
videoFullLink = 'http://www.yhdm.tv/' + indexVideoLink
}
}
open(videoFullLink)
})
}
})
},
playVideoOndmdm2020 (videoName, videoIndex) {
videoName = videoName.replace(/\s/g, '')
var url = `http://www.dmdm2020.com/dongmansearch.html?wd=${videoName}&submit=`
axios.get(url).then(res => {
const $ = cheerio.load(res.data)
var e = $('#searchList')
var searchResult = $(e).find('ul>li>div>h4>a').toArray()
// 获取第一个搜索结果的视频链接
var detailPageLink = $(searchResult[0]).attr('href')
// 获取第一个搜索结果的title
var title = $(searchResult[0]).text()
if (title === null || title === undefined || !title.replace(/\s/g, '').includes(videoName)) {
// 如果第一个搜索结果不符合,打开搜索页面
open(url)
} else {
// 解析详情页面
var detailPageFullLink = 'http://www.dmdm2020.com' + detailPageLink
axios.get(detailPageFullLink).then(res2 => {
const $ = cheerio.load(res2.data)
// 获取playlist1
var e = $('#playlist1')
// 获取所有视频链接
var videoList = $(e).find('div>ul>li>a').toArray()
// 获取index视频链接
var videoFullLink = detailPageFullLink
if (videoIndex < videoList.length) {
var indexVideoLink = $(videoList[videoIndex]).attr('href')
if (indexVideoLink.includes('.htm')) {
videoFullLink = 'http://www.dmdm2020.com' + indexVideoLink
}
}
open(videoFullLink)
})
}
})
},
playVideoOnSyrme (videoName, videoIndex) {
videoName = videoName.replace(/\s/g, '')
var url = `https://syrme.top/searchs?q=${videoName}`
axios.get(url).then(res => {
const $ = cheerio.load(res.data)
var e = $('ul.MovieList')
var searchResult = $(e).find('ul>li>article>a').toArray()
// 获取第一个搜索结果的视频链接
var detailPageLink = $(searchResult[0]).attr('href')
// 获取第一个搜索结果的title
var title = $(searchResult[0]).find('a>h2').text()
if (title === null || title === undefined || !title.replace(/\s/g, '').includes(videoName)) {
// 如果第一个搜索结果不符合,打开搜索页面
open(url)
} else {
// 解析详情页面
var detailPageFullLink = 'https://syrme.top' + detailPageLink
axios.get(detailPageFullLink).then(res2 => {
const $ = cheerio.load(res2.data)
// 获取playlist1
var e = $('#categories-2')
// 获取所有视频链接
var videoList = $(e).find('div>ul>li>a').toArray()
// 获取index视频链接
var videoFullLink = detailPageFullLink
if (videoIndex < videoList.length) {
var indexVideoLink = $(videoList[videoIndex]).attr('href')
videoFullLink = 'https://syrme.top' + indexVideoLink
}
open(videoFullLink)
})
}
})
},
playVideoOnJpysvip (videoName, videoIndex) {
videoName = videoName.replace(/\s/g, '')
var url = `https://www.jpysvip.net/vodsearch/-------------.html?wd=${videoName}&submit=`
axios.get(url).then(res => {
const $ = cheerio.load(res.data)
var e = $('#searchList')
var searchResult = $(e).find('ul>li>div>a').toArray()
// 获取第一个搜索结果的视频链接
var detailPageLink = $(searchResult[0]).attr('href')
// 获取第一个搜索结果的title
var title = $(searchResult[0]).attr('title')
if (title === null || title === undefined || !title.replace(/\s/g, '').includes(videoName)) {
// 如果第一个搜索结果不符合,打开搜索页面
open(url)
} else {
// 解析详情页面
var detailPageFullLink = 'https://www.jpysvip.net' + detailPageLink
axios.get(detailPageFullLink).then(res2 => {
const $ = cheerio.load(res2.data)
// 获取playlist1
var e = $('#playlist1')
// 获取所有视频链接
var videoList = $(e).find('div>ul>li>a').toArray()
// 获取index视频链接
var videoFullLink = detailPageFullLink
if (videoIndex < videoList.length) {
var indexVideoLink = $(videoList[videoIndex]).attr('href')
videoFullLink = 'https://www.jpysvip.net/' + indexVideoLink
}
open(videoFullLink)
})
}
})
},
playVideoOnXhkan (videoName, videoIndex) {
videoName = videoName.replace(/\s/g, '')
var url = `https://www.xhkan.com/vodsearch.html?wd=${videoName}&submit=`
axios.get(url).then(res => {
const $ = cheerio.load(res.data)
var e = $('#searchList')
var searchResult = $(e).find('ul>li>div>a').toArray()
// 获取第一个搜索结果的视频链接
var detailPageLink = $(searchResult[0]).attr('href')
// 获取第一个搜索结果的title
var title = $(searchResult[0]).attr('title')
if (title === null || title === undefined || !title.replace(/\s/g, '').includes(videoName)) {
// 如果第一个搜索结果不符合,打开搜索页面
open(url)
} else {
// 解析详情页面
var detailPageFullLink = detailPageLink
axios.get(detailPageFullLink).then(res2 => {
const $ = cheerio.load(res2.data)
// 获取playlist1
var e = $('#playlist1')
// 获取所有视频链接
var videoList = $(e).find('div>ul>li>a').toArray()
// 获取index视频链接
var videoFullLink = detailPageFullLink
if (videoIndex < videoList.length) {
var indexVideoLink = $(videoList[videoIndex]).attr('href')
videoFullLink = indexVideoLink
}
open(videoFullLink)
})
}
})
}
}
export default onlineVideo

18
src/lib/site/server.js Normal file
View File

@@ -0,0 +1,18 @@
import express from 'express'
import cors from 'cors'
const Axios = require('axios')
const app = express()
app.use(cors())
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.post('/api', async (req, res) => {
const result = await Axios.get(req.body.url)
res.json({
code: 1,
info: result.data
})
})
app.listen(44444)

File diff suppressed because it is too large Load Diff

View File

@@ -1,478 +1,398 @@
import { sites, setting } from '../dexie'
import axios from 'axios'
import { getSite } from './sites'
import parser from 'fast-xml-parser'
import cheerio from 'cheerio'
import { Parser as M3u8Parser } from 'm3u8-parser'
// axios使用系统代理 https://evandontje.com/2020/04/02/automatic-system-proxy-configuration-for-electron-applications/
// xgplayer使用chromium代理设置浏览器又默认使用系统代理 https://www.chromium.org/developers/design-documents/network-settings
// 要在设置中添加代理设置可参考https://stackoverflow.com/questions/37393248/how-connect-to-proxy-in-electron-webview
var http = require('http')
var https = require('http')
const { remote } = require('electron')
var win = remote.getCurrentWindow()
var session = win.webContents.session
var ElectronProxyAgent = require('electron-proxy-agent')
// 请求超时时限
axios.defaults.timeout = 10000 // 可能使用代理,增长超时
// 重试次数共请求3次
axios.defaults.retry = 2
// 请求的间隙
axios.defaults.retryDelay = 1000
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做些事
if (response.status && response.status === 200 && response.request.responseURL.includes('api.php') && !response.data.startsWith('<?xml')) {
}
return response
}, function (err) { // 请求错误时做些事
// 请求超时的之后,抛出 err.code = ECONNABORTED的错误..错误信息是 timeout of xxx ms exceeded
if (err.code === 'ECONNABORTED' && err.message.indexOf('timeout') !== -1) {
var config = err.config
config.__retryCount = config.__retryCount || 0
if (config.__retryCount >= config.retry) {
err.message = '多次请求均超时'
return Promise.reject(err)
}
config.__retryCount += 1
var backoff = new Promise(function (resolve) {
setTimeout(function () {
resolve()
}, config.retryDelay || 1)
})
return backoff.then(function () {
return axios(config)
})
} else {
if (err && !err.response) {
err.message = '连接服务器失败!'
}
return Promise.reject(err)
}
})
const zy = {
key: 'zuidazy', // sites[n] 视频源
id: 0, // 视频类型
page: 1, // 第几页
keywords: '', // 搜索关键字
// 获取浏览列表
film_get (key, id = 0, page = 1) {
xmlConfig: { // XML 转 JSON 配置
trimValues: true,
textNodeName: '_t',
ignoreAttributes: false,
attributeNamePrefix: '_',
parseAttributeValue: true
},
getSite (key) {
return new Promise((resolve, reject) => {
const site = getSite(key)
let url = ''
if (id === 0) {
url = site.new.replace(/{page}/, page)
sites.all().then(res => {
for (const i of res) {
if (key === i.key) {
resolve(i)
}
}
}).catch(err => {
reject(err)
})
})
},
/**
* 获取资源分类 和 所有资源的总数, 分页等信息
* @param {*} key 资源网 key
* @returns
*/
class (key) {
return new Promise((resolve, reject) => {
this.getSite(key).then(res => {
const url = res.api
axios.post(url).then(res => {
const data = res.data
const json = parser.parse(data, this.xmlConfig)
const arr = []
if (json.rss.class) {
for (const i of json.rss.class.ty) {
const j = {
tid: i._id,
name: i._t
}
arr.push(j)
}
}
const doc = {
class: arr,
page: json.rss.list._page,
pagecount: json.rss.list._pagecount,
pagesize: json.rss.list._pagesize,
recordcount: json.rss.list._recordcount
}
resolve(doc)
}).catch(err => {
reject(err)
})
})
})
},
/**
* 获取资源列表
* @param {*} key 资源网 key
* @param {number} [pg=1] 翻页 page
* @param {*} t 分类 type
* @returns
*/
list (key, pg = 1, t) {
return new Promise((resolve, reject) => {
this.getSite(key).then(res => {
const site = res
let url = null
if (t) {
url = `${site.api}?ac=videolist&t=${t}&pg=${pg}`
} else {
url = `${site.api}?ac=videolist&pg=${pg}`
}
axios.post(url).then(async res => {
const data = res.data
const json = parser.parse(data, this.xmlConfig)
const videoList = json.rss.list.video
resolve(videoList)
}).catch(err => {
reject(err)
})
})
})
},
/**
* 获取总资源数, 以及页数
* @param {*} key 资源网
* @param {*} t 分类 type
* @returns page object
*/
page (key, t) {
return new Promise((resolve, reject) => {
this.getSite(key).then(res => {
const site = res
let url = ''
if (t) {
url = `${site.api}?ac=videolist&t=${t}`
} else {
url = `${site.api}?ac=videolist`
}
axios.post(url).then(async res => {
const data = res.data
const json = parser.parse(data, this.xmlConfig)
const pg = {
page: json.rss.list._page,
pagecount: json.rss.list._pagecount,
pagesize: json.rss.list._pagesize,
recordcount: json.rss.list._recordcount
}
resolve(pg)
}).catch(err => {
reject(err)
})
})
})
},
/**
* 搜索资源
* @param {*} key 资源网 key
* @param {*} wd 搜索关键字
* @returns
*/
search (key, wd) {
return new Promise((resolve, reject) => {
this.getSite(key).then(res => {
const site = res
wd = encodeURI(wd)
var url = `${site.api}?wd=${wd}`
axios.post(url, { timeout: 3000 }).then(res => {
const data = res.data
const json = parser.parse(data, this.xmlConfig)
if (json && json.rss && json.rss.list) {
const videoList = json.rss.list.video
resolve(videoList)
}
}).catch(err => {
reject(err)
})
}).catch(err => {
reject(err)
})
})
},
/**
* 获取资源详情
* @param {*} key 资源网 key
* @param {*} id 资源唯一标识符 id
* @returns
*/
detail (key, id) {
return new Promise((resolve, reject) => {
this.getSite(key).then(res => {
const url = `${res.api}?ac=videolist&ids=${id}`
axios.post(url).then(res => {
const data = res.data
const json = parser.parse(data, this.xmlConfig)
const videoList = json.rss.list.video
// Parse m3u8List
var m3u8List = []
const dd = videoList.dl.dd
const type = Object.prototype.toString.call(dd)
if (type === '[object Array]') {
for (const i of dd) {
if (i._flag.indexOf('m3u8') >= 0) {
m3u8List = i._t.split('#')
}
}
} else {
m3u8List = dd._t.split('#')
}
videoList.m3u8List = m3u8List
resolve(videoList)
}).catch(err => {
reject(err)
})
}).catch(err => {
reject(err)
})
})
},
/**
* 下载资源
* @param {*} key 资源网 key
* @param {*} id 资源唯一标识符 id
* @returns
*/
download (key, id) {
return new Promise((resolve, reject) => {
this.getSite(key).then(res => {
const site = res
if (site.download) {
const url = `${site.download}?ac=videolist&ids=${id}&ct=1`
axios.post(url).then(res => {
const data = res.data
const json = parser.parse(data, this.xmlConfig)
const videoList = json.rss.list.video
resolve(videoList)
}).catch(err => {
reject(err)
})
} else {
resolve([])
}
})
})
},
/**
* 检查资源
* @param {*} key 资源网 key
* @returns boolean
*/
async check (key, id) {
try {
const cls = await this.class(key)
if (cls) {
return true
} else {
url = site.view.replace(/{id}/, id).replace(/{page}/, page)
return false
}
const type = site.type
axios.get(url).then(async res => {
const data = res.data
if (type === 0) {
const zeroData = await this.film_get_type_zero(data, key)
resolve(zeroData)
} catch (e) {
return false
}
},
/**
* 检查直播源
* @param {*} channel 直播频道 url
* @returns boolean
*/
async checkChannel (channel) {
return new Promise((resolve, reject) => {
axios.get(channel).then(res => {
const manifest = res.data
var parser = new M3u8Parser()
parser.push(manifest)
parser.end()
var parsedManifest = parser.manifest
if (parsedManifest.segments.length) {
resolve(true)
} else {
resolve(false)
}
if (type === 1) {
const oneData = await this.film_get_type_one(data, key)
resolve(oneData)
}).catch(e => {
resolve(false)
})
})
},
/**
* 获取豆瓣页面链接
* @param {*} name 视频名称
* @returns 豆瓣页面链接,如果没有搜到该视频,返回搜索页面链接
*/
doubanLink (name) {
return new Promise((resolve, reject) => {
// 豆瓣搜索链接
var nameToSearch = name.replace(/\s/g, '')
var doubanSearchLink = 'https://www.douban.com/search?q=' + nameToSearch
axios.get(doubanSearchLink).then(res => {
const $ = cheerio.load(res.data)
// 比较第一和第二给豆瓣搜索结果, 看名字是否相符
var link = ''
var linkInDouban = $($('div.result')[0]).find('div>div>h3>a').first()
var nameInDouban = linkInDouban.text().replace(/\s/g, '')
if (nameToSearch === nameInDouban) {
link = linkInDouban.attr('href')
} else {
linkInDouban = $($('div.result')[1]).find('div>div>h3>a').first()
nameInDouban = linkInDouban.text().replace(/\s/g, '')
if (nameToSearch === nameInDouban) {
link = linkInDouban.attr('href')
}
}
if (type === 2) {
const twoData = await this.film_get_type_two(data, key)
resolve(twoData)
}
if (type === 3) {
const threeData = await this.film_get_type_three(data, key)
resolve(threeData)
if (link) {
resolve(link)
} else {
// 如果没找到符合的链接,返回搜索页面
resolve(doubanSearchLink)
}
}).catch(err => {
reject(err)
})
})
},
film_get_type_zero (txt, key) {
/**
* 获取豆瓣评分
* @param {*} name 视频名称
* @returns 豆瓣评分
*/
doubanRate (name) {
return new Promise((resolve, reject) => {
try {
const parser = new DOMParser()
const html = parser.parseFromString(txt, 'text/html')
const list = html.querySelectorAll('.xing_vb li')
const d = { list: [], total: 0, update: 0 }
const url = getSite(key).url
for (let i = 1; i < list.length - 1; i++) {
const info = {
site: key,
name: list[i].childNodes[1].innerText,
type: list[i].childNodes[3].innerText,
time: list[i].childNodes[5].innerText,
detail: url + list[i].childNodes[1].querySelector('a').getAttribute('href'),
index: 0
}
d.list.push(info)
}
d.update = parseInt(html.querySelectorAll('.xing_top_right li strong')[0].innerText)
let t = html.querySelector('.pages').innerText
t = t.split('条')[0]
t = t.split('共')[1]
d.total = parseInt(t)
resolve(d)
} catch (err) {
reject(err)
}
})
},
film_get_type_one (txt, key) {
return new Promise((resolve, reject) => {
try {
const parser = new DOMParser()
const html = parser.parseFromString(txt, 'text/html')
const list = html.querySelectorAll('.videoContent li')
const d = { list: [], total: 0, update: 0 }
const url = getSite(key).url
for (let i = 0; i < list.length; i++) {
const info = {
site: key,
name: list[i].querySelector('.videoName').innerText,
type: list[i].querySelector('.category').innerText,
time: list[i].querySelector('.time').innerText,
detail: url + list[i].querySelector('.address').getAttribute('href'),
index: 0
}
d.list.push(info)
}
d.update = parseInt(html.querySelectorAll('.header_list li span')[0].innerText)
let t = html.querySelectorAll('.pagination li')
t = t[t.length - 2].innerText
d.total = parseInt(t) * 50
resolve(d)
} catch (err) {
reject(err)
}
})
},
film_get_type_two (txt, key) {
return new Promise((resolve, reject) => {
try {
const parser = new DOMParser()
const html = parser.parseFromString(txt, 'text/html')
const list = html.querySelectorAll('.nr')
const d = { list: [], total: 0, update: 0 }
const url = getSite(key).url
for (let i = 0; i < list.length; i++) {
const info = {
site: key,
name: '',
type: list[i].querySelector('.btn_span').innerText,
time: list[i].querySelector('.hours').innerText,
detail: url + list[i].querySelector('.name').getAttribute('href'),
index: 0
}
let name = list[i].querySelector('.name').innerText
name = name.replace(/^\s*|\s*$/g, '')
info.name = name
d.list.push(info)
}
d.update = parseInt(html.querySelector('.kfs em').innerText)
d.total = parseInt(html.querySelector('.date span').innerText)
let t = html.querySelector('.pag2').innerText
t = t.split('条')[0]
t = t.split('共')[1]
d.total = parseInt(t)
resolve(d)
} catch (err) {
reject(err)
}
})
},
film_get_type_three (txt, key) {
return new Promise((resolve, reject) => {
try {
const parser = new DOMParser()
const html = parser.parseFromString(txt, 'text/html')
const list = html.querySelectorAll('.xing_vb li')
const d = { list: [], total: 0, update: 0 }
const url = getSite(key).url
for (let i = 1; i < list.length - 1; i++) {
const info = {
site: key,
name: list[i].childNodes[1].innerText,
type: list[i].childNodes[2].innerText,
time: list[i].childNodes[3].innerText,
detail: url + list[i].childNodes[1].querySelector('a').getAttribute('href'),
index: 0
}
d.list.push(info)
}
d.update = parseInt(html.querySelectorAll('.xing_top_right li strong')[0].innerText)
let t = html.querySelector('.pages').innerText
t = t.split('条')[0]
t = t.split('共')[1]
d.total = parseInt(t)
resolve(d)
} catch (err) {
reject(err)
}
})
},
// 获取详情
detail_get (key, url) {
return new Promise((resolve, reject) => {
const type = getSite(key).type
axios.get(url).then(async res => {
if (type === 0) {
const zeroData = await this.detail_get_type_zero(res.data, key)
resolve(zeroData)
}
if (type === 1) {
const oneData = await this.detail_get_type_one(res.data, key)
resolve(oneData)
}
if (type === 2) {
const twoData = await this.detail_get_type_two(res.data, key)
resolve(twoData)
}
if (type === 3) {
const threeData = await this.detail_get_type_three(res.data, key)
resolve(threeData)
var nameToSearch = name.replace(/\s/g, '')
this.doubanLink(nameToSearch).then(link => {
if (link.includes('https://www.douban.com/search')) {
resolve('暂无评分')
} else {
axios.get(link).then(response => {
const parsedHtml = cheerio.load(response.data)
var rating = parsedHtml('body').find('#interest_sectl').first().find('strong').first()
if (rating.text()) {
resolve(rating.text().replace(/\s/g, ''))
} else {
resolve('暂无评分')
}
}).catch(err => {
reject(err)
})
}
}).catch(err => {
reject(err)
})
})
},
detail_get_type_zero (txt, key) {
async proxy () {
return new Promise((resolve, reject) => {
try {
const parser = new DOMParser()
const html = parser.parseFromString(txt, 'text/html')
const data = {
site: key,
name: '',
info: '',
desc: '',
m3u8_urls: [],
mp4_urls: []
}
const vodBox = html.querySelector('.vodBox')
data.info = vodBox.innerHTML
const title = html.querySelector('.vodh h2').innerText
const index = html.querySelector('.vodh span').innerText
data.name = title + index
const vodInfo = html.querySelectorAll('.playBox')
for (let i = 0; i < vodInfo.length; i++) {
const k = vodInfo[i].innerText
if (k.indexOf('剧情介绍') >= 0) {
data.desc = vodInfo[i].querySelector('.vodplayinfo').innerText
setting.find().then(db => {
if (db.proxy) {
if (db.proxy.type === 'none') {
session.setProxy({ proxyRules: 'direct://' })
http.globalAgent = https.globalAgent = new ElectronProxyAgent(session)
} else if (db.proxy.type === 'manual') {
if (db.proxy.scheme && db.proxy.url && db.proxy.port) {
const proxyURL = db.proxy.scheme + '://' + db.proxy.url.trim() + ':' + db.proxy.port.trim()
session.setProxy({ proxyRules: proxyURL })
http.globalAgent = https.globalAgent = new ElectronProxyAgent(session)
}
}
}
const vodLi = html.querySelectorAll('.ibox .vodplayinfo li')
const m3u8UrlArr = []
const mp4UrlArr = []
for (let i = 0; i < vodLi.length; i++) {
const j = vodLi[i].innerText
if (j.indexOf('.m3u8') >= 0) {
m3u8UrlArr.push(j)
}
if (j.indexOf('.mp4') >= 0) {
mp4UrlArr.push(j)
}
}
data.m3u8_urls = m3u8UrlArr
data.mp4_urls = mp4UrlArr
resolve(data)
} catch (err) {
reject(err)
}
})
},
detail_get_type_one (txt, key) {
return new Promise((resolve, reject) => {
try {
const parser = new DOMParser()
const html = parser.parseFromString(txt, 'text/html')
const data = {
site: key,
name: '',
info: '',
desc: '',
m3u8_urls: [],
mp4_urls: []
}
let name = html.querySelector('.whitetitle').innerText
name = name.split('')[1].replace(/^\s*|\s*$/g, '')
data.name = name
const vodBox = html.querySelector('.white').innerHTML
data.info = vodBox
const vodInfo = html.querySelectorAll('.white')
for (let i = 0; i < vodInfo.length; i++) {
const k = vodInfo[i].innerText
if (k.indexOf('剧情介绍') >= 0) {
data.desc = vodInfo[i].querySelector('div').innerText
}
}
const vodLi = html.querySelectorAll('.playlist li #m3u8')
const m3u8UrlArr = []
const mp4UrlArr = []
for (let i = 0; i < vodLi.length; i++) {
const j = vodLi[i].value
if (j.indexOf('.m3u8') >= 0) {
m3u8UrlArr.push(j)
}
if (j.indexOf('.mp4') >= 0) {
mp4UrlArr.push(j)
}
}
data.m3u8_urls = m3u8UrlArr
data.mp4_urls = mp4UrlArr
resolve(data)
} catch (err) {
reject(err)
}
})
},
detail_get_type_two (txt, key) {
return new Promise((resolve, reject) => {
try {
const parser = new DOMParser()
const html = parser.parseFromString(txt, 'text/html')
const data = {
site: key,
name: '',
info: '',
desc: '',
m3u8_urls: [],
mp4_urls: []
}
const title = html.querySelector('.vodh h2').innerText
const index = html.querySelector('.vodh span').innerText
data.name = title + index
const vodBox = html.querySelector('.vodBox').innerHTML
data.info = vodBox
data.desc = html.querySelector('.vodplayinfo').innerText
const vodLi = html.querySelectorAll('.vodplayinfo li')
const m3u8UrlArr = []
const mp4UrlArr = []
for (let i = 0; i < vodLi.length; i++) {
const j = vodLi[i].innerText
if (j.indexOf('.m3u8') >= 0) {
m3u8UrlArr.push(j)
}
if (j.indexOf('.mp4') >= 0) {
mp4UrlArr.push(j)
}
}
data.m3u8_urls = m3u8UrlArr
data.mp4_urls = mp4UrlArr
resolve(data)
} catch (err) {
reject(err)
}
})
},
detail_get_type_three (txt, key) {
return new Promise((resolve, reject) => {
try {
const parser = new DOMParser()
const html = parser.parseFromString(txt, 'text/html')
const data = {
site: key,
name: '',
info: '',
desc: '',
m3u8_urls: [],
mp4_urls: []
}
const vodBox = html.querySelector('.vodBox')
data.info = vodBox.innerHTML
const title = html.querySelector('.vodh h2').innerText
const index = html.querySelector('.vodh span').innerText
data.name = title + index
const vodInfo = html.querySelectorAll('.playBox')
for (let i = 0; i < vodInfo.length; i++) {
const k = vodInfo[i].innerText
if (k.indexOf('剧情介绍') >= 0) {
data.desc = vodInfo[i].querySelector('.vodplayinfo').innerHTML
}
}
const vodLi = html.querySelectorAll('.ibox .vodplayinfo li')
const m3u8UrlArr = []
const mp4UrlArr = []
for (let i = 0; i < vodLi.length; i++) {
const j = vodLi[i].innerText
if (j.indexOf('.m3u8') >= 0) {
m3u8UrlArr.unshift(j)
}
if (j.indexOf('.mp4') >= 0) {
mp4UrlArr.unshift(j)
}
}
data.m3u8_urls = m3u8UrlArr
data.mp4_urls = mp4UrlArr
resolve(data)
} catch (err) {
reject(err)
}
})
},
// 搜索列表
search_get (key, keywords = '', page = 1) {
return new Promise((resolve, reject) => {
const site = getSite(key)
const type = site.type
let url = null
if (type === 0) {
url = site.search.replace(/{page}/, page).replace(/{keywords}/, keywords)
}
if (type === 1) {
url = site.search.replace(/{keywords}/, keywords)
}
axios.get(url).then(async res => {
const data = res.data
if (type === 0) {
const zeroData = await this.search_get_type_zero(data, key)
resolve(zeroData)
}
if (type === 1) {
const oneData = await this.search_get_type_one(data, key)
resolve(oneData)
}
if (type === 3) {
const threeData = await this.search_get_type_three(data, key)
resolve(threeData)
}
}).catch(err => {
reject(err)
// 不要删了,留着测试用
// axios.get('https://api.my-ip.io/ip').then(res => console.log(res))
})
})
},
search_get_type_zero (txt, key) {
return new Promise((resolve, reject) => {
try {
const parser = new DOMParser()
const html = parser.parseFromString(txt, 'text/html')
const list = html.querySelectorAll('.xing_vb li')
const d = { list: [], total: 0 }
const url = getSite(key).url
for (let i = 1; i < list.length - 1; i++) {
const info = {
site: key,
name: list[i].childNodes[1].innerText,
type: list[i].childNodes[3].innerText,
time: list[i].childNodes[5].innerText,
detail: url + list[i].childNodes[1].querySelector('a').getAttribute('href'),
index: 0
}
d.list.push(info)
}
const t = html.querySelector('.nvc dd').innerText.replace(/[^\d]/g, '')
d.total = parseInt(t)
resolve(d)
} catch (err) {
reject(err)
}
})
},
search_get_type_one (txt, key) {
return new Promise((resolve, reject) => {
try {
const parser = new DOMParser()
const html = parser.parseFromString(txt, 'text/html')
const list = html.querySelectorAll('.videoContent li')
const d = { list: [], total: 0 }
const url = getSite(key).url
for (let i = 0; i < list.length; i++) {
const info = {
site: key,
name: list[i].querySelector('.videoName').innerText,
type: list[i].querySelector('.category').innerText,
time: list[i].querySelector('.time').innerText,
detail: url + list[i].querySelector('.address').getAttribute('href'),
index: 0
}
d.list.push(info)
}
d.total = list.length
resolve(d)
} catch (err) {
reject(err)
}
})
},
search_get_type_three (txt, key) {
return new Promise((resolve, reject) => {
try {
const parser = new DOMParser()
const html = parser.parseFromString(txt, 'text/html')
const list = html.querySelectorAll('.xing_vb li')
const d = { list: [], total: 0 }
const url = getSite(key).url
for (let i = 1; i < list.length - 1; i++) {
const info = {
site: key,
name: list[i].childNodes[1].innerText,
type: list[i].childNodes[2].innerText,
time: list[i].childNodes[3].innerText,
detail: url + list[i].childNodes[1].querySelector('a').getAttribute('href'),
index: 0
}
d.list.push(info)
}
const t = html.querySelector('.nvc dd').innerText.replace(/[^\d]/g, '')
d.total = parseInt(t)
resolve(d)
} catch (err) {
reject(err)
}
})
}
}
zy.proxy()
export default zy

48
src/lib/update/update.js Normal file
View File

@@ -0,0 +1,48 @@
import { BrowserWindow, ipcMain } from 'electron'
import { autoUpdater } from 'electron-updater'
export function initUpdater (win = BrowserWindow) {
autoUpdater.autoDownload = false
autoUpdater.autoInstallOnAppQuit = false
// 主进程监听检查更新事件
ipcMain.on('checkForUpdate', () => {
autoUpdater.checkForUpdates()
})
// 主进程监听退出并安装事件
ipcMain.on('quitAndInstall', () => {
autoUpdater.downloadUpdate()
})
// 开始检测是否有更新
autoUpdater.on('checking-for-update', () => {
win.webContents.send('checking-for-update')
})
// 检测到有可用的更新
autoUpdater.on('update-available', (info) => {
win.webContents.send('update-available', info)
})
// 没有检测到有可用的更新
autoUpdater.on('update-not-available', () => {
win.webContents.send('update-not-available')
})
// 更新出错
autoUpdater.on('update-error', err => {
win.webContents.send('update-error', err)
})
// 下载更新进度
autoUpdater.on('download-progress', (progressObj) => {
win.webContents.send('download-progress', progressObj)
})
// 下载完成并退出安装
autoUpdater.on('update-downloaded', () => {
win.webContents.send('update-downloaded')
autoUpdater.quitAndInstall()
})
}

View File

@@ -1,52 +0,0 @@
{
"zh": "Chinese",
"en": "English",
"language": "Language",
"default_site": "Default Site",
"view": "View",
"play": "Play",
"star": "Star",
"setting": "Setting",
"exists": "Already exists",
"videoName": "Video Name",
"type": "Type",
"time": "Time",
"operate": "Operate",
"share": "Share",
"detail": "Detail",
"close": "Close",
"download": "Download",
"all_download": "All Download",
"next": "Next",
"play_list": "Play List",
"history": "History",
"top": "Top",
"mini": "Mini",
"no_data": "No Data",
"clear_data": "Clear Data",
"delete": "Delete",
"from": "From",
"sync": "Sync",
"total": "Items",
"website": "Official Website",
"issues": "Issues",
"theme": "Theme",
"donate": "Donate",
"set_success": "Set up successfully.",
"delete_success": "Delete successful.",
"delete_failed": "Delete failed.",
"star_success": "Collection success.",
"first_video": "This is the first episode.",
"last_video": "This is the last episode.",
"qr_tips": "Long click recognition.",
"zy_tips": "Prohibit the dissemination of illegal resources.",
"share_tips": "It has been copied to the clipboard. Please share it~",
"not_support_search": "Search is not supported on this site.",
"copy_success": "has been copied, Download it now",
"async_failed": "Synchronization successful, no updates found.",
"async_success": "Synchronization succeeded, update found.",
"no_history": "No history data.",
"clearDB": "Reset software",
"clearTips": "Click to clear the database and close the software",
"rate": "The current video speed is: "
}

View File

@@ -1,9 +0,0 @@
import en from './en.json'
import zhCn from './zh-cn'
export const defaultLocal = 'zhCn'
export const languages = {
en: en,
zhCn: zhCn
}

View File

@@ -1,52 +0,0 @@
{
"zh": "中文",
"en": "英文",
"language": "语言",
"default_site": "默认源",
"view": "浏览",
"play": "播放",
"star": "收藏",
"setting": "设置",
"exists": "已存在",
"videoName": "视频名称",
"type": "类型",
"time": "时间",
"operate": "操作",
"share": "分享",
"detail": "详情",
"close": "关闭",
"download": "下载",
"all_download": "全集下载",
"next": "下一集",
"play_list": "播放列表",
"history": "历史记录",
"top": "置顶",
"mini": "精简模式",
"no_data": "无数据",
"clear_data": "清空数据",
"delete": "删除",
"from": "来源",
"sync": "同步",
"total": "条数据",
"website": "官网",
"issues": "反馈",
"theme": "主题",
"donate": "捐赠",
"set_success": "设置成功。",
"delete_success": "删除成功。",
"delete_failed": "删除失败。",
"star_success": "收藏成功。",
"first_video": "这已经是第一集了。",
"last_video": "这已经是最后一集了。",
"qr_tips": "长按二维码,识别播放。",
"zy_tips": "『ZY Player』技术支持严禁传播违法资源。",
"share_tips": "已复制到剪贴板,快去分享吧~ 严禁传播违法资源!!!",
"not_support_search": "这个网站不支持搜索。",
"copy_success": "已复制,快去下载吧。",
"async_failed": "同步成功, 未查询到更新。",
"async_success": "同步成功, 查询到更新。",
"no_history": "无历史记录",
"clearDB": "重置软件",
"clearTips": "软件没有问题,请勿重置软件,否则数据丢失概不负责.点击即清空数据库,并关闭软件.",
"rate": "当前视频播放倍速为:"
}

View File

@@ -3,24 +3,11 @@ import App from './App.vue'
import store from './store'
import 'modern-normalize'
import Register from './components/register'
import VueI18n from 'vue-i18n'
import { languages, defaultLocal } from './locales/index'
import './lib/element/index'
Vue.config.productionTip = false
Register.registerComponents()
Vue.use(VueI18n)
const messages = Object.assign(languages)
const i18n = new VueI18n({
locale: defaultLocal,
fallbackLocale: 'zhCn',
messages
})
Vue.config.productionTip = false
new Vue({
store,
i18n,
render: h => h(App)
}).$mount('#app')

View File

@@ -1,169 +1,255 @@
<template>
<div class="mini">
<div class="top">
<div class="header">
<div class="left">
<span class="number" v-show="length > 0">{{index + 1}} / {{length}}</span>
<span class="zy-svg" @click="prevEvent" v-show="index > 0">
<span class="title">
<span v-if="m3u8Arr.length > 1"> {{(video.index + 1)}} </span>{{name}}
</span>
<span class="zy-svg" @click="prevEvent" v-show="video.index > 0">
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="backIconTitle">
<title id="backIconTitle">上一集</title>
<path d="M14 14.74L21 19V5l-7 4.26V5L2 12l12 7v-4.26z"></path>
</svg>
</span>
<span class="zy-svg" @click="nextEvent" v-show="index < (length - 1)">
<span class="zy-svg" @click="nextEvent" v-show="video.index < (m3u8Arr.length - 1)">
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="forwardIconTitle">
<title id="forwardIconTitle">下一集</title>
<path d="M10 14.74L3 19V5l7 4.26V5l12 7-12 7v-4.26z"></path>
</svg>
</span>
<span class="opacity">
<input type="number" min="5" max="100" v-model="opacity" @change="opacityChange"/>
</span>
<span class="opacity" v-show="opacity !== 100">透明度: {{opacity}}</span>
<span class="rate" v-show="rate !== 1">播放速率: {{rate}}</span>
<span class="progress" v-show="progress > 0">播放进度: {{progress}}%</span>
</div>
<div class="right">
<span class="min" @click="frameClickEvent('miniMin')"></span>
<span class="close" @click="frameClickEvent('miniClose')"></span>
<span class="topping" @click="frameClickEvent('top')" title="置顶">
<svg t="1595919317571" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1188" style="width:10px;height:14px"><path d="M43.072 974.72l380.864-301.952 151.936 161.6c0 0 63.424 17.28 67.328-30.72l-3.904-163.584 225.088-259.648 98.048-5.696c0 0 76.928-15.488 21.184-82.752l-275.072-276.928c0 0-74.944-9.6-69.248 59.584l0 75.008L383.552 367.104 225.856 376.64c0 0-57.728 19.2-36.608 69.248l148.16 146.176L43.072 974.72 43.072 974.72z" p-id="1189" :fill="isAlwaysOnTop ? '#555555' : '#ffffff'"></path></svg>
</span>
<span class="min" @click="frameClickEvent('min')" title="最小化">
<svg t="1595917239849" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1155" style="width:8px;height:14px"><path d="M0 479.936C0 444.64 28.448 416 64.064 416L959.936 416C995.328 416 1024 444.736 1024 479.936L1024 544.064C1024 579.392 995.552 608 959.936 608L64.064 608C28.672 608 0 579.264 0 544.064L0 479.936Z" p-id="1156" fill="#ffffff"></path></svg>
</span>
<span class="max" @click="frameClickEvent('max')" title="最大化">
<svg t="1595917343956" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1540" style="width:8px;height:14px"><path d="M416 416 64.064 416C28.448 416 0 444.64 0 479.936L0 544.064C0 579.264 28.672 608 64.064 608L416 608 416 959.936C416 995.552 444.64 1024 479.936 1024L544.064 1024C579.264 1024 608 995.328 608 959.936L608 608 959.936 608C995.552 608 1024 579.36 1024 544.064L1024 479.936C1024 444.736 995.328 416 959.936 416L608 416 608 64.064C608 28.448 579.36 0 544.064 0L479.936 0C444.736 0 416 28.672 416 64.064L416 416Z" p-id="1541" fill="#ffffff"></path></svg>
</span>
<span class="close" @click="frameClickEvent('close')" title="退出精简模式">
<svg t="1595917372551" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1685" style="width:8px;height:14px"><path d="M511.968 376.224 796.096 92.096C833.536 54.624 894.4 54.624 931.84 92.096 969.312 129.568 969.312 190.4 931.84 227.872L647.744 512 931.84 796.096C969.312 833.568 969.312 894.4 931.84 931.872 894.4 969.344 833.536 969.344 796.096 931.872L511.968 647.744 227.84 931.872C190.4 969.344 129.536 969.344 92.096 931.872 54.624 894.4 54.624 833.568 92.096 796.096L376.224 512 92.096 227.872C54.624 190.4 54.624 129.568 92.096 92.096 129.536 54.624 190.4 54.624 227.84 92.096L511.968 376.224Z" p-id="1686" fill="#ffffff"></path></svg>
</span>
</div>
</div>
<div class="bottom">
<div class="footer">
<div id="xg"></div>
</div>
</div>
</template>
<script>
import tools from '../lib/site/tools'
import mini from '../lib/dexie/mini'
import history from '../lib/dexie/history'
import zy from '../lib/site/tools'
import { history, setting, shortcut, mini } from '../lib/dexie'
import mt from 'mousetrap'
import 'xgplayer'
import Hls from 'xgplayer-hls.js'
const ipc = require('electron').ipcRenderer
const { remote, ipcRenderer } = require('electron')
const VIDEO_DETAIL_CACHE = {}
export default {
name: 'mini',
data () {
const win = remote.getCurrentWindow()
return {
xg: null,
config: {
id: 'xg',
lang: 'zh-cn',
url: '',
fluid: true,
lang: 'zh-cn',
width: '100%',
height: '100%',
autoplay: false,
videoInit: true,
screenShot: true,
keyShortcut: 'on',
keyShortcut: 'off',
crossOrigin: true,
cssFullscreen: true,
defaultPlaybackRate: 1,
playbackRate: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 3, 4, 5]
playbackRate: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 3, 4, 5],
controls: false
},
opacity: 100,
name: '',
video: {},
d: {},
index: 0,
length: 0
detail: {},
m3u8Arr: [],
rate: 1,
progress: 0,
isAlwaysOnTop: win.isAlwaysOnTop()
}
},
methods: {
frameClickEvent (e) {
ipc.send(e)
const win = remote.getCurrentWindow()
if (e === 'min') {
win.minimize()
}
if (e === 'max') {
win.isMaximized() ? win.unmaximize() : win.maximize()
}
if (e === 'close') {
ipcRenderer.send('win')
return false
}
if (e === 'top') {
this.isAlwaysOnTop = !this.isAlwaysOnTop
win.setAlwaysOnTop(this.isAlwaysOnTop)
}
},
opacityChange (e) {
ipc.send('miniOpacity', this.opacity / 100)
opacityChange (val) {
const win = remote.getCurrentWindow()
const num = val / 100
win.setOpacity(num)
return false
},
getUrls () {
mini.find().then(res => {
const v = res
if (res.mode === 'iptv') {
this.xg.src = res.url
this.xg.play()
return
}
this.video = res
tools.detail_get(v.site, v.detail).then(res => {
this.d = res
this.index = v.index
this.length = this.d.m3u8_urls.length
const link = res.m3u8_urls[v.index]
const src = link.split('$')[1]
this.xg.src = src
const currentTime = v.currentTime
if (currentTime !== '') {
this.fetchM3u8List(res).then(m3u8Arr => {
this.m3u8Arr = m3u8Arr
this.xg.src = m3u8Arr[res.index]
if (res.time !== 0 || res.time !== '') {
this.xg.play()
this.xg.once('playing', () => {
this.xg.currentTime = currentTime
this.xg.currentTime = res.time
})
} else {
this.xg.play()
}
this.onPlayVideo()
this.xg.on('ended', () => {
if (this.d.m3u8_urls.length > 1 && (this.d.m3u8_urls.length - 1 > this.index)) {
this.video.currentTime = 0
this.videoPlaying()
this.xg.once('ended', () => {
if (m3u8Arr.length > 1 && (m3u8Arr.length - 1 > res.index)) {
this.video.time = 0
this.video.index++
this.index++
let src = this.d.m3u8_urls[this.index]
src = src.split('$')[1]
this.xg.src = src
this.xg.src = m3u8Arr[this.video.index]
this.xg.play()
}
})
})
})
},
onPlayVideo () {
const h = { ...this.video }
history.find({ detail: h.detail }).then(res => {
if (res) {
h.id = res.id
history.update(res.id, h)
} else {
h.currentTime = ''
delete h.id
history.add(h)
fetchM3u8List (info) {
return new Promise((resolve) => {
const cacheKey = info.site + '@' + info.ids
if (VIDEO_DETAIL_CACHE[cacheKey]) {
this.name = VIDEO_DETAIL_CACHE[cacheKey].name
resolve(VIDEO_DETAIL_CACHE[cacheKey].list)
return
}
})
this.timerEvent(h.detail)
},
timerEvent (d) {
this.timer = setInterval(() => {
history.find({ detail: d }).then(res => {
if (res) {
const v = res
v.currentTime = this.xg.currentTime
v.index = this.index
const id = v.id
delete v.id
history.update(id, v)
zy.detail(info.site, info.ids).then(res => {
this.name = res.name
const dd = res.dl.dd
const type = Object.prototype.toString.call(dd)
let m3u8Txt = []
if (type === '[object Array]') {
for (const i of dd) {
if (i._t.indexOf('m3u8') >= 0) {
m3u8Txt = i._t.split('#')
}
}
} else {
m3u8Txt = dd._t.split('#')
}
const m3u8Arr = []
for (const i of m3u8Txt) {
const j = i.split('$')
if (j.length > 1) {
for (let m = 0; m < j.length; m++) {
if (j[m].indexOf('m3u8') >= 0) {
m3u8Arr.push(j[m])
}
}
} else {
m3u8Arr.push(j[0])
}
}
VIDEO_DETAIL_CACHE[cacheKey] = {
list: m3u8Arr,
name: res.name
}
resolve(m3u8Arr)
})
})
},
async videoPlaying () {
const db = await history.find({ site: this.video.site, ids: this.video.ids })
if (db) {
db.index = this.video.index
history.update(db.id, db)
} else {
const doc = {
site: this.video.site,
ids: this.video.ids,
name: this.video.name,
index: this.video.index,
time: 0
}
history.add(doc)
}
this.timerEvent()
},
timerEvent () {
this.timer = setInterval(async () => {
const endTime = this.xg.duration
const currentTime = this.xg.currentTime
const progress = (currentTime / endTime) * 100
this.progress = progress.toFixed(2)
const percent = parseFloat((currentTime / endTime).toFixed(2))
const win = remote.getCurrentWindow()
win.setProgressBar(percent)
const db = await history.find({ site: this.video.site, ids: this.video.ids })
if (db) {
const v = db
v.time = this.xg.currentTime
v.index = this.video.index
const id = v.id
delete v.id
history.update(id, v)
}
}, 10000)
},
prevEvent () {
if (this.index === 0) {
async prevEvent () {
if (this.video.index === 0) {
this.$message.info('已是第一集.')
return false
}
history.find({ detail: this.video.detail }).then(res => {
const v = res
v.index--
const db = await history.find({ site: this.video.site, ids: this.video.ids })
if (db) {
const v = db
const id = v.id
v.index--
delete v.id
history.update(id, v).then(e => {
let src = this.d.m3u8_urls[v.index]
src = src.split('$')[1]
this.xg.src = src
this.index--
this.xg.src = this.m3u8Arr[v.index]
this.video.index--
})
})
}
},
nextEvent () {
if (this.index >= this.d.m3u8_urls.length - 1) {
async nextEvent () {
if (this.video.index >= this.m3u8Arr.length - 1) {
this.$message.info('已是最后一集.')
return false
}
history.find({ detail: this.video.detail }).then(res => {
const v = res
const db = await history.find({ site: this.video.site, ids: this.video.ids })
if (db) {
const v = db
v.index++
const id = v.id
delete v.id
history.update(id, v).then(e => {
let src = this.d.m3u8_urls[v.index]
src = src.split('$')[1]
this.xg.src = src
this.index++
this.xg.src = this.m3u8Arr[v.index]
this.video.index++
})
})
}
},
playbackRateEvent (e) {
let rate = this.xg.playbackRate
@@ -171,59 +257,161 @@ export default {
rate = rate + e
this.xg.playbackRate = rate
}
},
mtEvent () {
setting.find().then(res => {
if (res.shortcut) {
shortcut.all().then(res => {
for (const i of res) {
mt.bind(i.key, () => {
this.shortcutEvent(i.name)
})
}
})
}
})
},
shortcutEvent (e) {
if (e === 'playAndPause') {
if (this.xg) {
if (this.xg.paused) {
this.xg.play()
} else {
this.xg.pause()
}
}
return false
}
if (e === 'forward') {
if (this.xg && !this.xg.paused) {
this.xg.currentTime += 5
}
return false
}
if (e === 'back') {
if (this.xg && !this.xg.paused) {
this.xg.currentTime -= 5
}
return false
}
if (e === 'volumeUp') {
if (this.xg && this.xg.volume < 0.9) {
this.xg.volume += 0.1
}
return false
}
if (e === 'volumeDown') {
if (this.xg && this.xg.volume > 0.2) {
this.xg.volume -= 0.1
}
return false
}
if (e === 'mute') {
if (this.xg) {
this.xg.volume = 0
}
return false
}
if (e === 'top') {
const win = remote.getCurrentWindow()
if (win.isAlwaysOnTop()) {
win.setAlwaysOnTop(false)
} else {
win.setAlwaysOnTop(true)
}
return false
}
if (e === 'fullscreen') {
if (this.xg.fullscreen) {
this.xg.exitFullscreen()
} else {
this.xg.getFullscreen(this.xg.root)
}
return false
}
if (e === 'escape') {
if (this.xg.fullscreen) {
this.xg.exitFullscreen()
this.xg.exitCssFullscreen()
}
return false
}
if (e === 'next') {
this.nextEvent()
return false
}
if (e === 'prev') {
this.prevEvent()
return false
}
if (e === 'home') {
if (this.xg && !this.xg.paused) {
this.xg.currentTime = 0
}
return false
}
if (e === 'end') {
if (this.xg && !this.xg.paused) {
const endTime = this.xg.duration
this.xg.currentTime = endTime
}
return false
}
if (e === 'opacityUp') {
const win = remote.getCurrentWindow()
if (this.opacity >= 10) {
this.opacity -= 5
const num = this.opacity / 100
win.setOpacity(num)
}
return false
}
if (e === 'opacityDown') {
const win = remote.getCurrentWindow()
if (this.opacity <= 95) {
this.opacity += 5
const num = this.opacity / 100
win.setOpacity(num)
}
return false
}
if (e === 'playbackRateUp') {
if (this.xg && !this.xg.paused) {
const rate = this.xg.playbackRate
this.xg.playbackRate = rate + 0.25
this.rate = this.xg.playbackRate
}
return false
}
if (e === 'playbackRateDown') {
if (this.xg && !this.xg.paused) {
const rate = this.xg.playbackRate
if (rate > 0.25) {
this.xg.playbackRate = rate - 0.25
this.rate = this.xg.playbackRate
}
}
return false
}
if (e === 'mini') {
ipcRenderer.send('win')
return false
}
}
},
created () {
this.getUrls()
},
mounted () {
this.xg = new Hls(this.config)
ipc.on('next', () => {
if (this.xg) {
if (this.xg.hasStart) {
this.nextEvent()
}
}
})
ipc.on('prev', () => {
if (this.xg) {
if (this.xg.hasStart) {
this.prevEvent()
}
}
})
ipc.on('up', () => {
if (this.opacity <= 95) {
this.opacity = this.opacity + 5
this.opacityChange(this.opacity)
}
})
ipc.on('down', () => {
if (this.opacity >= 10) {
this.opacity = this.opacity - 5
this.opacityChange(this.opacity)
}
})
ipc.on('playbackRateUp', () => {
if (this.xg) {
if (this.xg.hasStart) {
this.playbackRateEvent(0.25)
}
}
})
ipc.on('playbackRateDown', () => {
if (this.xg) {
if (this.xg.hasStart) {
this.playbackRateEvent(-0.25)
}
}
})
this.mtEvent()
this.getUrls()
},
beforeDestroy () {
clearInterval(this.timer)
}
}
</script>
<style lang="scss">
html,body{
padding: 0;
padding: 1px;
margin: 0;
height: 100%;
width: 100%;
@@ -231,11 +419,18 @@ html,body{
background-color: #000;
}
.mini{
-webkit-app-region: drag;
box-sizing: border-box;
.top{
-webkit-app-region: drag;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: flex-start;
flex-direction: column;
.header{
width: 100%;
height: 30px;
min-height: 30px;
display: flex;
justify-content: space-between;
align-items: center;
@@ -249,7 +444,7 @@ html,body{
svg{
width: 24px;
height: 24px;
stroke: #fff;
stroke: #888;
stroke-width: 1;
stroke-linecap: round;
stroke-linejoin: round;
@@ -262,38 +457,38 @@ html,body{
align-items: center;
height: 100%;
flex: 1;
.number{
color: #fff;
margin: 0 10px;
.title, .opacity, .rate, .progress{
color: #888;
font-size: 12px;
}
.opacity{
-webkit-app-region: no-drag;
margin-left: 10px;
input{
text-indent: 4px;
background-color: #000;
color: #fff;
border: 1px solid #aaa;
}
margin: 0 10px;
}
}
.right{
width: 80px;
width: 100px;
height: 100%;
display: flex;
justify-content: flex-end;
align-items: center;
span{
-webkit-app-region: no-drag;
display: inline-block;
width: 16px;
height: 16px;
display: flex;
align-items: center;
justify-content: center;
width: 15px;
height: 15px;
text-align: center;
line-height: 15px;
border-radius: 50%;
margin-right: 10px;
cursor: pointer;
opacity: 0.5;
opacity: 0.4;
&.topping{
background-color: #f3bab7;
}
&.min{
background-color: #32dc36;
}
&.max{
background-color: #ffbe2a;
}
&.close{
@@ -329,9 +524,12 @@ html,body{
}
}
}
.bottom{
.footer{
width: 100%;
height: 305px;
flex: 1;
.xgplayer-start{
-webkit-app-region: no-drag;
}
}
}
</style>

View File

@@ -1,5 +1,8 @@
import Vue from 'vue'
import Mini from './Mini'
import 'modern-normalize'
import '../lib/element/index'
Vue.config.productionTip = false
new Vue({

View File

@@ -6,63 +6,68 @@ Vue.use(Vuex)
export default new Vuex.Store({
state: {
view: 'Film',
theme: 'light',
site: 'zuidazy',
language: 'zhCn',
setting: {
theme: 'light',
site: 'zuidazy',
view: 'picture',
shortcut: true
},
detail: {
show: false,
v: {}
key: '',
info: {}
},
share: {
show: false,
v: {}
key: '',
info: {}
},
video: {}
video: {
key: '',
info: {}
},
editSites: {
sites: []
}
},
getters: {
getView: state => {
return state.view
},
getTheme: state => {
return state.theme
},
getSite: state => {
return state.site
},
getLanguage: state => {
return state.language
getSetting: state => {
return state.setting
},
getDetail: state => {
return state.detail
},
getShare: state => {
return state.share
},
getVideo: state => {
return state.video
},
getShare: state => {
return state.share
getEditSites: state => {
return state.editSites
}
},
mutations: {
SET_VIEW: (state, payload) => {
state.view = payload
},
SET_THEME: (state, payload) => {
state.theme = payload
},
SET_SITE: (state, payload) => {
state.site = payload
},
SET_LANGUAGE: (state, payload) => {
state.language = payload
SET_SETTING: (state, payload) => {
state.setting = payload
},
SET_DETAIL: (state, payload) => {
state.detail = payload
},
SET_SHARE: (state, payload) => {
state.share = payload
},
SET_VIDEO: (state, payload) => {
state.video = payload
},
SET_SHARE: (state, payload) => {
state.share = payload
SET_EDITSITES: (state, payload) => {
state.editSites = payload
}
}
})

10410
yarn.lock Normal file

File diff suppressed because it is too large Load Diff