Compare commits

...

506 Commits

Author SHA1 Message Date
haiyangcui
8a5800df93 v2.6.8 2020-11-30 12:37:40 +01:00
haiyangcui
8cd2b920c8 降级xgplayer回2.13.1,新版居然不支持缓冲了. 2020-11-30 11:37:13 +01:00
haiyangcui
5b4cb43aa5 如果源站返回多个视频列表的话, 仅获取m3u8列表 2020-11-30 11:21:55 +01:00
haiyangcui
de1472e668 升级依赖 2020-11-30 10:56:24 +01:00
haiyangcui
0f846b996b 设置播放器默认预加载300秒 2020-11-29 20:11:23 +01:00
cuiocean
2bd5e31a28 Merge pull request #362 from Hunlongyu/dependabot/npm_and_yarn/highlight.js-9.18.5
Bump highlight.js from 9.18.1 to 9.18.5
2020-11-29 20:04:32 +01:00
haiyangcui
9d8dc9ecb1 删除不工作的cctv蓝光源 2020-11-29 16:53:24 +01:00
haiyangcui
2a073e4092 v2.6.7 2020-11-29 16:26:37 +01:00
haiyangcui
b1daa73afe 更新推荐 2020-11-29 16:23:15 +01:00
haiyangcui
18940ff9f7 Revert "更新视频源,删除无效源,添加需要解析的腾讯,搜狐视频等源"
This reverts commit 76d4d68401.
2020-11-29 13:27:20 +01:00
haiyangcui
76d4d68401 更新视频源,删除无效源,添加需要解析的腾讯,搜狐视频等源 2020-11-28 13:00:29 +01:00
haiyangcui
f91200e609 非m3u8视频,使用在线解析网站播放 2020-11-28 12:46:10 +01:00
haiyangcui
b64f500710 Download函数内解析m3u8List,改进downloadEvent函数 2020-11-28 12:30:43 +01:00
haiyangcui
cf1cfe9f77 支持某些源返回json数据不包含rss层 2020-11-28 11:47:48 +01:00
Hunlongyu
da4fe162f6 Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player into master 2020-11-28 09:44:37 +08:00
Hunlongyu
d949c52020 代码优化 2020-11-28 09:44:32 +08:00
buvta
1ce9e0525b Merge branch 'master' into master 2020-11-25 23:38:06 +08:00
dependabot[bot]
4ebf82eae0 Bump highlight.js from 9.18.1 to 9.18.5
Bumps [highlight.js](https://github.com/highlightjs/highlight.js) from 9.18.1 to 9.18.5.
- [Release notes](https://github.com/highlightjs/highlight.js/releases)
- [Changelog](https://github.com/highlightjs/highlight.js/blob/9.18.5/CHANGES.md)
- [Commits](https://github.com/highlightjs/highlight.js/compare/9.18.1...9.18.5)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-25 06:15:54 +00:00
buvta
e0b1a5332d iptv优化 2020-11-24 22:27:49 +08:00
buvta
3ecb4302ba iptv优化 2020-11-24 16:46:29 +08:00
buvta
5c39db8ca6 iptv恢复"播放",避免行点击时误操作 2020-11-23 16:34:53 +08:00
buvta
4f45045d18 精简模式alt+m切换进入退出 2020-11-23 16:34:53 +08:00
buvta
b7733179f2 导入直播源时允许网址带参数 2020-11-23 16:34:53 +08:00
haiyangcui
e1f7044ae0 数据更新后,刷新页面 2020-11-22 20:57:27 +01:00
buvta
93e76db444 恢复记录mini窗口状态
This reverts commit bedd1339df.
2020-11-22 23:48:50 +08:00
buvta
6eaa281e4a 直播主窗口隐藏退出mini图标 2020-11-22 23:31:30 +08:00
buvta
490d34e1fb 移除iptvSearch数据库 2020-11-22 22:39:42 +08:00
buvta
0d0d6bd90f iptv移除iptvSearch 2020-11-22 22:35:48 +08:00
buvta
ecdc96d2f3 Play样式相应调整 2020-11-22 22:35:48 +08:00
buvta
234f6dd069 Play频道搜索用el-input替代 2020-11-22 22:35:38 +08:00
haiyangcui
f80fe7ecf1 添加退出精简模式按钮 2020-11-22 14:37:30 +01:00
haiyangcui
6876721567 进入精简模式,无需设置大小位置,直接调用getCssFullscreen即可 2020-11-22 12:41:22 +01:00
haiyangcui
bedd1339df Revert "记录mini窗口大小" 2020-11-22 12:09:36 +01:00
hunlongyu
0a3a7a4d57 Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player 2020-11-22 16:38:49 +08:00
hunlongyu
786e23f5a2 删除冗余代码 2020-11-22 16:38:43 +08:00
buvta
418f14bcc1 调整Ctrl+0描述(弹窗容不下) 2020-11-22 11:20:00 +08:00
buvta
a9e4a34e4f 精简模式添加快捷键Ctrl+0用于恢复默认 2020-11-22 10:56:30 +08:00
buvta
fede7e4ef2 Revert "mini模式,大小直接设置为当前窗口大小,无需记录到数据库中"
This reverts commit f92af48a4e.
2020-11-22 10:41:19 +08:00
buvta
956ebbf8b8 调整Play页面channelList加载策略 2020-11-22 10:32:26 +08:00
haiyangcui
014dac0b64 排序源站,把可用的放上面 2020-11-21 23:37:05 +01:00
haiyangcui
5fc1020e79 升级所有依赖到最新版 2020-11-21 22:48:44 +01:00
haiyangcui
aca487f796 升级依赖 2020-11-21 22:41:09 +01:00
haiyangcui
429eb4aac0 移动getChannelList到if里,避免不必要的开销 2020-11-21 22:27:26 +01:00
haiyangcui
e032f86d3d 切换视图时,无需更新页面和改变infiniteId 2020-11-21 22:16:06 +01:00
haiyangcui
f92af48a4e mini模式,大小直接设置为当前窗口大小,无需记录到数据库中 2020-11-21 19:07:05 +01:00
haiyangcui
eff69db063 infiniteId会在classClick里更新 2020-11-21 18:52:33 +01:00
haiyangcui
a5c8d20635 更新麻花资源的api链接 2020-11-21 18:39:33 +01:00
haiyangcui
da22abd25d 避免不必要的资源访问 2020-11-21 18:38:53 +01:00
haiyangcui
2dd91f78c9 牛牛资源已失效,删除 2020-11-21 18:38:51 +01:00
buvta
a8b0e7e6a8 fix:直播时上下切换频道时的bug 2020-11-21 23:20:17 +08:00
buvta
39edb9ce35 v2.6.6 2020-11-21 16:44:50 +08:00
buvta
3323a56671 fix:置顶图标联动 2020-11-21 16:22:06 +08:00
buvta
4dc88469e8 调整iptv操作列表头,两种显示模式 2020-11-21 15:55:08 +08:00
buvta
b04201f803 Play将win常量提取出来,避免重复获取 2020-11-21 15:52:51 +08:00
buvta
f34da7ff85 Play支持按拼音首字母搜索频道 2020-11-21 13:38:03 +08:00
buvta
b8f010c4f5 调整Play初始化 2020-11-21 13:20:39 +08:00
buvta
f876b863e7 直播换源时可隐藏频道 2020-11-21 13:20:29 +08:00
buvta
384ae10475 iptv移到设置界面,播放界面不加载视频时自动弹出频道列表 2020-11-20 22:50:57 +08:00
buvta
647c540f0b 直播时隐藏历史及播放速率按钮 2020-11-20 22:30:33 +08:00
buvta
87d01da241 精简模式停止时回到主窗口 2020-11-20 22:30:33 +08:00
buvta
641bdf00d3 保存音量 2020-11-20 22:30:33 +08:00
buvta
31510624c1 Update feature.md 2020-11-20 21:14:45 +08:00
buvta
d5c4e296c3 Update bug.md 2020-11-20 21:13:59 +08:00
buvta
f55065472d 调整IPTV批处理时的按钮标签 2020-11-20 15:05:39 +08:00
buvta
525da05c5f iptv导入json时bug修复 2020-11-20 15:00:00 +08:00
buvta
de8c51918f 再次调整 2020-11-20 13:59:18 +08:00
buvta
17229eb6b4 fix:初次切换到Play播放频道时channelList为空 2020-11-20 13:45:17 +08:00
buvta
d4530eef89 iptv导入json时合并而非覆盖 2020-11-20 12:52:13 +08:00
buvta
cb68da5a22 Play调整下代码 2020-11-20 12:06:44 +08:00
buvta
c21f6538f3 iptv改为以channelList为主,导入不再丢失配置
仅在生成channelList时使用iptv数据库,平时清空
导入导出格式为m3u时使用iptvList,json使用channelList
2020-11-20 12:05:20 +08:00
buvta
729dab765c 清理多余的mini窗口代码 2020-11-20 12:02:21 +08:00
buvta
8521de2844 Merge pull request #353 from Hunlongyu/mergeChannelDev
频道合并及播放页面的频道列表及精简模式
2020-11-19 21:31:35 +08:00
buvta
6ec7dffd59 窗口合二为一,更完美的精简模式,按Esc键退出 2020-11-19 18:13:44 +08:00
buvta
51fccb699a Play频道搜索样式调整 2020-11-19 18:13:44 +08:00
buvta
525d6af888 Play支持频道搜索 2020-11-19 18:13:44 +08:00
buvta
5a17d1b991 播放页面支持频道分组(外置) 2020-11-19 18:13:44 +08:00
buvta
edef20d171 fix:源管理清空时亦可添加 2020-11-19 18:13:44 +08:00
buvta
e912804fcc IPTV播放添加prefer 2020-11-19 18:13:44 +08:00
buvta
3165345839 Play做相应调整以使用channelList代替iptvList 2020-11-19 18:13:44 +08:00
buvta
7133c8982a 调整iptv拖拽仅在"不可展开"即批处理模式可用 2020-11-19 18:13:44 +08:00
buvta
26c1ba1e62 解决懒加载带来的bug 2020-11-19 18:13:44 +08:00
buvta
4e83e365a6 移除对iptvList.length的依赖 2020-11-19 18:13:44 +08:00
buvta
03775b091d 调整shift多选时获取首尾位置的方法 2020-11-19 18:13:43 +08:00
buvta
9147a8e1fb Revert "改动syncTableData以便删除可用"
This reverts commit 25d65866ae.
2020-11-19 18:13:43 +08:00
buvta
0d84e20326 支持手动合并 2020-11-19 18:13:43 +08:00
buvta
d421a5cfe4 bug修复 2020-11-19 18:13:43 +08:00
buvta
46fc5a0942 频道合并bug待修复 2020-11-19 18:13:43 +08:00
buvta
60aac3944e 进一步完善合并功能,注释部分及联动待实现 2020-11-19 18:13:43 +08:00
buvta
4683223a68 数据库调整,新增channelList,根据iptvList自动生成 2020-11-19 18:13:43 +08:00
buvta
86856397f6 IPTV实现自动合并懒加载,其它待调整以适应合并 2020-11-19 18:13:43 +08:00
haiyangcui
09e6af6f18 删除无用的extraResources文件夹 2020-11-16 14:30:15 +01:00
haiyangcui
18db5a1eb0 实体化HlsJsPlayer,而非更底层一点的Hls 2020-11-15 16:05:08 +01:00
haiyangcui
d116f08550 更新"更新推荐"提示语 2020-11-15 15:18:07 +01:00
haiyangcui
7441341658 删除记录,成功的话结果很明显,无需消息提醒 2020-11-15 09:48:10 +01:00
haiyangcui
9b71355803 Recommendations都是cuiocean一个人在维护,故将该资源转移到独立的repository里,避免继续污染本repo的commit信息 2020-11-15 09:30:41 +01:00
buvta
aba07ea20b 添加issue模版 2020-11-15 15:07:19 +08:00
buvta
790ea92180 issue模版 2020-11-15 14:57:54 +08:00
haiyangcui
1dc683e332 再次解决恢复窗口不继续播放视频的问题 2020-11-14 20:23:37 +01:00
haiyangcui
82df96e4d0 解决恢复窗口视频不恢复播放的问题 2020-11-14 20:07:46 +01:00
haiyangcui
bb1e31a270 默认video触发touchend事件后视频切换播放/暂停状态,通过closeVideoTouch关闭 2020-11-14 18:09:51 +01:00
haiyangcui
1d8d9ae72f 改变高亮颜色,以适应不同主题 2020-11-14 15:59:10 +01:00
haiyangcui
6dfe3bea95 统一viewMode为列表时的值为table 2020-11-14 15:59:03 +01:00
haiyangcui
6fcb6ad16c 搜索结果支持海报和列表两种模式 2020-11-14 15:58:52 +01:00
haiyangcui
c692ed2100 显示引入使用的依赖,否则编译有警告 2020-11-14 15:58:43 +01:00
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
56 changed files with 18314 additions and 15216 deletions

28
.github/ISSUE_TEMPLATE/bug.md vendored Normal file
View File

@@ -0,0 +1,28 @@
---
name: 报告Bug(请先查看常见问题及搜索issue列表中有无你要提的问题)
about: 创建报告以帮助我们改进
title: '(未回答的问题请删除)'
labels: bug
assignees: ''
---
**描述错误**
清楚简洁地说明错误是什么。
**重现**
重现行为的步骤
**预期行为**
对您期望发生的事情的简洁明了的描述。
**截图**
如果适用,请添加屏幕截图以帮助解释您的问题(直接把图片拖到编辑框即可添加图片)。
**环境:**
-操作系统及版本:[例如Windows 10 64位 18362.156]
-软件安装包及版本:[例如Windows 64位绿色版 1.0.0]
**其他内容**
在此处添加有关该问题的任何其他上下文。

17
.github/ISSUE_TEMPLATE/feature.md vendored Normal file
View File

@@ -0,0 +1,17 @@
---
name: 功能请求(请先查看常见问题及搜索issue列表中有无你要提的问题)
about: 为这个项目提出一个想法
title: 例如添加xxx功能、优化xxx功能未回答的问题请删除
labels: enhancement
assignees: ''
---
**描述您想要的解决方案**
简洁明了地描述您要发生的事情。
**描述您考虑过的替代方案**
对您考虑过的所有替代解决方案或功能的简洁明了的描述。
**其他内容**
在此处添加有关功能请求的任何其他上下文或屏幕截图(直接把图片拖到编辑框即可添加图片)。

19
.github/ISSUE_TEMPLATE/help.md vendored Normal file
View File

@@ -0,0 +1,19 @@
---
name: 需要帮助
about: "其它问题"
labels: help wanted
---
### 版本、安装方式、系统
1. 你在使用什么版本的
2. 你通过什么方式安装
3. 你所使用的操作系统
### 描述问题:
<!-- 在下方描述问题 -->

View File

@@ -29,6 +29,7 @@
### ✨特性
- 🍕 全平台支持. Windows, Mac, Linux
- 🍥 支持 IPTV, 卫视直播
- 🍔 视频源支持自定义, 支持导入, 导出
- 🍟 支持海报模式和列表模式浏览资源
- 🌭 播放历史, 自动跳转历史进度
@@ -84,9 +85,3 @@
| :----------------------------------------------------------: | :----------------------------------------------------------: |
| <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" /> |
| 💻 🎨 🐛 | 💻 🐛 |
### 🧧 赞助
[![LATOPAY](https://latopay.com/w/lt-bg-2062.png)](https://latopay.com/@Hunlongyu)

View File

@@ -1,571 +0,0 @@
#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

@@ -1,723 +0,0 @@
#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

@@ -1,816 +0,0 @@
#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,6 +1,6 @@
{
"name": "zy",
"version": "2.5.2-1",
"version": "2.6.8",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
@@ -17,50 +17,58 @@
},
"main": "background.js",
"dependencies": {
"axios": "^0.19.2",
"axios": "^0.21.0",
"cheerio": "^1.0.0-rc.3",
"child_process": "^1.0.2",
"core-js": "^3.6.5",
"core-js": "^3.8.0",
"cors": "^2.8.5",
"dexie": "^3.0.1",
"dexie": "^3.0.3",
"electron-localshortcut": "^3.2.1",
"element-ui": "^2.13.2",
"electron-proxy-agent": "^1.2.0",
"electron-updater": "^4.3.5",
"element-ui": "^2.14.1",
"express": "^4.17.1",
"fast-xml-parser": "^3.17.4",
"html2canvas": "^1.0.0-rc.5",
"html2canvas": "^1.0.0-rc.7",
"iptv-playlist-parser": "^0.5.0",
"m3u": "0.0.2",
"modern-normalize": "^0.6.0",
"m3u8-parser": "^4.5.0",
"memcached": "^2.2.2",
"modern-normalize": "^1.0.0",
"mousetrap": "^1.6.5",
"pinyin-match": "^1.1.1",
"qrcode.vue": "^1.7.0",
"randomstring": "^1.1.5",
"vue": "^2.6.11",
"session": "^0.1.0",
"sortablejs": "^1.12.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.0.7",
"vuedraggable": "^2.24.1",
"vuex": "^3.4.0",
"xgplayer": "^2.9.10",
"xgplayer-hls.js": "^2.2.3"
"vue-waterfall-plugin": "^1.1.0",
"vuedraggable": "^2.24.3",
"vuex": "^3.6.0",
"xgplayer": "^2.13.1",
"xgplayer-hls.js": "^2.2.5"
},
"devDependencies": {
"@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/cli-plugin-babel": "~4.5.9",
"@vue/cli-plugin-eslint": "~4.5.9",
"@vue/cli-plugin-vuex": "~4.5.9",
"@vue/cli-service": "~4.5.9",
"@vue/eslint-config-standard": "^5.1.2",
"babel-eslint": "^10.1.0",
"babel-plugin-component": "^1.1.1",
"electron": "^9.3.1",
"electron-devtools-installer": "^3.1.0",
"eslint": "^6.7.2",
"eslint-plugin-import": "^2.20.2",
"electron": "^11.0.3",
"electron-devtools-installer": "^3.1.1",
"eslint": "^7.14.0",
"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-vue": "^6.2.2",
"sass": "^1.26.5",
"sass-loader": "^8.0.2",
"vue-cli-plugin-electron-builder": "2.0.0-rc.4",
"vue-template-compiler": "^2.6.11"
"eslint-plugin-standard": "^4.1.0",
"eslint-plugin-vue": "^7.1.0",
"sass": "^1.29.0",
"sass-loader": "^10.1.0",
"vue-cli-plugin-electron-builder": "2.0.0-rc.5",
"vue-template-compiler": "^2.6.12"
}
}

View File

@@ -5,7 +5,7 @@
<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 %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>

View File

@@ -5,10 +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'" />
<IPTV v-show="view === 'IPTV'" />
<EditSites v-if="view === 'EditSites'"/>
<Recommendation v-show="view === 'Recommendation'" />
</div>
<transition name="slide">
<Detail v-if="detail.show"/>
@@ -16,68 +18,15 @@
<transition name="slide">
<Share v-if="share.show"/>
</transition>
<transition name="slide">
<EditSites v-if="editSites.show"/>
</transition>
</div>
</template>
<script>
import { setting } from './lib/dexie'
const { remote } = require('electron')
export default {
name: 'App',
data () {
return {
appTheme: 'theme-light',
winSizePosition: {
x: 0,
y: 0,
width: 0,
height: 0
}
}
},
created () {
// 窗口创建口,检查是否有窗口大小位置的记录,如果有的话,更新窗口位置及大小
setting.find().then(res => {
if (res.windowSizePosition) {
var win = remote.getCurrentWindow()
win.setBounds({
x: res.windowSizePosition.x,
y: res.windowSizePosition.y,
width: res.windowSizePosition.width,
height: res.windowSizePosition.height
})
}
})
var win = remote.getCurrentWindow()
this.winSizePosition = {
x: win.getPosition()[0],
y: win.getPosition()[1],
width: win.getSize()[0],
height: win.getSize()[1]
}
},
updated () {
// 本来想hook up到beforedestroy 但不工作
// 每当窗口更新时检查窗口大小及位置记录到setting数据库中
const win = remote.getCurrentWindow()
var newWinSizePosition = {
x: win.getPosition()[0],
y: win.getPosition()[1],
width: win.getSize()[0],
height: win.getSize()[1]
}
if (newWinSizePosition.x !== this.winSizePosition.x ||
newWinSizePosition.y !== this.winSizePosition.y ||
newWinSizePosition.width !== this.winSizePosition.width ||
newWinSizePosition.height !== this.winSizePosition.height) {
this.winSizePosition = newWinSizePosition
setting.find().then(res => {
res.windowSizePosition = newWinSizePosition
setting.update(res)
})
appTheme: 'theme-light'
}
},
computed: {
@@ -95,6 +44,9 @@ export default {
},
editSites () {
return this.$store.getters.getEditSites
},
recommendation () {
return this.$store.getters.recommendation
}
},
watch: {

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

View File

@@ -95,89 +95,10 @@
text-indent: 10px;
}
}
.zy-highlighted{
color: var(--highlight-color);
}
// table
.zy-table{
display: flex;
flex-direction: column;
height: 100%;
font-size: 15px;
.tHeader{
display: flex;
align-items: center;
justify-content: space-between;
height: 50px;
min-height: 50px;
width: 100%;
border-bottom: 1px solid;
.btn{
user-select: none;
margin-left: 15px;
margin-right: 15px;
cursor: pointer;
font-size: 14px;
}
}
.tBody{
flex: 1;
border-bottom: 1px solid;
overflow: auto;
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;
font-size: 13px;
height: 50px;
line-height: 50px;
overflow: hidden;
margin-right: 5px;
&.name{
flex: 1;
min-width: 100px;
white-space: nowrap;
margin-left: 10px;
}
&.type{
width: 10%;
}
&.time{
width: 10%;
}
&.last{
width: 10%;
}
&.site{
width: 10%;
}
&.note{
width: 10%;
}
&.operate{
.btn{
width: 40px;
}
}
}
}
}
}
}
// scroll
.zy-scroll{
&::-webkit-scrollbar{
width: 5px;
width: 10px;
height: 1px;
}
&::-webkit-scrollbar-thumb {
@@ -189,6 +110,260 @@
position: absolute;
}
}
// 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;
}
}
.disableExpand div.el-table__expand-icon{
display: none;
}
.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{
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);
}
.site{
position: absolute;
top: 0%;
left: 0%;
width: 100%;
background-color: #111111aa;
color:#2f90b9;
height: 30px;
line-height: 30px;
font-size: 14px;
font-weight: bolder;
text-align: center;
}
.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%;
@@ -233,4 +408,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,6 +1,6 @@
:root{
// general
--highlight-color: #38dd77;
--highlight-color:#1677b3;
// light
--l-c-0: #823aa0;
--l-c-1: #823aa011;
@@ -65,7 +65,7 @@
--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 1px 3px #ef528533, 0 1px 2px #ef528544;

View File

@@ -41,38 +41,6 @@
color: var(--d-fc-1);
}
}
.zy-checkbox{
color: var(--d-fc-1);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
}
.zy-table{
color: var(--d-fc-2);
.tHeader{
border-bottom-color: var(--d-c-3);
.btn{
&:hover{
color: var(--d-fc-3)
}
}
}
.tBody{
border-bottom-color: var(--d-c-3);
ul{
li{
border-bottom-color: var(--d-c-2);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--d-bsc-hover);
}
span{
&.btn:hover{
color: var(--d-fc-3)
}
}
}
}
}
}
.zy-scroll{
&:hover{
&::-webkit-scrollbar-thumb {
@@ -168,26 +136,16 @@
}
}
}
.film{
.body{
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
.show-img{
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);
}
}
}
}
}
.play{
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
.el-input{
input{
background-color: var(--d-bgc-1);
border: 1px solid var(--d-bgc-1);
color: var(--d-fc-2);
}
}
.title{
color: var(--d-fc-1);
.right {
@@ -256,6 +214,14 @@
}
}
}
.list-channels{
.btn{
color: var(--d-fc-1);
&:hover{
text-decoration:underline;
}
}
}
.list-history{
li{
.title{
@@ -284,10 +250,6 @@
}
}
}
.star{
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
}
.setting{
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
@@ -353,4 +315,114 @@
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

@@ -24,6 +24,8 @@
}
}
.vs-input{
color: var(--g-fc-1);
background-color: var(--g-bgc-1);
input{
color: var(--g-fc-1);
&::-webkit-input-placeholder{
@@ -37,38 +39,6 @@
background-color: var(--g-bgc-1);
input{
color: var(--g-fc-1);
background-color: var(--g-bgc-1);
}
}
.zy-checkbox{
color: var(--g-fc-1);
}
.zy-table{
color: var(--g-fc-2);
.tHeader{
border-bottom-color: var(--g-c-3);
.btn{
&:hover{
color: var(--g-fc-3)
}
}
}
.tBody{
border-bottom-color: var(--g-c-3);
ul{
li{
border-bottom-color: var(--g-c-2);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--g-bsc-hover);
}
span{
&.btn:hover{
color: var(--g-fc-3)
}
}
}
}
}
}
.zy-scroll{
@@ -166,26 +136,16 @@
}
}
}
.film{
.body{
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
.show-img{
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);
}
}
}
}
}
.play{
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
.el-input{
input{
background-color: var(--g-bgc-1);
border: 1px solid var(--g-bgc-1);
color: var(--g-fc-2);
}
}
.title{
color: var(--g-fc-1);
.right {
@@ -250,7 +210,15 @@
color: var(--g-fc-3);
}
&:hover{
background-color: var(--d-c-3);
background-color: var(--g-c-3);
}
}
}
.list-channels{
.btn{
color: var(--g-fc-1);
&:hover{
text-decoration:underline;
}
}
}
@@ -282,10 +250,6 @@
}
}
}
.star{
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
}
.setting{
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
@@ -351,4 +315,114 @@
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

@@ -24,6 +24,8 @@
}
}
.vs-input{
color: var(--l-fc-1);
background-color: var(--l-bgc-1);
input{
color: var(--l-fc-1);
&::-webkit-input-placeholder{
@@ -37,38 +39,6 @@
background-color: var(--l-bgc-1);
input{
color: var(--l-fc-1);
background-color: var(--l-bgc-1);
}
}
.zy-checkbox{
color: var(--l-fc-1);
}
.zy-table{
color: var(--l-fc-2);
.tHeader{
border-bottom-color: var(--l-c-3);
.btn{
&:hover{
color: var(--l-fc-3)
}
}
}
.tBody{
border-bottom-color: var(--l-c-3);
ul{
li{
border-bottom-color: var(--l-c-2);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--l-bsc-hover);
}
span{
&.btn:hover{
color: var(--l-fc-3)
}
}
}
}
}
}
.zy-scroll{
@@ -166,26 +136,16 @@
}
}
}
.film{
.body{
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
.show-img{
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);
}
}
}
}
}
.play{
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
.el-input{
input{
background-color: var(--l-bgc-1);
border: 1px solid var(--l-bgc-1);
color: var(--l-fc-2);
}
}
.title{
color: var(--l-fc-1);
.right {
@@ -250,7 +210,15 @@
color: var(--l-fc-3);
}
&:hover{
background-color: var(--d-c-3);
background-color: var(--l-c-3);
}
}
}
.list-channels{
.btn{
color: var(--l-fc-1);
&:hover{
text-decoration:underline;
}
}
}
@@ -282,10 +250,6 @@
}
}
}
.star{
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
}
.setting{
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
@@ -351,4 +315,114 @@
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

@@ -24,6 +24,8 @@
}
}
.vs-input{
color: var(--p-fc-1);
background-color: var(--p-bgc-1);
input{
color: var(--p-fc-1);
&::-webkit-input-placeholder{
@@ -39,37 +41,6 @@
color: var(--p-fc-1);
}
}
.zy-checkbox{
color: var(--p-fc-1);
}
.zy-table{
color: var(--p-fc-2);
.tHeader{
border-bottom-color: var(--p-c-3);
.btn{
&:hover{
color: var(--p-fc-3)
}
}
}
.tBody{
border-bottom-color: var(--p-c-3);
ul{
li{
border-bottom-color: var(--p-c-2);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--p-bsc-hover);
}
span{
&.btn:hover{
color: var(--p-fc-3)
}
}
}
}
}
}
.zy-scroll{
&:hover{
&::-webkit-scrollbar-thumb {
@@ -165,26 +136,16 @@
}
}
}
.film{
.body{
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
.show-img{
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);
}
}
}
}
}
.play{
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
.el-input{
input{
background-color: var(--p-bgc-1);
border: 1px solid var(--p-bgc-1);
color: var(--p-fc-2);
}
}
.title{
color: var(--p-fc-1);
.right {
@@ -249,7 +210,15 @@
color: var(--p-fc-3);
}
&:hover{
background-color: var(--d-c-3);
background-color: var(--p-c-3);
}
}
}
.list-channels{
.btn{
color: var(--p-fc-1);
&:hover{
text-decoration:underline;
}
}
}
@@ -281,10 +250,6 @@
}
}
}
.star{
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
}
.setting{
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
@@ -350,4 +315,114 @@
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,16 +1,16 @@
'use strict'
import './lib/site/server'
import { app, protocol, BrowserWindow, globalShortcut, ipcMain } from 'electron'
import { app, protocol, BrowserWindow, globalShortcut } 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'
// 允许跨域
app.commandLine.appendSwitch('disable-features', 'OutOfBlinkCors')
app.commandLine.appendSwitch('disable-features', 'OutOfBlinkCors') // 允许跨域
// app.commandLine.appendSwitch('--ignore-certificate-errors', 'true') // 忽略证书相关错误
let win
let mini
protocol.registerSchemesAsPrivileged([{ scheme: 'app', privileges: { secure: true, standard: true } }])
@@ -22,6 +22,7 @@ function createWindow () {
resizable: true,
webPreferences: {
webSecurity: false,
enableRemoteModule: true,
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION
}
})
@@ -34,43 +35,19 @@ function createWindow () {
win.loadURL('app://./index.html')
}
initUpdater(win)
win.on('closed', () => {
win = null
})
}
function createMini () {
mini = new BrowserWindow({
width: 550,
miniWidth: 860,
height: 340,
miniHeight: 180,
frame: false,
resizable: true,
webPreferences: {
webSecurity: false,
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION
}
})
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')
}
mini.on('closed', () => {
mini = null
})
}
if (process.platform === 'darwin') {
app.dock.show()
}
if (process.platform === 'Linux') {
app.disableHardwareAcceleration()
app.commandLine.appendSwitch('--no-sandbox') // linux 关闭沙盒模式
}
app.allowRendererProcessReuse = true
@@ -84,17 +61,6 @@ app.on('activate', () => {
}
})
ipcMain.on('mini', () => {
createMini()
win.hide()
})
ipcMain.on('win', () => {
mini.destroy()
win.show()
win.webContents.send('miniClosed')
})
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
app.quit()
@@ -118,9 +84,6 @@ if (!gotTheLock) {
if (win) {
win.isFocused() ? win.blur() : win.focus()
}
if (mini) {
mini.isFocused() ? mini.blur() : mini.focus()
}
})
})
}

View File

@@ -14,6 +14,13 @@
</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 === '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">播放</title>
@@ -26,13 +33,6 @@
<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 === '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 === '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>
@@ -69,29 +69,15 @@ export default {
set (val) {
this.SET_DETAIL(val)
}
},
editSites: {
get () {
return this.$store.getters.getEditSites
},
set (val) {
this.SET_EDITSITES(val)
}
}
},
methods: {
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_EDITSITES']),
...mapMutations(['SET_VIEW', 'SET_DETAIL']),
changeView (e) {
this.view = e
// ChangeView 的时候关闭Detail和EditSites页面
this.detail = {
show: false
}
if (this.editSites.show === true) {
this.editSites = {
show: false
}
}
}
}
}

View File

@@ -4,7 +4,14 @@
<div class="detail-header">
<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">
<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>
@@ -44,7 +51,8 @@
</select>
</span>
</div>
<div class="desc" v-show="info.des">{{info.des}}</div>
<div
class="desc" v-show="info.des">{{info.des}}</div>
<div class="m3u8">
<div class="box">
<span v-for="(i, j) in m3u8List" :key="j" @click="playEvent(j)">{{i | ftName}}</span>
@@ -72,7 +80,7 @@ export default {
info: {},
playOnline: false,
selectedOnlineSite: '哔嘀',
onlineSites: ['哔嘀', '素白白', '简影', '1080影视']
onlineSites: ['哔嘀', '素白白', '简影', '极品', '喜欢看', '1080影视']
}
},
filters: {
@@ -120,72 +128,57 @@ export default {
close () {
this.detail.show = false
},
m3u8Parse (e) {
const dd = e.dl.dd
const type = Object.prototype.toString.call(dd)
if (type === '[object Array]') {
for (const i of dd) {
if (i._flag.indexOf('m3u8') >= 0) {
this.m3u8List = i._t.split('#')
}
}
} else {
this.m3u8List = dd._t.split('#')
}
},
playEvent (n) {
async playEvent (n) {
if (!this.playOnline) {
history.find({ site: this.detail.key, ids: this.detail.info.id }).then(res => {
if (res) {
this.video = { key: res.site, info: { id: res.ids, name: res.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 } }
}
})
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 } }
}
this.video.detail = this.info
this.view = 'Play'
this.detail.show = false
} else {
history.find({ site: this.detail.key, ids: this.detail.info.id }).then(res => {
if (res) {
res.index = n
history.update(res.id, res)
} 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: ''
}
history.add(doc)
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
}
})
this.playVideoOnline(this.detail.info.name, n)
history.add(doc)
}
onlineVideo.playVideoOnline(this.selectedOnlineSite, this.detail.info.name, n)
}
},
starEvent () {
star.find({ key: this.detail.key, ids: this.info.id }).then(res => {
if (res) {
this.$message.info('该影片已被收藏')
} else {
const docs = {
key: this.detail.key,
ids: this.info.id,
name: this.info.name,
type: this.info.type,
year: this.info.year,
last: this.info.last,
note: this.info.note
}
star.add(docs).then(res => {
this.$message.success('收藏成功')
})
}
}).catch(() => {
this.$message.warning('收藏失败')
})
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
@@ -210,6 +203,9 @@ export default {
case '简影':
onlineVideo.playVideoOnSyrme(videoName, videoIndex)
break
case '极品':
onlineVideo.playVideoOnJpysvip(videoName, videoIndex)
break
default:
this.$message.console.error(`不支持该网站:${this.selectedOnlineSite}`)
}
@@ -250,61 +246,16 @@ export default {
}
},
doubanLinkEvent () {
const open = require('open')
const axios = require('axios')
const cheerio = require('cheerio')
const name = this.detail.info.name.trim()
// 豆瓣搜索链接
var doubanSearchLink = 'https://www.douban.com/search?q=' + name
var link = doubanSearchLink
axios.get(doubanSearchLink).then(res => {
const $ = cheerio.load(res.data)
// 比较第一和第二豆瓣搜索结果, 如果名字相符, 就打开该链接,否则打开搜索页面
var nameInDouban = $($('div.result')[0]).find('div>div>h3>a').first()
if (name.replace(/\s/g, '') === nameInDouban.text().replace(/\s/g, '')) {
link = nameInDouban.attr('href')
} else {
nameInDouban = $($('div.result')[1]).find('div>div>h3>a').first()
if (name.replace(/\s/g, '') === nameInDouban.text().replace(/\s/g, '')) {
link = nameInDouban.attr('href')
}
}
zy.doubanLink(name).then(link => {
const open = require('open')
open(link)
})
},
getDoubanRate () {
const axios = require('axios')
const cheerio = require('cheerio')
const name = this.detail.info.name.trim()
// 豆瓣搜索链接
var doubanSearchLink = 'https://www.douban.com/search?q=' + name
axios.get(doubanSearchLink).then(res => {
const $ = cheerio.load(res.data)
// 比较第一和第二给豆瓣搜索结果, 看名字是否相符
var link = ''
var nameInDouban = $($('div.result')[0]).find('div>div>h3>a').first()
if (name.replace(/\s/g, '') === nameInDouban.text().replace(/\s/g, '')) {
link = nameInDouban.attr('href')
} else {
nameInDouban = $($('div.result')[1]).find('div>div>h3>a').first()
if (name.replace(/\s/g, '') === nameInDouban.text().replace(/\s/g, '')) {
link = nameInDouban.attr('href')
}
}
// 如果找到链接,就打开该链接获取评分
if (link) {
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()) {
this.info.rate = rating.text()
} else {
this.info.rate = '暂无评分'
}
})
} else {
this.info.rate = '暂无评分'
}
zy.doubanRate(name).then(res => {
this.info.rate = res
})
},
getDetailInfo () {
@@ -313,7 +264,7 @@ export default {
if (res) {
this.info = res
this.$set(this.info, 'rate', '')
this.m3u8Parse(res)
this.m3u8List = res.m3u8List
this.getDoubanRate()
this.loading = false
}
@@ -326,7 +277,7 @@ export default {
}
</script>
<style lang="scss" scoped>
.detail{
.detail {
position: absolute;
left: 80px;
right: 20px;
@@ -334,28 +285,28 @@ export default {
width: calc(100% - 100px);
height: calc(100% - 40px);
z-index: 888;
.detail-content{
.detail-content {
height: calc(100% - 10px);
padding: 0 60px;
position: relative;
.detail-header{
.detail-header {
width: 100%;
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
.detail-title{
.detail-title {
font-size: 16px;
}
.detail-close{
.detail-close {
cursor: pointer;
}
}
}
.detail-body{
.detail-body {
height: calc(100% - 50px);
overflow-y: auto;
.info{
.info {
width: 100%;
padding: 10px;
display: flex;
@@ -366,47 +317,54 @@ export default {
border-radius: 2px;
margin-bottom: 10px;
height: auto;
.info-left{
.info-left {
width: 200px;
height: 100%;
img{
img {
width: 100%;
height: auto;
}
}
.info-right{
.info-right {
flex: 1;
margin-left: 20px;
.name{
.name {
font-size: 20px;
margin-bottom: 10px;
font-weight: bold;
}
.director, .actor, .type, .area, .lang, .year, .last, .note{
.director,
.actor,
.type,
.area,
.lang,
.year,
.last,
.note {
font-size: 14px;
line-height: 26px;
}
.rate{
.rate {
font-size: 16px;
line-height: 26px;
font-weight: bolder;
}
}
}
.operate{
.operate {
border: 1px solid;
padding: 10px;
width: 100%;
margin-bottom: 10px;
border-radius: 2px;
span{
span {
margin-right: 20px;
font-size: 14px;
cursor: pointer;
user-select: none;
}
}
.desc{
.desc {
border: 1px solid;
padding: 10px;
width: 100%;
@@ -415,15 +373,15 @@ export default {
font-size: 14px;
line-height: 20px;
}
.m3u8{
.m3u8 {
border: 1px solid;
padding: 10px 0 10px 10px;
width: 100%;
margin-bottom: 10px;
border-radius: 2px;
.box{
.box {
width: 100%;
span{
span {
display: inline-block;
font-size: 12px;
border: 1px solid;
@@ -435,7 +393,7 @@ export default {
}
}
}
.detail-mask{
.detail-mask {
position: absolute;
top: 50px;
left: 0;
@@ -457,28 +415,37 @@ export default {
@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;
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;
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;
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;
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;
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;
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;
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;
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,100 +1,163 @@
<template>
<div class="detail">
<div class="detail-content">
<div class="detail-header">
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="openAddSite">添加新源</div>
</div>
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="exportSites">导出</div>
</div>
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="importSites">导入</div>
</div>
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="resetSites">重置</div>
</div>
<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>
<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>
</div>
<div class="detail-body zy-scroll">
<div class="zy-table">
<div class="tBody zy-scroll">
<div class="addSites-box zy-scroll" v-show="showAddSite">
<ul>
<li >
<span class="name">源名称</span>
<span class="name">API接口</span>
<span class="name">DOWNLOAD接口</span>
<span class="operate">
<span class="btn"></span>
<span class="btn"></span>
</span>
</li>
<li>
<span class="name" style="display:inline-block;vertical-align:middle">
<input style="height: 30px" v-model="newSite.name">
</span>
<span class="name" style="display:inline-block;vertical-align:middle">
<input style="height: 30px" v-model="newSite.api">
</span>
<span class="name" style="display:inline-block;vertical-align:middle">
<input style="height: 30px" v-model="newSite.download" placeholder="可以为空">
</span>
<span class="operate">
<span class="btn" @click="addNewSite">添加</span>
<span class="btn" @click="closeAddSite">关闭</span>
</span>
</li>
<li ></li>
</ul>
</div>
<ul>
<draggable v-model="sites" @change="listUpdatedEvent">
<transition-group>
<li v-for="(i, j) in sites" :key="j">
<span class="name">{{i.name}}</span>
<span class="operate">
<span class="btn" @click.stop="removeEvent(i)">删除</span>
</span>
</li>
</transition-group>
</draggable>
</ul>
</div>
</div>
</div>
</el-dialog>
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import { sites, setting } from '../lib/dexie'
import draggable from 'vuedraggable'
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: [],
showAddSite: false,
newSite: {
dialogType: 'new',
dialogVisible: false,
siteInfo: {
key: '',
name: '',
api: '',
download: ''
}
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: ''
}
},
components: {
draggable
},
computed: {
setting: {
get () {
@@ -104,76 +167,179 @@ export default {
this.SET_SETTING(val)
}
},
editSites: {
get () {
return this.$store.getters.getEditSites
},
set (val) {
this.SET_EDITSITES(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', 'SET_EDITSITES']),
close () {
this.editSites.show = false
...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 = this.sites.findIndex(e => e.id === Math.min(this.selectionBegin, this.selectionEnd))
const end = this.sites.findIndex(e => e.id === Math.max(this.selectionBegin, this.selectionEnd))
const selections = this.sites.slice(start, end + 1)
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)
})
},
listUpdatedEvent () {
sites.clear().then(res1 => {
// 重新排序
var id = 1
this.sites.forEach(element => {
element.id = id
sites.add(element)
id += 1
})
})
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
}
},
openAddSite () {
this.showAddSite = true
},
closeAddSite () {
this.showAddSite = false
},
addNewSite () {
if (!this.newSite.name || !this.newSite.api) {
addOrEditSite () {
if (!this.siteInfo.name || !this.siteInfo.api) {
this.$message.error('名称和API接口不能为空。')
return
return false
}
if (!this.checkSiteKey()) {
return false
}
var randomstring = require('randomstring')
var doc = {
key: randomstring.generate(6),
id: this.sites[this.sites.length - 1].id + 1,
name: this.newSite.name,
api: this.newSite.api,
download: this.newSite.download
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.length ? this.sites[this.sites.length - 1].id + 1 : 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.newSite = {
this.siteInfo = {
key: '',
name: '',
api: '',
download: ''
download: '',
group: ''
}
this.$message.success('添加新源成功!')
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, 4)
const str = JSON.stringify(arr, null, 2)
const options = {
filters: [
{ name: 'JSON file', extensions: ['json'] },
@@ -191,78 +357,148 @@ export default {
})
},
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']
properties: ['openFile', 'multiSelections']
}
remote.dialog.showOpenDialog(options).then(result => {
if (!result.canceled) {
sites.clear()
result.filePaths.forEach(file => {
var str = fs.readFileSync(file)
const json = JSON.parse(str)
sites.bulkAdd(json).then(e => {
this.getSites()
this.d.site = json[0].key
setting.update(this.d).then(res => {
this.setting = this.d
})
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('导入成功')
}).catch(err => {
this.$message.error(err)
this.getSites()
})
}
})
},
resetSites () {
sites.clear()
sites.bulkAdd(defaultSites).then(e => {
this.getSites()
this.$message.success('重置源成功')
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.$refs.editSitesTable.tableData.length === this.sites.length) {
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>
<style lang="scss" scoped>
.detail{
position: absolute;
left: 80px;
right: 20px;
bottom: 0;
width: calc(100% - 100px);
height: calc(100% - 40px);
z-index: 888;
.detail-content{
height: calc(100% - 10px);
padding: 0 60px;
position: relative;
.detail-header{
width: 100%;
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
.detail-title{
font-size: 16px;
}
.detail-close{
cursor: pointer;
}
}
}
.detail-body{
height: calc(100% - 50px);
overflow-y: auto;
}
}
</style>

View File

@@ -1,43 +1,72 @@
<template>
<div class="film">
<div class="header">
<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 class="zy-scroll" style="max-height: 600px;">
<li :class="site.key === i.key ? 'active' : ''" v-for="i in sites" :key="i.key" @click="siteClick(i)">{{ i.name }}</li>
</ul>
</div>
</div>
<div class="zy-select" @mouseleave="show.classList = false" v-show="show.class">
<div class="vs-placeholder" @click="show.classList = true">{{type.name}}</div>
<div class="vs-options" v-show="show.classList">
<ul class="zy-scroll" style="max-height: 600px;">
<li :class="type.tid === i.tid ? 'active' : ''" v-for="i in classList" :key="i.tid" @click="classClick(i)">{{ i.name }}</li>
</ul>
</div>
</div>
<div class="zy-select" @mouseleave="show.search = false">
<div class="vs-input" @click="show.search = true"><input v-model.trim="searchTxt" type="text" placeholder="搜索" @keyup.enter="searchEvent(searchTxt)"></div>
<div class="vs-options" v-show="show.search">
<ul class="zy-scroll" style="max-height: 600px">
<li v-for="(i, j) in searchList" :key="j" @click="searchEvent(i.keywords)">{{i.keywords}}</li>
<li v-show="searchList.length >= 1" @click="clearSearch">清空历史记录</li>
</ul>
</div>
</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-switch v-model="searchViewMode" active-text="海报" active-value="picture" inactive-text="列表" inactive-value="table" @change="updateSearchViewMode"
v-if="show.find"></el-switch>
<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="body zy-scroll" infinite-wrapper>
<div class="body-box" v-show="!show.find">
<div class="show-img" v-if="setting.view === 'picture'">
<Waterfall ref="waterfall" :list="list" :gutter="20" :width="240"
:breakpoints="{ 1200: { rowPerView: 4 } }"
animationEffect="fadeInUp"
<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.waterfall.refresh()" @click="detailEvent(site, props.data)">
<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>
@@ -48,6 +77,7 @@
</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>
@@ -56,59 +86,193 @@
</template>
</Waterfall>
<infinite-loading force-use-infinite-wrapper :identifier="infiniteId" @infinite="infiniteHandler"></infinite-loading>
</div>
<div class="show-table" v-if="setting.view === 'table'">
<div class="zy-table">
<div class="tBody">
<ul>
<li v-for="(i, j) in list" :key="j" @click="detailEvent(site, i)" v-show="!setting.excludeR18Films || !containsR18Keywords(i.type)">
<span class="name">{{i.name}}</span>
<span class="type">{{i.type}}</span>
<span class="time">{{i.year}}</span>
<span class="time">{{i.note}}</span>
<span class="last">{{i.last}}</span>
<span class="operate">
<span class="btn" @click.stop="playEvent(site, i)">播放</span>
<span class="btn" @click.stop="starEvent(site, i)">收藏</span>
<span class="btn" @click.stop="shareEvent(site, i)">分享</span>
<span class="btn" @click.stop="downloadEvent(site, i)">下载</span>
</span>
</li>
</ul>
<infinite-loading force-use-infinite-wrapper="tBody" :identifier="infiniteId" @infinite="infiniteHandler"></infinite-loading>
</div>
</div>
</div>
</div>
<div class="body-box" v-show="show.find">
<div class="show-table">
<div class="zy-table">
<div class="tBody zy-scroll">
<ul>
<li v-for="(i, j) in searchContents" :key="j" @click="detailEvent(i.site, i)">
<span class="name">{{i.name}}</span>
<span class="type">{{i.type}}</span>
<span class="last">{{i.last}}</span>
<span class="site">{{i.site.name}}</span>
<span class="note">{{i.note}}</span>
<span class="operate">
<span class="btn" @click.stop="playEvent(i.site, i)">播放</span>
<span class="btn" @click.stop="starEvent(i.site, i)">收藏</span>
<span class="btn" @click.stop="shareEvent(i.site, i)">分享</span>
<span class="btn" @click.stop="downloadEvent(i.site, i)">下载</span>
</span>
</li>
</ul>
</div>
</div>
</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="searchViewMode=== 'table' && 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 class="show-picture" v-show="searchViewMode === 'picture' && show.find">
<Waterfall ref="filmSearchWaterfall" :list="searchContents.filter(res => !setting.excludeR18Films || (res.type !== undefined && !containsR18Keywords(res.type)))" :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">
<div class="site">
<span>{{props.data.site.name}}</span>
</div>
<img style="width: 100%" :src="props.data.pic" alt="" @load="$refs.filmSearchWaterfall.refresh()" @click="detailEvent(props.data.site, props.data)">
<div class="operate">
<div class="operate-wrap">
<span class="o-play" @click="playEvent(props.data.site, props.data)">播放</span>
<span class="o-star" @click="starEvent(props.data.site, props.data)">收藏</span>
<span class="o-share" @click="shareEvent(props.data.site, props.data)">分享</span>
</div>
</div>
</div>
<div class="name" @click="detailEvent(props.data.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>
</div>
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import { star, history, search, sites } from '../lib/dexie'
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'
@@ -122,23 +286,28 @@ export default {
site: false,
class: false,
classList: false,
search: false,
img: true,
table: false,
find: false
},
sites: [],
site: {},
classList: [],
type: {},
selectedClassName: '最新',
selectedSiteName: '',
pagecount: 0,
list: [],
statusText: ' ',
infiniteId: +new Date(),
searchID: 0,
searchList: [],
searchTxt: '',
searchContents: [],
currentColumn: '',
searchGroup: '',
searchGroups: [],
// 福利片关键词
r18KeyWords: ['伦理', '倫理', '福利', '激情', '理论', '写真', '情色', '美女', '街拍', '赤足', '性感', '里番']
r18KeyWords: ['伦理', '论理', '倫理', '福利', '激情', '理论', '写真', '情色', '美女', '街拍', '赤足', '性感', '里番'],
searchViewMode: 'picture'
}
},
components: {
@@ -178,8 +347,22 @@ export default {
this.SET_SHARE(val)
}
},
setting () {
return this.$store.getters.getSetting
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: {
@@ -187,36 +370,69 @@ export default {
this.changeView()
},
searchTxt () {
this.searchChangeEvent()
if (this.searchTxt === '清除历史记录...') {
this.clearSearchHistory()
this.searchTxt = ''
this.searchChangeEvent()
}
},
'$store.state.editSites.sites': function () {
this.getAllsites()
filterSettings () {
this.siteClick(this.site.name)
}
},
methods: {
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
siteClick (e) {
this.list = []
this.site = e
this.show.site = false
this.show.class = false
if (this.searchTxt.length > 0) {
this.searchSingleSiteEvent(this.site, this.searchTxt)
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE', 'SET_SETTING']),
updateSearchViewMode () {
setting.find().then(res => {
res.searchViewMode = this.searchViewMode
setting.update(res)
})
},
sortByLocaleCompare (a, b) {
return a.localeCompare(b, 'zh')
},
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.searchTxt = ''
this.show.find = false
this.classList = []
this.type = {}
this.getClass().then(res => {
if (res) {
this.show.class = true
this.infiniteId += 1
}
this.classClick(this.classList[0].name)
})
}
},
classClick (e) {
classClick (className) {
this.show.classList = false
this.list = []
this.type = e
this.type = this.classList.find(x => x.name === className)
this.getPage().then(res => {
if (res) {
this.infiniteId += 1
@@ -276,8 +492,10 @@ export default {
const key = this.site.key
const type = this.type.tid
const page = this.pagecount
if (page < 1) {
this.statusText = ' '
if (key === undefined || page < 1 || type === undefined) { // OK资源前几类硬是去不掉
$state.complete()
this.statusText = '暂无数据'
return false
}
zy.list(key, page, type).then(res => {
@@ -295,8 +513,13 @@ export default {
this.list.push(res)
}
$state.loaded()
// 数据更新后,刷新页面
if (this.$refs.filmWaterfall) {
this.$refs.filmWaterfall.refresh()
}
} else {
$state.complete()
this.statusText = '暂无数据'
}
})
},
@@ -308,37 +531,36 @@ export default {
info: e
}
},
playEvent (site, e) {
history.find({ site: site.key, ids: e.id }).then(res => {
if (res) {
this.video = { key: res.site, info: { id: res.ids, name: res.name, index: res.index, site: site } }
} else {
this.video = { key: site.key, info: { id: e.id, name: e.name, index: 0, site: site } }
}
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'
},
starEvent (site, e) {
star.find({ key: site.key, ids: e.id }).then(res => {
if (res) {
this.$message.info('已存在')
} else {
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,
type: e.type,
year: e.year,
last: e.last,
note: e.note
detail: detailRes
}
star.add(docs).then(res => {
this.$message.success('收藏成功')
})
}
}).catch(() => {
this.$message.warning('收藏失败')
})
})
}
},
shareEvent (site, e) {
this.share = {
@@ -347,10 +569,10 @@ export default {
info: e
}
},
downloadEvent (site, e) {
zy.download(site.key, e.id).then(res => {
if (res && res.length > 0 && res.dl && res.dl.dd) {
const text = res.dl.dd._t
downloadEvent (site, row) {
zy.download(site.key, row.id).then(res => {
if (res && res.length > 0) {
const text = res.m3u8List
if (text) {
const list = text.split('#')
let downloadUrl = res.name + '\n'
@@ -365,7 +587,7 @@ export default {
}
} else {
let m3u8List = []
const dd = res.dl.dd
const dd = row.dl.dd
const type = Object.prototype.toString.call(dd)
if (type === '[object Array]') {
for (const i of dd) {
@@ -376,7 +598,7 @@ export default {
} else {
m3u8List = dd._t.split('#')
}
let downloadUrl = e.name + '\n'
let downloadUrl = row.name + '\n'
for (const i of m3u8List) {
const url = encodeURI(i.split('$')[1])
downloadUrl += (url + '\n')
@@ -388,74 +610,103 @@ export default {
},
changeView () {
if (this.view === 'Film') {
if (this.show.img) {
this.$refs.waterfall.refresh()
}
this.getPage().then(() => {
this.infiniteId += 1
if (this.show.img || this.show.table) {
this.getAllSites()
if (this.setting.view === 'picture') {
if (this.$refs.filmWaterfall) {
this.$refs.filmWaterfall.refresh()
}
})
}
}
},
getAllSearch () {
search.all().then(res => {
this.searchList = res.reverse()
})
querySearch (queryString, cb) {
var searchList = this.searchList.slice(0, -1)
var results = queryString ? searchList.filter(this.createFilter(queryString)) : this.searchList
// 调用 callback 返回建议列表的数据
cb(results)
},
searchAllSitesEvent (sites, wd) {
this.searchTxt = wd
this.searchContents = []
this.pagecount = 0
this.show.search = false
this.show.find = true
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.getAllSearch()
this.getSearchHistory()
})
sites.forEach(site => {
}
},
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 wd = this.searchTxt
if (this.setting.searchGroup !== this.searchGroup) {
this.setting.searchGroup = this.searchGroup
setting.update(this.setting)
}
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 => {
element.site = site
this.searchContents.push(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]') {
res.site = site
this.searchContents.push(res)
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 = '暂无数据'
})
}
})
})
} else {
this.show.find = false
this.getClass().then(res => {
if (res) {
this.infiniteId += 1
}
})
}
},
searchEvent (wd) {
if (this.setting.searchAllSites) {
this.searchAllSitesEvent(this.sites, wd)
} else {
this.searchSingleSiteEvent(this.site, wd)
}
},
searchSingleSiteEvent (site, wd) {
var sites = []
sites.push(this.site)
this.searchAllSitesEvent(sites, wd)
},
clearSearch () {
search.clear().then(res => {
this.getAllSearch()
})
searchAndRecord () {
this.addSearchRecord()
this.searchEvent()
},
searchChangeEvent () {
if (this.searchTxt.length >= 1) {
@@ -464,123 +715,59 @@ export default {
this.show.class = true
this.searchContents = []
this.show.find = false
if (this.show.img) {
this.$refs.waterfall.refresh()
if (this.setting.view === 'picture' && this.$refs.filmWaterfall) {
this.$refs.filmWaterfall.refresh()
} else {
this.getClass().then(res => {
if (res) {
this.infiniteId += 1
}
})
}
}
},
getAllsites () {
getAllSites () {
sites.all().then(res => {
this.sites = res
this.site = this.sites[0]
this.siteClick(this.site)
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
}
}
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 })
})
},
getSearchViewMode () {
setting.find().then(res => {
this.searchViewMode = res.searchViewMode === undefined ? 'picture' : res.searchViewMode
})
}
},
created () {
this.getAllsites()
this.getAllSearch()
this.getAllSites()
this.getSearchHistory()
this.getSearchViewMode()
},
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;
.header{
height: 30px;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
z-index: 10;
}
.body{
margin-top: 20px;
flex: 1;
width: 100%;
border-radius: 0 0 5px 5px;
overflow-y: scroll;
&::-webkit-scrollbar{
width: 5px;
height: 1px;
}
&::-webkit-scrollbar-thumb {
border-radius: 10px;
position: absolute;
}
&::-webkit-scrollbar-track {
border-radius: 10px;
position: absolute;
}
.body-box{
height: 100%;
width: 100%;
}
.show-img{
height: 100%;
width: 100%;
padding: 10px;
.card{
border-radius: 6px;
overflow: hidden;
.img{
position: relative;
min-height: 40px;
img{
width: 100%;
height: auto;
cursor: pointer;
}
.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;
cursor: pointer;
}
.info{
display: flex;
justify-content: space-between;
font-size: 12px;
padding: 10px;
}
&:hover{
.operate{
display: block;
}
}
}
}
}
}
</style>

View File

@@ -1,7 +1,7 @@
<template>
<div class="frame">
<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>
<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="appState.windowIsOnTop ? '#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>
@@ -18,10 +18,14 @@
const { remote } = require('electron')
export default {
name: 'frame',
data () {
const win = remote.getCurrentWindow()
return {
isAlwaysOnTop: win.isAlwaysOnTop()
computed: {
appState: {
get () {
return this.$store.getters.getAppState
},
set (val) {
this.SET_APPSTATE(val)
}
}
},
methods: {
@@ -37,8 +41,8 @@ export default {
win.destroy()
}
if (e === 'top') {
this.isAlwaysOnTop = !this.isAlwaysOnTop
win.setAlwaysOnTop(this.isAlwaysOnTop)
this.appState.windowIsOnTop = !this.appState.windowIsOnTop
win.setAlwaysOnTop(this.appState.windowIsOnTop)
}
}
}

View File

@@ -1,55 +1,123 @@
<template>
<div class="history">
<div class="body zy-scroll">
<div class="zy-table">
<div class="tHeader">
<span class="btn"></span>
<span class="btn" @click="clearAllHistory">清空</span>
</div>
<div class="tBody zy-scroll">
<ul>
<li v-show="this.history.length === 0">无数据</li>
<li v-show="this.history.length > 0">
<span class="name">名字</span>
<span class="site">片源</span>
<span class="note">观看至</span>
<span class="operate">
<span class="btn"></span>
<span class="btn"></span>
<span class="btn"></span>
<span class="btn"></span>
<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="table" @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 === 'table'">
<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>
</li>
<li v-for="(i, j) in history" :key="j" @click="historyItemEvent(i)">
<span class="name" @click.stop="detailEvent(i)">{{i.name}}</span>
<span class="site">{{getSiteName(i.site)}}</span>
<span class="note">{{i.index+1}}</span>
<span class="operate">
<span class="btn" @click.stop="playEvent(i)">播放</span>
<span class="btn" @click.stop="shareEvent(i)">分享</span>
<span class="btn" @click.stop="downloadEvent(i)">下载</span>
<span class="btn" @click.stop="removeHistoryItem(i)">删除</span>
</span>
</li>
</ul>
</div>
</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>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import { history, sites } from '../lib/dexie'
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: history,
sites: []
history: [],
sites: [],
viewMode: setting.historyViewMode
}
},
components: {
Waterfall
},
computed: {
view: {
get () {
@@ -88,10 +156,16 @@ export default {
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,
@@ -102,13 +176,15 @@ export default {
}
}
},
playEvent (e) {
history.find({ site: e.site, ids: e.ids }).then(res => {
if (res) {
this.video = { key: res.site, info: { id: res.ids, name: res.name, index: res.index } }
} else {
this.video = { key: e.site, info: { id: e.ids, name: e.name, index: 0 } }
}
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'
},
@@ -121,35 +197,18 @@ export default {
},
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('没有查询到下载链接.')
if (res && res.m3u8List) {
const list = res.m3u8List.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 {
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]
const list = [...res.m3u8List]
let downloadUrl = ''
for (const i of list) {
const url = encodeURI(i.split('$')[1])
@@ -161,6 +220,44 @@ export default {
}
})
},
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 = []
@@ -182,44 +279,61 @@ export default {
return site.name
}
},
historyItemEvent (e) {
this.video = {
key: e.site,
info: {
id: e.ids,
name: e.name,
type: e.type,
year: e.year,
index: e.index,
time: e.time
}
}
},
removeHistoryItem (e) {
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>
<style lang="scss" scoped>
.history{
position: relative;
height: calc(100% - 40px);
width: 100%;
display: flex;
justify-content: center;
align-items: center;
border-radius: 5px;
.body{
width: 100%;
height: 100%;
}
}
</style>

View File

@@ -1,80 +1,139 @@
<template>
<div class="detail">
<div class="detail-content">
<div class="detail-header">
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="exportSites">导出</div>
</div>
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="importSites">导入</div>
</div>
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="removeAllSites">清空</div>
</div>
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="resetSites">重置</div>
</div>
<div style="width: 200px; height: 30px;">
</div>
</div>
<div class="detail-header">
<div>
<div class="vs-placeholder vs-noAfter" @click="exportSites">总频道数:{{iptvList.length}}</div>
</div>
<div class="zy-select" @mouseleave="show.search = false">
<div class="vs-input" @click="show.search = true"><input v-model.trim="searchTxt" type="text" placeholder="搜索" @keyup.enter="searchEvent(searchTxt)"></div>
<div class="vs-options" v-show="show.search">
<ul class="zy-scroll" style="max-height: 600px">
<li v-for="(i, j) in searchList" :key="j" @click="searchEvent(i.keywords)">{{i.keywords}}</li>
<li v-show="searchList.length >= 1" @click="clearSearch">清空历史记录</li>
</ul>
</div>
</div>
</div>
<div class="detail-body zy-scroll">
<div class="zy-table">
<div class="tBody zy-scroll">
<ul>
<draggable v-model="iptvList" @change="listUpdatedEvent">
<transition-group>
<li v-for="(i, j) in iptvList" :key="j" @click.stop="playEvent(i)" v-show="containsearchTxt(i)">
<span class="name">{{i.name}}</span>
<span class="operate">
<span class="btn" @click.stop="playEvent(i)">播放</span>
<span class="btn" @click.stop="removeEvent(i)">删除</span>
</span>
</li>
</transition-group>
</draggable>
</ul>
</div>
</div>
<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="inputContent"></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 type="primary" icon="el-icon-film" @click.stop="mergeChannel">{{ this.multipleSelection.length === 1 ? '频道重命名' : '频道合并' }}</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"
lazy
:load="(row, treeNode, resolve) => resolve(row.channels)"
:tree-props="{hasChildren: 'hasChildren'}"
@expand-change="expandChange"
@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"
:class-name="enableBatchEdit ? 'disableExpand' : ''"
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>{{ enableBatchEdit ? `频道总数:${channelList.length}` : `资源总数:${iptvList.length}` }}</span>
</template>
<template slot-scope="scope">
<el-button @click.stop="moveToTopEvent(scope.row)" type="text" v-if="scope.row.channels">置顶</el-button>
<el-button @click.stop="playEvent(scope.row)" type="text">播放</el-button>
<!-- 检测时先强制批量检测一遍,如果不强制直接单个检测时第一次不会显示“检测中”-->
<el-button size="mini" v-if="iptvList.every(channel => channel.status)" v-show="!checkAllChannelsLoading" @click.stop="checkChannel(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 draggable from 'vuedraggable'
import { iptv as defaultSites } from '../lib/dexie/initData'
import { iptv, channelList } 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: [],
channelList: [],
searchTxt: '',
searchList: [],
show: {
search: false
}
enableBatchEdit: false,
inputContent: '',
batchIsActive: true,
shiftDown: false,
selectionBegin: '',
selectionEnd: '',
multipleSelection: [],
expandedRows: [],
checkAllChannelsLoading: false,
checkProgress: 0,
stopFlag: false,
sortableTable: ''
}
},
components: {
draggable
},
computed: {
view: {
get () {
@@ -94,19 +153,122 @@ export default {
set (val) {
this.SET_VIDEO(val)
}
},
filteredTableData () {
if (this.searchTxt) {
return this.channelList.filter(x => x.name.toLowerCase().includes(this.searchTxt.toLowerCase()))
} else {
return this.channelList
}
},
getFilters () {
const groups = [...new Set(this.channelList.map(iptv => iptv.group))]
var filters = []
groups.forEach(g => {
var doc = {
text: g,
value: g
}
filters.push(doc)
})
return filters
}
},
watch: {
view () {
this.getAllSites()
if (this.view === 'IPTV' && !this.checkAllChannelsLoading) {
this.getChannelList()
}
},
searchTxt () {
enableBatchEdit () {
if (this.checkAllChannelsLoading) {
this.$message.info('正在检测, 请勿操作.')
this.enableBatchEdit = false
return
}
if (this.enableBatchEdit) {
this.$nextTick(() => {
this.expandedRows.forEach(e => this.$refs.iptvTable.toggleRowExpansion(e, false))
})
this.rowDrop()
} else {
this.sortableTable.destroy()
}
}
},
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 = this.channelList.findIndex(e => e.id === Math.min(this.selectionBegin, this.selectionEnd))
const end = this.channelList.findIndex(e => e.id === Math.max(this.selectionBegin, this.selectionEnd))
const selections = this.channelList.slice(start, end + 1) // 多选时强制不让展开
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 = ''
}
},
expandChange (row, expanded) {
const index = this.expandedRows.indexOf(row)
if (expanded && index === -1) {
this.expandedRows.push(row)
} else if (!expanded && index !== -1) {
this.expandedRows.splice(index, 1)
}
},
handleSelectionChange (rows) {
this.multipleSelection = rows
},
handleSortChange (column, prop, order) {
if (this.checkAllChannelsLoading) {
this.$message.info('正在检测, 请勿操作.')
return
}
this.updateDatabase()
},
saveBatchEdit () {
this.multipleSelection.forEach(ele => {
if (this.inputContent) {
ele.group = this.inputContent
}
ele.isActive = this.batchIsActive
})
this.updateDatabase()
},
mergeChannel () {
if (this.inputContent && this.multipleSelection.length) {
var channels = []
const id = this.multipleSelection[0].id
this.multipleSelection.forEach(ele => {
channels = channels.concat(ele.channels)
channels.forEach(e => { e.channelID = id })
channelList.remove(ele.id)
})
const mergeChannel = { id: id, name: this.inputContent, isActive: channels.some(c => c.isActive), group: this.determineGroup(this.inputContent), hasChildren: channels.length > 1, channels: channels }
channelList.add(mergeChannel)
this.getChannelList()
this.updateDatabase()
}
},
playEvent (e) {
this.video = { iptv: { name: e.name, url: e.url } }
if (e.url) {
this.video = { iptv: e }
} else {
const prefer = e.prefer ? e.channels.find(c => c.id === e.prefer) : e.channels.filter(c => c.isActive)[0]
if (!prefer) return
this.video = { iptv: prefer }
}
this.view = 'Play'
},
containsearchTxt (i) {
@@ -116,25 +278,30 @@ export default {
return true
}
},
removeEvent (e) {
iptv.remove(e.id).then(res => {
this.getAllSites()
}).catch(err => {
removeEvent (row) {
if (this.checkAllChannelsLoading) {
this.$message.info('正在检测, 请勿操作.')
return false
}
try {
if (row.url) { // tree树形控件节点一旦展开就不再重新加载节点数据
const ele = this.channelList.find(e => e.id === row.channelID)
ele.channels.splice(ele.channels.findIndex(e => e.id === row.id), 1)
channelList.remove(row.channelID)
if (ele.channels.length) {
if (ele.channels.length === 1) ele.hasChildren = false
channelList.add(ele)
this.$set(this.$refs.iptvTable.store.states.lazyTreeNodeMap, ele.id, ele.channels)
}
} else {
channelList.remove(row.id)
}
this.getChannelList()
} catch (err) {
this.$message.warning('删除频道失败, 错误信息: ' + err)
})
}
},
listUpdatedEvent () {
iptv.clear().then(res1 => {
// 重新排序
var id = 1
this.iptvList.forEach(element => {
element.id = id
iptv.add(element)
id += 1
})
})
},
exportSites () {
exportChannels () { // 导出导入m3u为iptvListjson为channelList
const options = {
filters: [
{ name: 'm3u file', extensions: ['m3u'] },
@@ -151,8 +318,8 @@ export default {
fs.writeFileSync(result.filePath, writer.toString())
this.$message.success('已保存成功')
} else {
const arr = [...this.iptvList]
const str = JSON.stringify(arr, null, 4)
const arr = [...this.channelList] // 要保存channelList必须选json
const str = JSON.stringify(arr, null, 2)
fs.writeFileSync(result.filePath, str)
this.$message.success('已保存成功')
}
@@ -161,116 +328,310 @@ export default {
this.$message.error(err)
})
},
importSites () {
importChannels () {
if (this.checkAllChannelsLoading) {
this.$message.info('正在检测, 请勿操作.')
return false
}
const options = {
filters: [
{ name: 'm3u file', extensions: ['m3u', 'm3u8'] }
{ 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
result.filePaths.forEach(file => {
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.includes('.m3u8')) {
var doc = {
name: ele.name,
url: ele.url
if (file.endsWith('m3u') || file.endsWith('m3u8')) {
const docs = []
const URL = require('url')
let id = this.channelList.length ? this.channelList.slice(-1)[0].id + 1 : 1
const parser = require('iptv-playlist-parser')
const playlist = fs.readFileSync(file, { encoding: 'utf-8' })
const result = parser.parse(playlist)
result.items.forEach(ele => {
const urls = ele.url.split('#').filter(e => e.startsWith('http')) // 网址带#时自动分割
urls.forEach(url => {
if (ele.name && url && new URL.URL(url).pathname.endsWith('.m3u8')) { // 网址可能带参数
var doc = {
id: id,
name: ele.name,
url: url,
isActive: true
}
id += 1
docs.push(doc)
}
})
})
// 获取url不重复的列表
const uniqueList = [...new Map(docs.map(item => [item.url, item])).values()]
iptv.clear().then(res => {
iptv.bulkAdd(uniqueList).then(e => { // 支持导入同名频道,群里反馈
this.updateChannelList()
})
})
} else {
// Import Json file
const importedList = JSON.parse(fs.readFileSync(file))
importedList.forEach(ele => {
const commonEle = this.channelList.find(e => e.name === ele.name)
if (commonEle) {
const urls = commonEle.channels.map(c => c.url)
const channels = ele.channels.filter(e => !urls.includes(e.url))
commonEle.channels = commonEle.channels.concat(channels)
} else {
ele.id = this.channelList.length ? this.channelList.slice(-1)[0].id + 1 : 1
this.channelList.push(ele)
}
docs.push(doc)
}
})
})
// 获取url不重复的列表
const uniqueList = [...new Map(docs.map(item => [item.url, item])).values()]
iptv.clear().then(res => {
iptv.bulkAdd(uniqueList).then(e => {
this.getAllSites()
this.$message.success('导入成功')
})
})
this.updateDatabase()
}
})
this.$message.success('导入成功')
}
})
},
resetSites () {
iptv.clear()
iptv.bulkAdd(defaultSites).then(e => {
this.getAllSites()
})
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 '其他'
}
},
removeAllSites () {
iptv.clear().then(res => {
this.getAllSites()
})
resetChannelsEvent () {
this.stopFlag = true
if (this.checkAllChannelsLoading) {
this.$message.info('部分检测还未完全终止, 请稍等...')
return
}
this.channelList = []
this.iptvList = []
iptv.clear().then(iptv.bulkAdd(defaultChannels).then(this.updateChannelList()))
},
getAllSites () {
removeSelectedChannels () {
this.multipleSelection.forEach(e => channelList.remove(e.id))
this.$refs.iptvTable.clearFilter()
this.getChannelList()
this.updateDatabase()
this.enableBatchEdit = false
},
updateChannelList () {
iptv.all().then(res => {
this.iptvList = res
})
},
getAllSearch () {
iptvSearch.all().then(res => {
this.searchList = res.reverse()
})
},
clearSearch () {
iptvSearch.clear().then(res => {
this.getAllSearch()
})
},
searchEvent (wd) {
this.searchTxt = wd
this.show.search = false
if (wd) {
iptvSearch.find({ keywords: wd }).then(res => {
if (!res) {
iptvSearch.add({ keywords: wd })
res = res.filter(o => !this.iptvList.find(e => o.url === e.url))
const resClone = JSON.parse(JSON.stringify(res))
const uniqueChannelName = {}
for (var i = 0; i < resClone.length; i++) {
var channelName = resClone[i].name.trim().replace(/[- ]?(1080p|蓝光|超清|高清|标清|hd|cq|4k)(\d{1,2})?$/i, '')
if (channelName.match(/cctv/i)) channelName = channelName.replace('-', '')
if (Object.keys(uniqueChannelName).some(name => channelName.match(new RegExp(`${name}(1080p|4k|(?!\\d))`, 'i')))) continue // 避免重复
const matchRule = new RegExp(`${channelName}(1080p|4k|(?!\\d))`, 'i')
for (var j = i; j < resClone.length; j++) {
if (resClone[j].name.match(/cctv/i)) {
resClone[j].name = resClone[j].name.replace('-', '')
}
if (matchRule.test(resClone[j].name)) {
if (uniqueChannelName[channelName]) {
!uniqueChannelName[channelName].includes(res[j]) && uniqueChannelName[channelName].push(res[j])
} else {
uniqueChannelName[channelName] = [res[j]]
}
}
}
}
res.forEach(ele => {
if (ele.isActive === undefined) {
ele.isActive = true
}
this.getAllSearch()
})
Object.keys(uniqueChannelName).forEach(k => {
const ele = this.channelList.find(e => e.name === k)
if (ele) {
ele.channels = ele.channels.concat(uniqueChannelName[k])
delete uniqueChannelName[k]
}
})
if (Object.keys(uniqueChannelName).length) {
let id = this.channelList.length ? this.channelList.slice(-1)[0].id + 1 : 1
const channelList = Object.keys(uniqueChannelName).map(e => { return { id: id++, name: e, isActive: uniqueChannelName[e].some(c => c.isActive), group: this.determineGroup(e), hasChildren: uniqueChannelName[e].length > 1, channels: uniqueChannelName[e] } })
this.channelList = this.channelList.concat(channelList)
}
this.updateDatabase()
iptv.clear() // iptv默认清空状态
})
},
async getChannelList () {
await channelList.all().then(res => {
this.channelList = res
this.getIptvList()
})
},
getIptvList () {
this.iptvList = this.channelList.reduce((result, item) => { item.channels.forEach(e => { e.channelID = item.id }); return result.concat(item.channels) }, [])
},
moveToTopEvent (row) {
if (this.checkAllChannelsLoading) {
this.$message.info('正在检测, 请勿操作.')
return false
}
// this.channelList.sort(function (x, y) { return (x.name === i.name && x.url === i.url) ? -1 : (y.name === i.name && y.url === i.url) ? 1 : 0 })
if (row.channels) {
this.channelList.splice(this.channelList.findIndex(e => e.id === row.id), 1)
this.channelList.unshift(row)
this.updateDatabase()
}
},
syncTableData () {
if (this.$refs.iptvTable.tableData && this.$refs.iptvTable.tableData.length === this.channelList.length) {
this.channelList = this.$refs.iptvTable.tableData
}
},
updateDatabase () {
this.syncTableData()
Object.values(this.$refs.iptvTable.store.states.treeData).forEach(e => { e.loaded = false })
channelList.clear().then(res => {
this.resetId(this.channelList)
channelList.bulkAdd(this.channelList)
this.getChannelList()
})
},
resetId (channelList) {
var id = 1
channelList.forEach(ele => {
ele.id = id
id += 1
ele.channels.forEach(e => {
e.channelID = ele.id
const embedChannelID = ele.id + '_'
const prefer = ele.prefer ? ele.channels.find(e => e.id === ele.prefer) : ''
ele.channels.forEach((e, index) => { e.id = embedChannelID + index }) // 为避免混杂给内置iptv重起id
if (prefer) ele.prefer = prefer.id
})
if (ele.channels.length === 1) {
ele.hasChildren = false
} else {
ele.hasChildren = true
}
})
},
rowDrop () {
if (this.checkAllChannelsLoading) {
this.$message.info('正在检测, 请勿操作.')
return false
}
const tbody = document.getElementById('iptv-table').querySelector('.el-table__body-wrapper tbody')
const _this = this
this.sortableTable = new Sortable(tbody, {
filter: '.el-table__row--level-1', // 禁止children拖动
onEnd ({ newIndex, oldIndex }) {
const currRow = _this.channelList.splice(oldIndex, 1)[0]
_this.channelList.splice(newIndex, 0, currRow)
_this.updateDatabase()
}
})
},
isActiveChangeEvent (row) {
if (row.url) {
const ele = this.channelList.find(e => e.id === row.channelID)
ele.isActive = ele.channels.some(e => e.isActive)
channelList.remove(row.channelID)
channelList.add(ele)
} else {
if (row.channels.length === 1) row.channels[0].isActive = row.isActive
channelList.remove(row.id)
channelList.add(row)
}
},
async checkAllChannels () {
this.checkAllChannelsLoading = true
this.stopFlag = false
this.checkProgress = 0
this.channelList.filter(e => e.channels.length).forEach(e => { e.status = ' '; e.hasCheckedNum = 0 })
const uncheckedList = this.iptvList.filter(e => e.status === undefined || e.status === ' ') // 未检测过的优先
const other = this.iptvList.filter(e => !uncheckedList.includes(e))
await this.checkChannelsBySite(uncheckedList)
await this.checkChannelsBySite(other).then(res => {
this.checkAllChannelsLoading = false
this.getChannelList()
})
},
async checkChannelsBySite (channels) {
var siteList = {}
channels.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 (channel) {
if (this.setting.allowPassWhenIptvCheck && !channel.isActive) {
this.checkProgress += 1
return
}
channel.status = ' '
const ele = this.channelList.find(e => e.id === channel.channelID)
if (this.stopFlag) {
this.checkProgress += 1
return channel.status
}
const flag = await zy.checkChannel(channel.url)
this.checkProgress += 1
ele.hasCheckedNum++
if (flag) {
channel.status = '可用'
} else {
channel.status = '失效'
channel.isActive = false
if (this.setting.autocleanWhenIptvCheck) {
ele.channels.splice(ele.channels.findIndex(e => e.id === channel.id), 1)
ele.hasCheckedNum--
}
}
if (ele.hasCheckedNum === ele.channels.length) {
ele.status = ele.channels.some(channel => channel.status === '可用') ? '可用' : '失效'
if (ele.status === '失效') ele.isActive = false
channelList.remove(channel.channelID)
if (ele.channels.length === 1) ele.hasChildren = false
if (ele.channels.length) channelList.add(ele)
}
return channel.status
},
async checkChannel (row) {
if (row.channels) {
row.status = ' '
row.hasCheckedNum = 0
row.channels.forEach(e => this.checkSingleChannel(e))
} else {
this.checkSingleChannel(row)
}
}
},
created () {
this.getAllSites()
this.getAllSearch()
mounted () {
addEventListener('keydown', code => { if (code.keyCode === 16) this.shiftDown = true })
addEventListener('keyup', code => { if (code.keyCode === 16) this.shiftDown = false })
},
async created () {
await this.getChannelList()
if (!this.channelList.length) this.resetChannelsEvent()
}
}
</script>
<style lang="scss" scoped>
.detail{
position: absolute;
left: 80px;
right: 20px;
bottom: 0;
width: calc(100% - 100px);
height: calc(100% - 40px);
z-index: 888;
.detail-content{
height: calc(100% - 10px);
padding: 0 60px;
position: relative;
.detail-header{
width: 100%;
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
.detail-title{
font-size: 16px;
}
.detail-close{
cursor: pointer;
}
}
}
.detail-body{
height: calc(100% - 100px);
overflow-y: auto;
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,348 @@
<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="table" @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 === 'table'">
<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/cuiocean/ZY-Player-Resources/main/Recommendations/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
recommendation.clear().then(recommendation.bulkAdd(this.recommendations))
this.getFilterData()
this.$message.success('更新推荐成功. 仅根据作者cuiocean个人喜好推荐,不喜请无视.')
}
}
this.loading = false
}).catch(error => {
this.loading = false
this.$message.error('更新推荐失败. ' + error)
this.$message.warning('最新的推荐数据保存在Github上,请考虑使用代理或者等待下一版本内置数据更新.')
})
},
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('删除失败')
}
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) {
const text = res.m3u8List
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 {
zy.detail(e.key, e.ids).then(res => {
const list = [...res.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

@@ -6,7 +6,7 @@
<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}} 反馈</a>
<a style="color:#38dd77" @click="linkOpen('https://github.com/Hunlongyu/ZY-Player/releases/tag/v' + latestVersion)" v-show="latestVersion !== pkg.version" >最新版本v{{latestVersion}}</a>
<a style="color:#38dd77" @click="quitAndInstall()" v-show="latestVersion !== pkg.version" >最新版本v{{latestVersion}}</a>
</div>
<div class="view">
<div class="title">视图</div>
@@ -42,34 +42,50 @@
</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='search'>
<div class="title">搜索</div>
<div class="zy-input" @click="toggleSearchAllSites">
<input type="checkbox" v-model = "d.searchAllSites" @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 = "editPlayerPath = true">
<div class="vs-placeholder vs-noAfter" v-show = "editPlayerPath == false">
<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 = "editPlayerPath == true" v-model = "d.externalPlayer"
<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="view = 'IPTV'">编辑直播源</div>
</div>
<div class="zy-input">
<input type="checkbox" v-model = "d.allowPassWhenIptvCheck" @change="updateSettingEvent"> 检测时自动跳过停用源
</div>
<div class="zy-input">
<input type="checkbox" v-model = "d.autocleanWhenIptvCheck" @change="updateSettingEvent"> 检测时自动清理无效源
</div>
</div>
</div>
<div class="site">
<div class="title">源管理</div>
<div class="site-box">
@@ -79,9 +95,21 @@
<div class="zy-input" @click="toggleExcludeRootClasses">
<input type="checkbox" v-model = "d.excludeRootClasses" @change="updateSettingEvent"> 屏蔽主分类
</div>
<div class="zy-input" @click="toggleExcludeR18Films">
<input type="checkbox" v-model = "d.excludeR18Films" @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">
@@ -116,61 +144,119 @@
<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 class="clearDB">
<span @click="clearDBEvent" class="clearBtn">软件重置</span>
<span class="clearTips">如果新安装用户, 无法显示资源, 请点击软件重置. 如非必要, 切勿点击. 会清空用户数据, 恢复默认设置. 点击即软件重置, 并关闭软件.</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 pkg from '../../package.json'
import { setting, sites, shortcut, star } from '../lib/dexie'
import { shell, clipboard, remote } from 'electron'
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,
sitesList: [],
shortcutList: [],
favoritesList: [],
show: {
site: false,
shortcut: false,
view: false
},
externalPlayer: '',
editPlayerPath: false,
excludeR18Films: true,
latestVersion: pkg.version,
forwardTimeInSec: 5,
d: {
id: 0,
site: '',
theme: '',
shortcut: true,
searchAllSites: true,
view: 'picture',
externalPlayer: '',
view: false,
editPlayerPath: false,
excludeRootClasses: true,
excludeR18Films: true,
forwardTimeInSec: 5
checkPasswordDialog: false,
changePasswordDialog: false,
proxy: false,
proxyDialog: false
},
d: { },
latestVersion: pkg.version,
inputPassword: '',
action: '',
proxy: {
type: '',
scheme: '',
url: '',
port: ''
}
}
},
computed: {
view: {
get () {
return this.$store.getters.getView
},
set (val) {
this.SET_VIEW(val)
}
},
setting: {
get () {
return this.$store.getters.getSetting
@@ -178,40 +264,25 @@ export default {
set (val) {
this.SET_SETTING(val)
}
},
editSites: {
get () {
return this.$store.getters.getEditSites
},
set (val) {
this.SET_EDITSITES(val)
}
}
},
methods: {
...mapMutations(['SET_SETTING', 'SET_EDITSITES']),
...mapMutations(['SET_SETTING', 'SET_VIEW']),
linkOpen (e) {
shell.openExternal(e)
},
getSetting () {
setting.find().then(res => {
this.d = {
id: res.id,
theme: res.theme,
shortcut: res.shortcut,
view: res.view,
externalPlayer: res.externalPlayer,
searchAllSites: res.searchAllSites,
excludeRootClasses: res.excludeRootClasses,
excludeR18Films: res.excludeR18Films,
forwardTimeInSec: res.forwardTimeInSec
}
this.d = res
this.setting = this.d
})
},
getSites () {
sites.all().then(res => {
this.sitesList = res
if (res.length <= 0) {
this.$message.warning('检测到视频源未能正常加载, 即将重置源.')
sites.clear().then(sites.bulkAdd(defaultSites).then(this.getSites()))
}
})
},
getShortcut () {
@@ -219,25 +290,24 @@ export default {
this.shortcutList = res
})
},
getFavorites () {
star.all().then(res => {
this.favoritesList = 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.editPlayerPath = false
this.show.editPlayerPath = false
this.setting = this.d
setting.update(this.d)
},
toggleSearchAllSites () {
this.d.searchAllSites = !this.d.searchAllSites
this.updateSettingEvent()
},
toggleExcludeR18Films () {
this.d.excludeR18Films = !this.d.excludeR18Films
this.updateSettingEvent()
@@ -274,15 +344,56 @@ export default {
},
updatePlayerPath () {
this.$message.success('设定第三方播放器路径为:' + this.d.externalPlayer)
this.editPlayerPath = false
this.show.editPlayerPath = false
this.updateSettingEvent()
},
editSitesEvent () {
this.editSites = {
show: true,
sites: this.sitesList
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.d.theme = e
this.updateSettingEvent()
@@ -294,7 +405,7 @@ export default {
},
expShortcut () {
const arr = [...this.shortcutList]
const str = JSON.stringify(arr, null, 4)
const str = JSON.stringify(arr, null, 2)
clipboard.writeText(str)
this.$message.success('已复制到剪贴板')
},
@@ -309,7 +420,36 @@ export default {
})
})
},
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.$message.success('重置成功')
const win = remote.getCurrentWindow()
@@ -327,14 +467,30 @@ export default {
}
},
getLatestVersion () {
const cheerio = require('cheerio')
const axios = require('axios')
var url = 'https://github.com/Hunlongyu/ZY-Player/releases'
axios.get(url).then(res => {
const $ = cheerio.load(res.data)
var e = $('div.release-header')[0]
var firstResult = $(e).find('div>div>a')
this.latestVersion = firstResult.text()
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())
})
}
},
@@ -342,8 +498,8 @@ export default {
this.getSites()
this.getSetting()
this.getShortcut()
this.getFavorites()
this.getLatestVersion()
this.createContextMenu()
}
}
</script>
@@ -391,11 +547,6 @@ export default {
}
}
}
.search{
width: 100%;
padding: 20px;
margin-top: 20px;
}
.site{
width: 100%;
padding: 20px;
@@ -480,9 +631,9 @@ export default {
line-height: 32px;
}
.clearTips{
margin: 10px 0 0 20px;
font-size: 12px;
color: #ff000088;
margin-left: 10px;
}
}
.Tips{

View File

@@ -1,5 +1,5 @@
<template>
<div class="share" id="share" @click="shareClickEvent">
<div class="share" id="share" @click="shareClickEvent" v-on-clickaway="shareClickEvent">
<div class="left">
<img :src="pic" alt="" @load="picLoadEvent">
</div>
@@ -22,6 +22,7 @@ import { mapMutations } from 'vuex'
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',
@@ -56,6 +57,9 @@ export default {
deep: true
}
},
directives: {
onClickaway: onClickaway
},
methods: {
...mapMutations(['SET_SHARE']),
shareClickEvent () {
@@ -70,18 +74,7 @@ export default {
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('#')
}
var m3u8List = res.m3u8List
const url = m3u8List[1]
this.link = 'http://zyplayer.fun/player/player.html?url=' + url + '&title=' + this.share.info.name
}
@@ -89,7 +82,7 @@ export default {
})
},
picLoadEvent () {
const dom = document.getElementById('right')
const dom = document.getElementById('share')
html2canvas(dom, { useCORS: true, allowTaint: true }).then(res => {
const png = res.toDataURL('image/png')
const p = nativeImage.createFromDataURL(png)

View File

@@ -1,99 +1,157 @@
<template>
<div class="detail">
<div class="detail-content">
<div class="detail-header">
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="exportFavoritesEvent">
导出
</div>
</div>
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="importFavoritesEvent">
导入
</div>
</div>
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="clearFavoritesEvent">
清空
</div>
</div>
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="updateAllEvent">
同步所有收藏
</div>
</div>
<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="table" @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 === 'table'">
<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="detail-body zy-scroll">
<div class="zy-table">
<div class="tBody zy-scroll">
<ul>
<li v-show="this.list.length > 0">
<span class="name">名字</span>
<span class="type">类型</span>
<span class="time">上映</span>
<span class="site">片源</span>
<span class="note">备注</span>
<span class="note">观看至</span>
<span class="operate">
<span class="btn"></span>
<span class="btn"></span>
<span class="btn"></span>
<span class="btn"></span>
<span class="btn"></span>
</span>
</li>
<draggable v-model="list" @change="listUpdatedEvent">
<transition-group>
<li
v-for="(i, j) in list"
:key="j"
@click="detailEvent(i)"
:class="[i.hasUpdate ? 'zy-highlighted' : '']"
>
<span class="name">{{ i.name }}</span>
<span class="type">{{ i.type }}</span>
<span class="time">{{ i.year }}</span>
<span class="site">{{ getSiteName(i.key) }}</span>
<span class="note">{{ i.note }}</span>
<span class="note">{{ getHistoryNote(i.index) }}</span>
<span class="operate">
<span class="btn" @click.stop="playEvent(i)">播放</span>
<span class="btn" @click.stop="shareEvent(i)">分享</span>
<span class="btn" @click.stop="updateEvent(i)">同步</span>
<span class="btn" @click.stop="downloadEvent(i)"
>下载</span
>
<span class="btn" @click.stop="deleteEvent(i)">删除</span>
</span>
</li>
</transition-group>
</draggable>
</ul>
</div>
</div>
<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 { star, history, sites } from '../lib/dexie'
import { star, sites, setting } from '../lib/dexie'
import zy from '../lib/site/tools'
import draggable from 'vuedraggable'
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 {
list: [],
sites: []
sites: [],
viewMode: 'picture',
numNoUpdate: 0
}
},
components: {
draggable
Waterfall
},
computed: {
view: {
@@ -131,12 +189,30 @@ export default {
},
watch: {
view () {
this.getFavorites()
this.getAllsites()
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,
@@ -150,14 +226,12 @@ export default {
this.clearHasUpdateFlag(e)
}
},
playEvent (e) {
history.find({ site: e.key, ids: e.ids }).then(res => {
if (res) {
this.video = { key: e.key, info: { id: res.ids, name: res.name, index: res.index } }
} else {
this.video = { key: e.key, info: { id: e.ids, name: e.name, index: 0 } }
}
})
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)
}
@@ -167,8 +241,6 @@ export default {
star.remove(e.id).then(res => {
if (res) {
this.$message.warning('删除失败')
} else {
this.$message.success('删除成功')
}
this.getFavorites()
})
@@ -180,46 +252,37 @@ export default {
info: e
}
},
clearHasUpdateFlag (e) {
star.find({ id: e.id }).then(res => {
res.hasUpdate = false
star.update(e.id, res)
this.getFavorites()
})
checkUpdate ({ row, rowIndex }) {
if (this.list[rowIndex].hasUpdate) {
return 'highlight'
}
},
listUpdatedEvent () {
star.clear().then(res1 => {
// 重新排序
var id = this.list.length
this.list.forEach(element => {
element.id = id
star.add(element)
id -= 1
})
})
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) {
zy.detail(e.key, e.ids).then(res => {
zy.detail(e.key, e.ids).then(detailRes => {
var doc = {
key: e.key,
id: e.id,
ids: res.id,
last: res.last,
name: res.name,
type: res.type,
year: res.year,
note: res.note
key: e.key,
ids: e.ids,
site: e.site,
name: e.name,
detail: detailRes,
index: e.index
}
star.get(e.id).then(resStar => {
doc.hasUpdate = resStar.hasUpdate
var msg = ''
if (e.last === res.last) {
msg = `同步"${e.name}"成功, 未查询到更新。`
this.$message.info(msg)
} else {
if (!e.hasUpdate && e.detail.last !== detailRes.last) {
doc.hasUpdate = true
msg = `同步"${e.name}"成功, 检查到更新。`
var msg = `同步"${e.name}"成功, 检查到更新。`
this.$message.success(msg)
} else {
this.numNoUpdate += 1
}
star.update(e.id, doc)
this.getFavorites()
@@ -230,14 +293,15 @@ export default {
})
},
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 (res) {
const text = res.m3u8List
if (text) {
const list = text.split('#')
let downloadUrl = ''
@@ -251,20 +315,8 @@ export default {
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]
const list = [...res.m3u8List]
let downloadUrl = ''
for (const i of list) {
const url = encodeURI(i.split('$')[1])
@@ -276,10 +328,14 @@ export default {
}
})
},
getSiteName (key) {
var site = this.sites.find(e => e.key === key)
if (site) {
return site.name
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
}
}
},
getHistoryNote (index) {
@@ -291,7 +347,9 @@ export default {
},
getFavorites () {
star.all().then(res => {
this.list = res.reverse()
this.list = res.sort(function (a, b) {
return b.id - a.id
})
})
},
getAllsites () {
@@ -301,7 +359,7 @@ export default {
},
exportFavoritesEvent () {
const arr = [...this.list]
const str = JSON.stringify(arr, null, 4)
const str = JSON.stringify(arr, null, 2)
const options = {
filters: [
{ name: 'JSON file', extensions: ['json'] },
@@ -312,7 +370,7 @@ export default {
remote.dialog.showSaveDialog(options).then(result => {
if (!result.canceled) {
fs.writeFileSync(result.filePath, str)
this.$message.success('已保存成功')
this.$message.success('导出收藏成功')
}
}).catch(err => {
this.$message.error(err)
@@ -329,84 +387,107 @@ export default {
}
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)
star.bulkAdd(json).then(e => {
this.getFavorites()
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)
}
})
this.upgradeFavorites()
})
this.$message.success('导入收藏成功')
star.clear().then(star.bulkAdd(starList).then(res => {
this.getFavorites()
this.$message.success('导入收藏成功')
}))
}
}).catch(err => {
this.$message.error(err)
})
},
upgradeFavorites () {
star.all().then(res => {
res.forEach(element => {
const docs = {
key: element.key,
ids: element.ids,
name: element.name,
type: element.type,
year: element.year,
last: element.last,
note: element.note
}
star.find({ key: element.key, ids: element.ids }).then(res => {
if (!res) {
star.add(docs)
}
})
})
this.getFavorites()
})
},
clearFavoritesEvent () {
star.clear().then(e => {
this.getFavorites()
this.$message.success('清空所有收藏成功')
})
},
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()
}
})
},
getViewMode () {
setting.find().then(res => {
this.viewMode = res.starViewMode
})
},
updateViewMode () {
setting.find().then(res => {
res.starViewMode = this.viewMode
setting.update(res)
})
}
},
created () {
this.getFavorites()
window.Sortable = require('sortablejs').Sortable
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>
.detail{
position: absolute;
left: 80px;
right: 20px;
bottom: 0;
width: calc(100% - 100px);
height: calc(100% - 40px);
z-index: 888;
.detail-content{
height: calc(100% - 10px);
padding: 0 60px;
position: relative;
.detail-header{
width: 100%;
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
.detail-title{
font-size: 16px;
}
.detail-close{
cursor: pointer;
}
}
}
.detail-body{
height: calc(100% - 50px);
overflow-y: auto;
}
}
</style>

View File

@@ -10,7 +10,7 @@ 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)
@@ -24,5 +24,6 @@ export default {
Vue.component('History', History)
Vue.component('EditSites', EditSites)
Vue.component('IPTV', IPTV)
Vue.component('Recommendation', Recommendation)
}
}

View File

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

View File

@@ -1,18 +1,19 @@
import Dexie from 'dexie'
import { setting, sites, localKey, iptv } from './initData'
import { setting, sites, localKey, iptv, recommendations } from './initData'
const db = new Dexie('zy')
db.version(3).stores({
db.version(4).stores({
search: '++id, keywords',
iptvSearch: '++id, keywords',
setting: 'id, theme, site, shortcut, view, externalPlayer, searchAllSites, excludeRootClasses, excludeR18Films, forwardTimeInSec',
setting: 'id, theme, site, shortcut, view, volume, externalPlayer, searchGroup, excludeRootClasses, excludeR18Films, forwardTimeInSec, starViewMode, recommandationViewMode, searchViewMode, password, proxy, allowPassWhenIptvCheck, autocleanWhenIptvCheck',
shortcut: 'name, key, desc',
star: '++id, site, ids, name, type, year, index',
sites: '++id, key, name, json, xml, down, level',
history: '++id, site, ids, name, type, year, index, time',
mini: 'id, site, ids, name, index, time',
iptv: '++id, name, url'
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, bounds',
iptv: '++id, name, url, isActive',
channelList: '++id, name, prefer, channels, group, isActive'
})
db.on('populate', () => {
@@ -20,6 +21,7 @@ db.on('populate', () => {
db.sites.bulkAdd(sites)
db.shortcut.bulkAdd(localKey)
db.iptv.bulkAdd(iptv)
db.recommendation.bulkAdd(recommendations)
})
db.open()

View File

@@ -4,8 +4,11 @@ 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

@@ -5,8 +5,9 @@ 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 channelList from './channelList'
import recommendation from './recommendation'
export {
history,
@@ -16,6 +17,7 @@ export {
star,
sites,
iptv,
channelList,
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,259 @@
[
{
"id": 1,
"key": "mahuazy",
"name": "麻花资源",
"api": "http://www.mhapi123.com/inc/ldg_api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 2,
"key": "1886zy",
"name": "1886 资源",
"api": "http://cj.1886zy.co/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"key": "wolongzy",
"id": 3,
"name": "卧龙资源网",
"api": "https://www.mhapi123.com/inc/api.php",
"download": "",
"group": "默认",
"isActive": true
},
{
"id": 4,
"key": "123ku",
"name": "123 资源",
"api": "http://cj.123ku2.com:12315/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 5,
"key": "subo988",
"name": "速播资源站",
"api": "https://www.subo988.com/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 6,
"key": "88zyw",
"name": "88 影视资源站",
"api": "http://www.88zyw.net/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"key": "zuidazy",
"id": 7,
"name": "最大资源网",
"api": "http://www.zdziyuan.com/inc/ldg_sea.php",
"download": "http://www.zdziyuan.com/inc/apidown.php",
"group": "默认",
"isActive": true
},
{
"key": "mbo",
"id": 8,
"name": "秒播资源",
"api": "http://caiji.mb77.vip/inc/seacmsapi.php",
"download": "",
"group": "默认",
"isActive": true
},
{
"id": 9,
"key": "apibdzy",
"name": "百度云资源",
"api": "https://api.apibdzy.com/api.php/provide/vod/at/xml",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 10,
"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": 11,
"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": 12,
"key": "kubozy",
"name": "酷播资源",
"api": "http://api.kbzyapi.com/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 13,
"key": "yongjiuzy",
"name": "永久资源",
"api": "http://cj.yongjiuzyw.com/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 14,
"key": "rrzy",
"name": "人人资源",
"api": "https://www.rrzyw.cc/api.php/provide/vod/from/rrm3u8/at/xml/",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 15,
"key": "bbkdj",
"name": "步步高顶尖资源网",
"api": "http://api.bbkdj.com/api",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 16,
"key": "solezy",
"name": "搜乐资源网",
"api": "https://www.caijizy.vip/api.php/provide/vod/at/xml/",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 17,
"key": "zuixinzy",
"name": "最新资源",
"api": "http://api.zuixinapi.com/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 18,
"key": "605zy",
"name": "605资源",
"api": "http://www.605zy.net/inc/seacmsapi.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": "mokazy",
"name": "魔卡资源网",
"api": "https://cj.heiyap.com/api.php/provide/vod/at/xml/",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 25,
"key": "158zy",
"name": "壹伍捌资源网",
"api": "http://cj.158zyz.net:158/inc/api.php",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
},
{
"id": 26,
"key": "kyzy",
"name": "快影资源站",
"api": "https://www.kyzy.tv/api.php/kyyun/vod/at/xml/",
"download": "",
"group": "默认",
"isActive": true,
"status": "可用"
}
]

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +0,0 @@
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

@@ -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()
}
}

View File

@@ -8,7 +8,7 @@ export default {
return await star.bulkAdd(doc)
},
async find (doc) {
return await star.get(doc)
return await star.where(doc).first()
},
async update (id, docs) {
return await star.update(id, docs)

View File

@@ -1,3 +1,20 @@
import Vue from 'vue'
import { Message } from 'element-ui'
import { Message, Button, Table, TableColumn, Tag, Input, Dialog, Form, FormItem, Switch, Select, Option, Checkbox, Autocomplete, Col, Tree } 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.use(Tree)
Vue.prototype.$message = Message

View File

@@ -3,6 +3,36 @@ 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}`
@@ -214,6 +244,74 @@ const onlineVideo = {
})
}
})
},
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

View File

@@ -1,6 +1,64 @@
import { sites } from '../dexie'
import { sites, setting } from '../dexie'
import axios from 'axios'
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 = {
xmlConfig: { // XML 转 JSON 配置
trimValues: true,
@@ -34,9 +92,10 @@ const zy = {
axios.post(url).then(res => {
const data = res.data
const json = parser.parse(data, this.xmlConfig)
const jsondata = json.rss === undefined ? json : json.rss
const arr = []
if (json.rss.class) {
for (const i of json.rss.class.ty) {
if (jsondata.class) {
for (const i of jsondata.class.ty) {
const j = {
tid: i._id,
name: i._t
@@ -46,10 +105,10 @@ const zy = {
}
const doc = {
class: arr,
page: json.rss.list._page,
pagecount: json.rss.list._pagecount,
pagesize: json.rss.list._pagesize,
recordcount: json.rss.list._recordcount
page: jsondata.list._page,
pagecount: jsondata.list._pagecount,
pagesize: jsondata.list._pagesize,
recordcount: jsondata.list._recordcount
}
resolve(doc)
}).catch(err => {
@@ -78,7 +137,8 @@ const zy = {
axios.post(url).then(async res => {
const data = res.data
const json = parser.parse(data, this.xmlConfig)
const videoList = json.rss.list.video
const jsondata = json.rss === undefined ? json : json.rss
const videoList = jsondata.list.video
resolve(videoList)
}).catch(err => {
reject(err)
@@ -105,11 +165,12 @@ const zy = {
axios.post(url).then(async res => {
const data = res.data
const json = parser.parse(data, this.xmlConfig)
const jsondata = json.rss === undefined ? json : json.rss
const pg = {
page: json.rss.list._page,
pagecount: json.rss.list._pagecount,
pagesize: json.rss.list._pagesize,
recordcount: json.rss.list._recordcount
page: jsondata.list._page,
pagecount: jsondata.list._pagecount,
pagesize: jsondata.list._pagesize,
recordcount: jsondata.list._recordcount
}
resolve(pg)
}).catch(err => {
@@ -133,8 +194,9 @@ const zy = {
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
const jsondata = json.rss === undefined ? json : json.rss
if (json && jsondata && jsondata.list) {
const videoList = jsondata.list.video
resolve(videoList)
}
}).catch(err => {
@@ -158,7 +220,23 @@ const zy = {
axios.post(url).then(res => {
const data = res.data
const json = parser.parse(data, this.xmlConfig)
const videoList = json.rss.list.video
const jsondata = json.rss === undefined ? json : json.rss
const videoList = jsondata.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) {
// 如果含有多个视频列表的话, 仅获取m3u8列表
if (i._flag.includes('m3u8')) {
m3u8List = i._t.split('#')
}
}
} else {
m3u8List = dd._t.split('#')
}
videoList.m3u8List = m3u8List
resolve(videoList)
}).catch(err => {
reject(err)
@@ -178,12 +256,25 @@ const zy = {
return new Promise((resolve, reject) => {
this.getSite(key).then(res => {
const site = res
const url = `${site.download}?ac=videolist&ids=${id}&ct=1`
if (url) {
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
const jsondata = json.rss === undefined ? json : json.rss
const videoList = jsondata.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) {
m3u8List = i._t.split('#')
}
} else {
m3u8List = dd._t.split('#')
}
videoList.m3u8List = m3u8List
resolve(videoList)
}).catch(err => {
reject(err)
@@ -193,7 +284,134 @@ const zy = {
}
})
})
},
/**
* 检查资源
* @param {*} key 资源网 key
* @returns boolean
*/
async check (key, id) {
try {
const cls = await this.class(key)
if (cls) {
return true
} else {
return false
}
} 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)
}
}).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 (link) {
resolve(link)
} else {
// 如果没找到符合的链接,返回搜索页面
resolve(doubanSearchLink)
}
}).catch(err => {
reject(err)
})
})
},
/**
* 获取豆瓣评分
* @param {*} name 视频名称
* @returns 豆瓣评分
*/
doubanRate (name) {
return new Promise((resolve, reject) => {
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)
})
})
},
async proxy () {
return new Promise((resolve, reject) => {
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)
}
}
}
// 不要删了,留着测试用
// axios.get('https://api.my-ip.io/ip').then(res => console.log(res))
})
})
}
}
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

@@ -4,6 +4,7 @@ import store from './store'
import 'modern-normalize'
import Register from './components/register'
import './lib/element/index'
Register.registerComponents()
Vue.config.productionTip = false
new Vue({

View File

@@ -1,524 +0,0 @@
<template>
<div class="mini">
<div class="top">
<div class="left">
<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="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" 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="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>
</div>
<div class="bottom">
<div id="xg"></div>
</div>
</div>
</template>
<script>
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 { remote, ipcRenderer } = require('electron')
const VIDEO_DETAIL_CACHE = {}
export default {
name: 'mini',
data () {
const win = remote.getCurrentWindow()
return {
xg: null,
config: {
id: 'xg',
url: '',
lang: 'zh-cn',
width: '100%',
height: '100%',
autoplay: false,
videoInit: true,
screenShot: true,
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],
controls: false
},
opacity: 100,
name: '',
video: {},
detail: {},
m3u8Arr: [],
rate: 1,
progress: 0,
isAlwaysOnTop: win.isAlwaysOnTop()
}
},
methods: {
frameClickEvent (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 (val) {
const win = remote.getCurrentWindow()
const num = val / 100
win.setOpacity(num)
return false
},
getUrls () {
mini.find().then(res => {
this.video = res
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 = res.time
})
} else {
this.xg.play()
}
this.videoPlaying()
this.xg.once('ended', () => {
if (m3u8Arr.length > 1 && (m3u8Arr.length - 1 > res.index)) {
this.video.time = 0
this.video.index++
this.xg.src = m3u8Arr[this.video.index]
this.xg.play()
}
})
})
})
},
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
}
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)
})
})
},
videoPlaying () {
history.find({ site: this.video.site, ids: this.video.ids }).then(res => {
if (res) {
res.index = this.video.index
history.update(res.id, res)
} 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(() => {
const endTime = this.xg.duration
const currentTime = this.xg.currentTime
const progress = (currentTime / endTime) * 100
this.progress = progress.toFixed(2)
history.find({ site: this.video.site, ids: this.video.ids }).then(res => {
if (res) {
const v = res
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.video.index === 0) {
this.$message.info('已是第一集.')
return false
}
history.find({ site: this.video.site, ids: this.video.ids }).then(res => {
const v = res
const id = v.id
v.index--
delete v.id
history.update(id, v).then(e => {
this.xg.src = this.m3u8Arr[v.index]
this.video.index--
})
})
},
nextEvent () {
if (this.video.index >= this.m3u8Arr.length - 1) {
this.$message.info('已是最后一集.')
return false
}
history.find({ site: this.video.site, ids: this.video.ids }).then(res => {
const v = res
v.index++
const id = v.id
delete v.id
history.update(id, v).then(e => {
this.xg.src = this.m3u8Arr[v.index]
this.video.index++
})
})
},
playbackRateEvent (e) {
let rate = this.xg.playbackRate
if (rate > 0.25) {
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
}
}
},
mounted () {
this.xg = new Hls(this.config)
this.mtEvent()
this.getUrls()
},
beforeDestroy () {
clearInterval(this.timer)
}
}
</script>
<style lang="scss">
html,body{
padding: 1px;
margin: 0;
height: 100%;
width: 100%;
overflow: hidden;
background-color: #000;
}
.mini{
-webkit-app-region: drag;
box-sizing: border-box;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: flex-start;
flex-direction: column;
.top{
width: 100%;
height: 30px;
display: flex;
justify-content: space-between;
align-items: center;
user-select: none;
.zy-svg{
-webkit-app-region: no-drag;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
svg{
width: 24px;
height: 24px;
stroke: #888;
stroke-width: 1;
stroke-linecap: round;
stroke-linejoin: round;
fill: none;
}
}
.left{
display: flex;
justify-content: flex-start;
align-items: center;
height: 100%;
flex: 1;
.title, .opacity, .rate, .progress{
color: #888;
font-size: 12px;
margin: 0 10px;
}
}
.right{
width: 80px;
height: 100%;
display: flex;
justify-content: flex-end;
align-items: center;
span{
-webkit-app-region: no-drag;
display: inline-block;
width: 14px;
height: 14px;
text-align: center;
line-height: 14px;
border-radius: 50%;
margin-right: 10px;
cursor: pointer;
opacity: 0.4;
&.min{
background-color: #32dc36;
}
&.max{
background-color: #ffbe2a;
}
&.close{
background-color: #ff5f56;
}
&.top{
background-color: #f3bab7;
}
&: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;
}
}
}
}
}
.bottom{
width: 100%;
flex: 1;
.xgplayer-start{
-webkit-app-region: no-drag;
}
}
}
</style>

View File

@@ -1,10 +0,0 @@
import Vue from 'vue'
import Mini from './Mini'
import 'modern-normalize'
import '../lib/element/index'
Vue.config.productionTip = false
new Vue({
render: h => h(Mini)
}).$mount('#app')

View File

@@ -26,9 +26,8 @@ export default new Vuex.Store({
key: '',
info: {}
},
editSites: {
show: false,
sites: []
appState: {
windowIsOnTop: false
}
},
getters: {
@@ -47,8 +46,8 @@ export default new Vuex.Store({
getVideo: state => {
return state.video
},
getEditSites: state => {
return state.editSites
getAppState: state => {
return state.appState
}
},
mutations: {
@@ -67,8 +66,8 @@ export default new Vuex.Store({
SET_VIDEO: (state, payload) => {
state.video = payload
},
SET_EDITSITES: (state, payload) => {
state.editSites = payload
SET_APPSTATE: (state, payload) => {
state.appState = payload
}
}
})

View File

@@ -1,7 +1,6 @@
module.exports = {
pages: {
index: 'src/main.js',
mini: 'src/mini/main.js'
index: 'src/main.js'
},
pluginOptions: {
electronBuilder: {

2044
yarn.lock

File diff suppressed because it is too large Load Diff