Compare commits

..

21 Commits

Author SHA1 Message Date
Hunlongyu
069e7e16d6 ✌ 大佬优化了播放器 🤞 2020-07-29 10:31:55 +08:00
Hunlongyu
cabe4240f4 Merge pull request #150 from hectorqin/master
完善播放器功能,完善右上角窗口管理icon
2020-07-29 10:27:57 +08:00
hectorqin
5448e86109 更新播放库 2020-07-29 09:54:45 +08:00
hectorqin
536f6dad7d 新增导出播放列表功能,修复mini同步进度,优化mini视频加载 2020-07-28 22:53:54 +08:00
hectorqin
bf2796779f 优化播放器 2020-07-28 21:18:21 +08:00
hectorqin
3a29147fd6 完善右上角按钮,完善播放器标题 2020-07-28 17:33:45 +08:00
hectorqin
e987ecc446 完善播放器功能 2020-07-28 10:21:14 +08:00
Hunlongyu
9aee6d8527 Merge pull request #143 from godvmxi/master
add yarn guide for dev and build
2020-07-24 20:39:35 +08:00
Bright Jiang
4d438fcdd3 add yarn usage guide for dev and build 2020-07-24 15:23:34 +08:00
hunlongyu
36e40f4778 🚀 x86 🚁 2020-07-22 10:51:38 +08:00
hunlongyu
422def0702 🎨🖼 x86 打包 🎭🎪 2020-07-22 09:44:25 +08:00
hunlongyu
fc52d79d88 🎉 V2.0.0 正式版发布 🎇🎊 2020-07-22 09:38:26 +08:00
dandan
cc09d0aca0 Merge pull request #1 from Hunlongyu/master
merge to latest
2020-07-17 14:36:52 +08:00
hunlongyu
b514f1c04e v1.2.6 2020-07-16 00:03:34 +08:00
hunlongyu
189e67eb22 🦺 1.2.5 🥼 2020-07-15 23:55:34 +08:00
hunlongyu
e5c3adf1c5 🎍 1.2.4 🎋 2020-07-15 23:53:53 +08:00
hunlongyu
299367f0b8 修复收藏夹播放多集视频的BUG 🎉 2020-07-15 23:51:27 +08:00
hunlongyu
0d67474459 🎟 版本号 🎫 2020-07-15 17:38:21 +08:00
hunlongyu
15a188aa85 🎍 优化 MINI 模式 🎋 2020-07-15 17:38:00 +08:00
hunlongyu
0555badcfa 🍚 修复列表模式下, 下载BUG 🍜 2020-07-14 16:35:51 +08:00
hunlongyu
6f8f700dfc 🍟 修复BUG 🌭 2020-07-14 15:26:01 +08:00
18 changed files with 760 additions and 141 deletions

View File

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

View File

@@ -25,13 +25,15 @@
# 目录
- [特性](#特性)
- [全局快捷键](#全局快捷键)
- [重要](#重要)
- [快捷键](#快捷键)
- [下载](#下载)
- [赞助](#赞助)
- [截图](#截图)
- [开发向导](#开发向导)
- [准备环境](#准备环境)
- [nodejs安装](#nodejs安装)
- [yarn新一代包管理器安利](#yarn新一代包管理器安利)
- [npm配置](#npm配置)
- [翻墙代理设置](#翻墙代理设置)
- [镜像源设置](#镜像源设置)
@@ -57,7 +59,10 @@
觉得软件不错的, 点击右上角 star 收藏关注一波呀~
#### 快捷键:
## 重要
从 V1.x 版本升级到 V2.x 版本, 需要重置软件, 由于数据库改动较大, 重置后收藏的资源会丢失. 重置功能在设置界面里.
#### 快捷键
播放窗口 和 Mini窗口
@@ -76,9 +81,9 @@
#### 下载:
1. [Github -- 官方下载(最新版)](https://github.com/Hunlongyu/ZY-Player/releases)
1. [Github -- 官方下载](https://github.com/Hunlongyu/ZY-Player/releases)
2. [蓝奏云 -- 快速下载(老版本)](https://www.lanzous.com/b04s6a3re) 密码:95px
2. [蓝奏云 -- 快速下载](https://www.lanzous.com/b04s6a3re) 密码:95px
3. 适用于32位操作系统的x86软件,在蓝奏云网盘里, 后缀名: ZY Player * 32位.exe
@@ -87,25 +92,24 @@
#### 截图:
0. 分享 ⇣ ↓
![share.gif](https://i.loli.net/2020/06/05/hbJwBXlx194umcO.gif)
1. 浏览 ⇣ ↓
![01浏览.png](https://i.loli.net/2020/05/18/MshDLnXq2CTpoBy.png)
![海报.png](https://i.loli.net/2020/07/22/QDRqv9X1uWbVcpi.png)
![列表.png](https://i.loli.net/2020/07/22/1Rnm6QDyPYWw9ec.png)
2. 搜索 ⇣ ↓
![02搜索.png](https://i.loli.net/2020/05/20/QgJqDkcjpeiRvBb.png)
![搜索.png](https://i.loli.net/2020/07/22/qFdyYfc7iNxZXKT.png)
3. 详情 ⇣ ↓
![03详情.png](https://i.loli.net/2020/05/18/s7gUj6unEfyYb4Z.png)
![详情.png](https://i.loli.net/2020/07/22/aPUwFHSXYKTn3dC.png)
4. 播放 ⇣ ↓
![04播放.png](https://i.loli.net/2020/05/18/WqgnOw3mHd6e5uU.png)
![播放.png](https://i.loli.net/2020/07/22/xhWCRlOFKw52Vzi.png)
![Mini.png](https://i.loli.net/2020/07/22/suf4bQkoP3gMORH.png)
5. 收藏 ⇣ ↓
![05收藏.png](https://i.loli.net/2020/05/18/bhIgeGMTPWmrdYi.png)
![收藏.png](https://i.loli.net/2020/07/22/32THQIEqdo8YyS6.png)
6. 白色主题皮肤 ⇣ ↓
![06白色.png](https://i.loli.net/2020/05/18/UgiVZ89dhkuxDBI.png)
![白色.png](https://i.loli.net/2020/07/22/ci9oAXC2SE4gqka.png)
7. 绿色主题皮肤 ⇣ ↓
![07绿色.png](https://i.loli.net/2020/05/18/4d2UnFRECm7vyJQ.png)
![绿色.png](https://i.loli.net/2020/07/22/WOfDG5P8CR2cXju.png)
8. 粉色色主题皮肤 ⇣ ↓
![08粉色.png](https://i.loli.net/2020/05/18/PLlEfzd8mSC9vMW.png)
![粉色.png](https://i.loli.net/2020/07/22/48euCatIfnZ6qX7.png)
### 重要:
所有资源来自网上, 该软件不参与任何制作, 上传, 储存, 下载等内容. 该软件仅供学习参考, 请于安装后24小时内删除.
@@ -119,6 +123,9 @@
* [LINK1](https://nodejs.org/zh-cn/)
* [LINK2](https://www.jianshu.com/p/13f45e24b1de/)
#### yarn新一代包管理器安利
最近管理员用[yarn](https://yarn.bootcss.com/)替换了npm本人测试后表示非常好用。。连翻墙都不想要了强烈推荐, 安装好使用yarn代理npm命令即可, [官网安装向导](https://yarn.bootcss.com/docs/install/)
#### npm配置
天朝的网络环境都有耳闻,想顺利开发,要么翻墙,要么镜像源,以下按照自己的水平二选一

View File

@@ -1,6 +1,6 @@
{
"name": "zy",
"version": "1.2.1",
"version": "2.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
@@ -33,7 +33,7 @@
"vue-infinite-loading": "^2.4.5",
"vue-waterfall-plugin": "^1.0.7",
"vuex": "^3.4.0",
"xgplayer": "^2.9.8",
"xgplayer": "^2.9.10",
"xgplayer-hls.js": "^2.2.3"
},
"devDependencies": {

View File

@@ -59,7 +59,7 @@ export default {
@import './assets/scss/theme.scss';
html, body, #app{
height: 100%;
border-radius: 6px;
border-radius: 0px;
}
#app {
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', SimSun, sans-serif;

View File

@@ -101,6 +101,9 @@
&.close{
background-color: #ff5f56;
}
&.top{
background-color: #f3bab7;
}
}
}
.detail{

View File

@@ -101,6 +101,9 @@
&.close{
background-color: #ff5f56;
}
&.top{
background-color: #f3bab7;
}
}
}
.detail{

View File

@@ -101,6 +101,9 @@
&.close{
background-color: #ff5f56;
}
&.top{
background-color: #f3bab7;
}
}
}
.detail{

View File

@@ -101,6 +101,9 @@
&.close{
background-color: #ff5f56;
}
&.top{
background-color: #f3bab7;
}
}
}
.detail{

View File

@@ -28,17 +28,16 @@
</div>
</div>
<div class="body zy-scroll" infinite-wrapper>
<div class="body-box" v-if="!show.find">
<div class="body-box" v-show="!show.find">
<div class="show-img" v-if="setting.view === 'picture'">
<Waterfall :list="list" :gutter="20" :width="240"
<Waterfall ref="waterfall" :list="list" :gutter="20" :width="240"
:breakpoints="{ 1200: { rowPerView: 4 } }"
animationEffect="fadeInUp"
backgroundColor="rgba(0, 0, 0, 0)"
ref="wimg">
backgroundColor="rgba(0, 0, 0, 0)">
<template slot="item" slot-scope="props">
<div class="card">
<div class="img">
<img style="width: 100%" :src="props.data.pic" alt="" @load="$refs.wimg.refresh()" @click="detailEvent(props.data)">
<img style="width: 100%" :src="props.data.pic" alt="" @load="$refs.waterfall.refresh()" @click="detailEvent(props.data)">
<div class="operate">
<div class="operate-wrap">
<span class="o-play" @click="playEvent(props.data)">播放</span>
@@ -79,7 +78,7 @@
</div>
</div>
</div>
<div class="body-box" v-if="show.find">
<div class="body-box" v-show="show.find">
<div class="show-table">
<div class="zy-table">
<div class="tBody">
@@ -185,9 +184,9 @@ export default {
searchTxt () {
this.searchChangeEvent()
},
setting: {
handler (ov, nv) {
this.settingChangeEvent(ov, nv)
'setting.site': {
handler (nv) {
this.getAllsites(nv)
},
deep: true
}
@@ -323,7 +322,7 @@ export default {
},
downloadEvent (e) {
zy.download(this.site.key, e.id).then(res => {
if (res) {
if (res.length > 0) {
const text = res.dl.dd._t
if (text) {
const list = text.split('#')
@@ -338,9 +337,20 @@ export default {
this.$message.warning('没有查询到下载链接.')
}
} else {
const list = [...this.m3u8List]
let m3u8List = []
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) {
m3u8List = i._t.split('#')
}
}
} else {
m3u8List = dd._t.split('#')
}
let downloadUrl = e.name + '\n'
for (const i of list) {
for (const i of m3u8List) {
const url = encodeURI(i.split('$')[1])
downloadUrl += (url + '\n')
}
@@ -352,7 +362,7 @@ export default {
changeView () {
if (this.view === 'Film') {
if (this.show.img) {
this.$refs.wimg.refresh()
this.$refs.waterfall.refresh()
}
this.getPage().then(() => {
this.infiniteId += 1
@@ -371,6 +381,7 @@ export default {
this.searchContents = []
this.pagecount = 0
this.show.search = false
this.show.find = true
if (wd) {
search.find({ keywords: wd }).then(res => {
if (!res) {
@@ -389,7 +400,6 @@ export default {
if (type === '[object Object]') {
this.searchContents.push(res)
}
this.show.find = true
})
} else {
this.show.find = false
@@ -405,6 +415,7 @@ export default {
this.pagecount = 0
this.searchTxt = e.keywords
this.show.search = false
this.show.find = true
search.remove(e.id).then(res => {
search.add({ keywords: e.keywords })
this.getAllSearch()
@@ -420,7 +431,6 @@ export default {
if (type === '[object Object]') {
this.searchContents.push(res)
}
this.show.find = true
})
},
clearSearch () {
@@ -436,20 +446,29 @@ export default {
this.searchContents = []
this.show.find = false
if (this.show.img) {
this.$refs.wimg.refresh()
this.$refs.waterfall.refresh()
}
}
},
getAllsites () {
sites.all().then(res => {
this.sites = res
this.site = this.sites[0]
this.siteClick(this.site)
})
},
settingChangeEvent (ov, nv) {
console.log(ov, nv, 'ov nv')
this.getAllsites()
getAllsites (nv) {
if (nv) {
sites.all().then(res => {
this.sites = res
for (const i of res) {
if (i.key === nv) {
this.site = i
this.siteClick(this.site)
return false
}
}
})
} else {
sites.all().then(res => {
this.sites = res
this.site = this.sites[0]
this.siteClick(this.site)
})
}
}
},
created () {

View File

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

View File

@@ -85,13 +85,14 @@
</div>
<div class="list-body zy-scroll" :style="{overflowY:scroll? 'auto' : 'hidden',paddingRight: scroll ? '0': '5px' }" @mouseenter="scroll = true" @mouseleave="scroll = false">
<ul v-show="right.type === 'list'" class="list-item">
<li v-show="right.history.length > 1" @click="exportM3u8">导出</li>
<li v-show="right.list.length === 0">无数据</li>
<li @click="listItemEvent(j)" :class="video.info.index === j ? 'active' : ''" v-for="(i, j) in right.list" :key="j">{{i | ftName(j)}}</li>
</ul>
<ul v-show="right.type === 'history'" class="list-history">
<li v-show="right.history.length > 1" @click="clearAllHistory">清空</li>
<li v-show="right.history.length === 0">无数据</li>
<li @click="historyItemEvent(m)" :class="video.info.id === m.ids ? 'active' : ''" v-for="(m, n) in right.history" :key="n"><span class="title">{{m.name}}</span><span @click.stop="removeHistoryItem(m)" class="detail-delete">删除</span></li>
<li @click="historyItemEvent(m)" :class="video.info.id === m.ids ? 'active' : ''" v-for="(m, n) in right.history" :key="n"><span class="title" :title="'【' + m.site + '】' + m.name + ' 第' + (m.index+1) + '集'">【{{m.site}}】{{m.name}} 第{{m.index+1}}集</span><span @click.stop="removeHistoryItem(m)" class="detail-delete">删除</span></li>
</ul>
</div>
</div>
@@ -102,10 +103,54 @@
import { mapMutations } from 'vuex'
import { star, history, setting, shortcut, mini } from '../lib/dexie'
import zy from '../lib/site/tools'
import 'xgplayer'
import Player from 'xgplayer'
import Hls from 'xgplayer-hls.js'
import mt from 'mousetrap'
const { remote, ipcRenderer } = require('electron')
const VIDEO_DETAIL_CACHE = {}
const addPlayerBtn = function (event, svg, attrs) {
const player = this
const util = Player.util
const controlEl = player.controls
const btnConfig = player.config[event]
if (btnConfig) {
const btnName = 'xg-btn-' + event
const btn = util.createDom(btnName, svg || btnConfig.svg, attrs || {}, btnName)
controlEl.appendChild(btn)
const ev = ['click', 'touchend']
ev.forEach(item => {
btn.addEventListener(item, function (e) {
e.preventDefault()
e.stopPropagation()
player.emit(event)
}, false)
})
}
}
const addPlayerView = function (event, tpl, attrs) {
const player = this
console.log(player)
const util = Player.util
const rootEl = player.root
const viewConfig = player.config[event]
if (viewConfig) {
const viewName = 'xg-view-' + event
const view = util.createDom(viewName, tpl, attrs || {}, viewName)
rootEl.appendChild(view)
const ev = ['click', 'touchend']
ev.forEach(item => {
view.addEventListener(item, function (e) {
e.preventDefault()
e.stopPropagation()
player.emit(event)
}, false)
})
}
}
export default {
name: 'play',
data () {
@@ -130,7 +175,16 @@ export default {
crossOrigin: true,
cssFullscreen: true,
defaultPlaybackRate: 1,
playbackRate: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 3, 4, 5]
playbackRate: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 3, 4, 5],
playPrev: true,
playNextOne: true,
showList: true,
showHistory: true,
videoTitle: true
},
state: {
showList: false,
showHistory: false
},
name: '',
length: 0,
@@ -205,12 +259,22 @@ export default {
this.changeSetting()
},
deep: true
},
name () {
const span = document.querySelector('.xg-view-videoTitle span')
if (!span) {
return
}
if (this.right.list.length > 1) {
span.innerText = `『第 ${this.video.info.index + 1} 集』${this.name}`
} else {
span.innerText = `${this.name}`
}
}
},
methods: {
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
getUrls () {
console.log(this.video, 'this.video')
this.name = ''
if (this.timer !== null) {
clearInterval(this.timer)
@@ -235,36 +299,7 @@ export default {
})
},
playVideo (index = 0, time = 0) {
const id = this.video.info.id
zy.detail(this.video.key, id).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('#')
}
this.right.list = m3u8Txt
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])
}
}
this.fetchM3u8List().then(m3u8Arr => {
this.xg.src = m3u8Arr[index]
this.showNext = m3u8Arr.length > 1
@@ -286,6 +321,102 @@ export default {
this.xg.off('ended')
})
})
// const id = this.video.info.id
// zy.detail(this.video.key, id).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('#')
// }
// this.right.list = m3u8Txt
// 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])
// }
// }
// this.xg.src = m3u8Arr[index]
// this.showNext = m3u8Arr.length > 1
// if (time !== 0) {
// this.xg.play()
// this.xg.once('playing', () => {
// this.xg.currentTime = time
// })
// } else {
// this.xg.play()
// }
// this.videoPlaying()
// this.xg.once('ended', () => {
// if (m3u8Arr.length > 1 && (m3u8Arr.length - 1 > index)) {
// this.video.info.time = 0
// this.video.info.index++
// }
// this.xg.off('ended')
// })
// })
},
fetchM3u8List () {
return new Promise((resolve) => {
const cacheKey = this.video.key + '@' + this.video.info.id
if (VIDEO_DETAIL_CACHE[cacheKey]) {
this.name = VIDEO_DETAIL_CACHE[cacheKey].name
resolve(VIDEO_DETAIL_CACHE[cacheKey].list)
return
}
zy.detail(this.video.key, this.video.info.id).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('#')
}
this.right.list = m3u8Txt
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 () {
this.changeVideo()
@@ -457,6 +588,47 @@ export default {
this.right.show = false
this.right.type = ''
},
exportM3u8 () {
const m3u8Arr = []
for (const i of this.right.list) {
const j = i.split('$')
let link, name
if (j.length > 1) {
for (let m = 0; m < j.length; m++) {
if (j[m].indexOf('m3u8') >= 0) {
link = j[m]
}
}
name = j[0]
} else {
name = `${m3u8Arr.length + 1}`
link = j[0]
}
m3u8Arr.push({
name: name,
link: link
})
}
console.log(m3u8Arr)
let m3u8Content = `#EXTM3U
`
for (const item of m3u8Arr) {
m3u8Content += `#EXTINF:-1, ${item.name}
${item.link}
`
}
const blob = new Blob([m3u8Content], { type: 'application/vnd.apple.mpegurl' })
const downloadElement = document.createElement('a') // 创建下载的链接
const href = window.URL.createObjectURL(blob)
downloadElement.href = href
downloadElement.download = `${this.name}.m3u8` // 下载后的文件名
document.body.appendChild(downloadElement)
downloadElement.click() // 下载
document.body.removeChild(downloadElement) // 下载完成 移除 a
window.URL.revokeObjectURL(href) // 释放blob对象
},
clearAllHistory () {
history.clear().then(res => {
this.right.history = []
@@ -571,8 +743,10 @@ export default {
return false
}
if (e === 'escape') {
this.xg.exitFullscreen()
this.xg.exitCssFullscreen()
if (this.xg.fullscreen) {
this.xg.exitFullscreen()
this.xg.exitCssFullscreen()
}
return false
}
if (e === 'next') {
@@ -637,6 +811,133 @@ export default {
},
changeSetting () {
this.mtEvent()
},
toggleList () {
if (this.state.showList) {
document.querySelector('xg-btn-showlist ul').style.display = 'none'
this.state.showList = false
} else {
this.refreshList()
document.querySelector('xg-btn-showlist ul').style.display = 'block'
this.state.showList = true
}
},
refreshList () {
let ul = document.querySelector('xg-btn-showlist ul')
if (!ul) {
ul = document.createElement('ul')
document.querySelector('xg-btn-showlist').appendChild(ul)
ul.addEventListener('click', (ev) => {
ev = ev || window.event
const target = ev.target || ev.srcElement // target表示在事件冒泡中触发事件的源元素在IE中是srcElement
if (target.nodeName.toLowerCase() === 'li') {
this.listItemEvent(parseInt(target.dataset.index))
}
})
}
ul.style.display = 'none'
let li = ''
if (this.right.list.length === 0) {
li = '<li>无数据</li>'
} else {
for (let index = 0; index < this.right.list.length; index++) {
const item = this.right.list[index]
const num = item.split('$')
let title
if (num.length > 1) {
title = num[0]
} else {
title = `${(index + 1)}`
}
if (index === this.video.info.index) {
li += `<li class="selected" data-index="${index}" title="${title}">${title}</li>`
} else {
li += `<li data-index="${index}" title="${title}">${title}</li>`
}
}
}
ul.innerHTML = li
},
toggleHistory () {
if (this.state.showHistory) {
document.querySelector('xg-btn-showhistory ul').style.display = 'none'
this.state.showHistory = false
} else {
this.refreshHistory()
document.querySelector('xg-btn-showhistory ul').style.display = 'block'
this.state.showHistory = true
}
},
refreshHistory () {
let ul = document.querySelector('xg-btn-showhistory ul')
if (!ul) {
ul = document.createElement('ul')
document.querySelector('xg-btn-showhistory').appendChild(ul)
ul.addEventListener('click', (ev) => {
ev = ev || window.event
const target = ev.target || ev.srcElement // target表示在事件冒泡中触发事件的源元素在IE中是srcElement
if (target.nodeName.toLowerCase() === 'li') {
this.historyItemEvent(this.right.history[parseInt(target.dataset.index)])
}
})
}
ul.style.display = 'none'
let li = ''
if (this.right.history.length === 0) {
li = '<li>无数据</li>'
} else {
window.historyItemEvent = this.historyItemEvent.bind(this)
for (let index = 0; index < this.right.history.length; index++) {
const item = this.right.history[index]
const text = `${item.site}${item.name}${item.index + 1}`
if (this.video.info.id === item.ids) {
li += `<li class="selected" data-index="${index}" title="${text}">${text}</li>`
} else {
li += `<li data-index="${index}" title="${text}">${text}</li>`
}
}
}
ul.innerHTML = li
},
bindEvent () {
this.xg.on('playNextOne', () => {
this.nextEvent()
})
this.xg.on('playPrev', () => {
this.prevEvent()
})
this.xg.on('showList', () => {
this.toggleList()
})
this.xg.on('showHistory', () => {
this.toggleHistory()
})
const ev = ['click', 'touchend', 'mousemove']
let timerID
ev.forEach(item => {
this.xg.root.addEventListener(item, () => {
if (!this.xg.fullscreen) {
return
}
const videoTitle = document.querySelector('.xg-view-videoTitle')
videoTitle.style.display = 'block'
clearTimeout(timerID)
timerID = setTimeout(() => {
// 播放中自动消失
if (this.xg && !this.xg.paused) {
videoTitle.style.display = 'none'
}
}, 3000)
})
})
this.xg.on('exitFullscreen', () => {
document.querySelector('.xg-view-videoTitle').style.display = 'none'
})
}
},
created () {
@@ -644,18 +945,184 @@ export default {
this.mtEvent()
},
mounted () {
console.log(this)
Player.install('playPrev', function () {
addPlayerBtn.bind(this, 'playPrev', '<svg t="1595866093990" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3657" style="width: 20px;height: 20px;margin-top: 11px;margin-left: 9px;" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M98.583851 3.180124h190.807453a31.801242 31.801242 0 0 1 31.801243 31.801242v387.021118L902.201242 10.176398l11.130435-7.632299A31.801242 31.801242 0 0 1 957.217391 31.801242v960.397516a31.801242 31.801242 0 0 1-43.885714 29.257143l-11.130435-7.632299L321.192547 601.997516V989.018634a31.801242 31.801242 0 0 1-31.801243 31.801242H98.583851a31.801242 31.801242 0 0 1-31.801242-31.801242v-954.037268a31.801242 31.801242 0 0 1 31.801242-31.801242z" p-id="3658" fill="#ffffff"></path></svg>', { title: '上一集' })()
})
Player.install('playNextOne', function () {
addPlayerBtn.bind(this, 'playNextOne', '<svg t="1595866110378" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3946" style="width: 20px;height: 20px;margin-top: 11px;margin-left: 0px;" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M925.416149 3.180124h-190.807453a31.801242 31.801242 0 0 0-31.801243 31.801242v387.021118L121.798758 10.176398 110.668323 2.544099A31.801242 31.801242 0 0 0 98.583851 0a31.801242 31.801242 0 0 0-31.801242 31.801242v960.397516a31.801242 31.801242 0 0 0 31.801242 31.801242 31.801242 31.801242 0 0 0 12.084472-2.544099l11.130435-7.632299L702.807453 601.997516V989.018634a31.801242 31.801242 0 0 0 31.801243 31.801242h190.807453a31.801242 31.801242 0 0 0 31.801242-31.801242v-954.037268a31.801242 31.801242 0 0 0-31.801242-31.801242z" p-id="3947" fill="#ffffff"></path></svg>', { title: '下一集' })()
})
Player.install('showList', function () {
addPlayerBtn.bind(this, 'showList', '<svg t="1595866128681" class="icon" viewBox="0 0 1316 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4187" style="width: 22px;height: 22px;margin-top: 9px;margin-left: 6px;" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M0 0h1316.571429v146.285714H0zM0 438.857143h1316.571429v146.285714H0zM0 877.714286h1316.571429v146.285714H0z" p-id="4188" fill="#ffffff"></path></svg>', { title: '播放列表' })()
})
Player.install('showHistory', function () {
addPlayerBtn.bind(this, 'showHistory', '<svg t="1595866015473" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3282" style="width: 22px;height: 22px;margin-top: 9px;margin-left: 6px;" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M512 0a512 512 0 1 0 512 512A512 512 0 0 0 512 0z m0 910.222222a398.222222 398.222222 0 1 1 398.222222-398.222222 398.222222 398.222222 0 0 1-398.222222 398.222222z" p-id="3283" fill="#ffffff"></path><path d="M568.888889 227.555556h-113.777778v341.333333h227.555556v-113.777778h-113.777778V227.555556z" p-id="3284" fill="#ffffff"></path></svg>', { title: '播放历史' })()
})
const that = this
Player.install('videoTitle', function () {
let title
if (that.right.list.length > 1) {
title = `『第 ${that.video.info.index + 1} 集』${that.name}`
} else {
title = `${that.name}`
}
addPlayerView.bind(this, 'videoTitle', `<span>${title}</span>`, {})()
})
this.xg = new Hls(this.config)
ipcRenderer.on('miniClosed', () => {
this.xg.destroy()
this.xg = new Hls(this.config)
this.getUrls()
// this.xg.destroy()
// this.xg = new Hls(this.config)
// this.bindEvent()
// 同步进度
history.find({ site: this.video.key, ids: this.video.info.id }).then(res => {
if (res) {
if (this.video.info.index !== res.index) {
this.video.info.index = res.index
} else {
this.getUrls()
}
}
})
})
this.bindEvent()
},
beforeDestroy () {
clearInterval(this.timer)
}
}
</script>
<style>
.xgplayer-skin-default .xg-btn-playPrev {
width: 32px;
position: relative;
-webkit-order: 0;
-moz-box-ordinal-group: 1;
order: 0;
display: block;
cursor: pointer;
margin-left: 3px;
}
.xgplayer-skin-default .xg-btn-playPrev:hover {
opacity: 0.8;
}
.xgplayer-skin-default .xg-btn-playNextOne {
width: 32px;
position: relative;
-webkit-order: 2;
-moz-box-ordinal-group: 1;
order: 2;
display: block;
cursor: pointer;
margin-left: 3px;
}
.xgplayer-skin-default .xg-btn-playNextOne:hover {
opacity: 0.8;
}
.xgplayer-skin-default .xgplayer-play, .xgplayer-skin-default .xgplayer-play-img {
order: 1 !important;
}
.xgplayer-skin-default .xg-btn-showList {
width: 32px;
position: relative;
-webkit-order: 4;
-moz-box-ordinal-group: 1;
order: 4;
display: block;
cursor: pointer;
margin-right: 3px;
}
.xgplayer-skin-default .xg-btn-showList:hover {
opacity: 0.8;
}
.xgplayer-skin-default .xg-btn-showHistory {
width: 32px;
position: relative;
-webkit-order: 4;
-moz-box-ordinal-group: 1;
order: 4;
display: block;
cursor: pointer;
margin-right: 3px;
}
.xgplayer-skin-default .xg-btn-showHistory:hover {
opacity: 0.8;
}
.xgplayer-skin-default .xg-btn-showList ul, .xgplayer-skin-default .xg-btn-showHistory ul {
display: none;
list-style: none;
min-width: 85px;
max-width: 300px;
max-height: 60vh;
overflow-y: scroll;
background: rgba(0,0,0,.54);
border-radius: 1px;
position: absolute;
bottom: 45px;
left: 50%;
-webkit-transform: translateX(-50%);
-ms-transform: translateX(-50%);
transform: translateX(-50%);
text-align: left;
white-space: nowrap;
z-index: 26;
cursor: pointer;
}
.xgplayer-skin-default .xg-btn-showList ul li, .xgplayer-skin-default .xg-btn-showHistory ul li {
opacity: .7;
font-family: PingFangSC-Regular;
font-size: 13px;
color: hsla(0,0%,100%,.8);
position: relative;
padding: 5px;
text-align: center;
}
.xgplayer-skin-default .xg-btn-showList ul li:first-child, .xgplayer-skin-default .xg-btn-showHistory ul li:first-child {
position: relative;
margin-top: 12px;
}
.xgplayer-skin-default .xg-btn-showList ul li:last-child, .xgplayer-skin-default .xg-btn-showHistory ul li:last-child {
margin-bottom: 12px;
}
.xgplayer-skin-default .xg-btn-showList ul li.selected, .xgplayer-skin-default .xg-btn-showHistory ul li.selected, .xgplayer-skin-default .xg-btn-showList ul li:hover, .xgplayer-skin-default .xg-btn-showHistory ul li:hover {
color: #fff;
opacity: 1;
}
.xgplayer-skin-default .xgplayer-volume {
width: 32px !important;
}
.xgplayer-skin-default .xgplayer-playbackrate {
width: 40px !important;
}
.xgplayer-skin-default .xgplayer-playbackrate .name {
top: 10px !important;
}
.xgplayer-skin-default .xgplayer-playbackrate ul {
bottom: 25px;
}
.xgplayer-skin-default .xgplayer-playbackrate ul li {
font-size: 13px !important;
}
.xgplayer-skin-default .xgplayer-screenshot .name span {
width: 40px !important;
}
.xgplayer-skin-default .xg-view-videoTitle {
display: none;
position: absolute;
top: 0;
left: 0;
right: 0;
height: 40px;
padding-left: 10px;
background-image: linear-gradient(180deg,rgba(0,0,0,.75),rgba(0,0,0,.75),rgba(0,0,0,.37),transparent);
z-index: 10;
}
.xgplayer-skin-default .xg-view-videoTitle span {
font-size: 16px;
line-height: 40px;
color: #ffffff;
}
</style>
<style lang="scss" scoped>
.play{
position: relative;

View File

@@ -207,7 +207,9 @@ export default {
this.$message.success('已添加成功')
this.getSites()
this.d.site = json[0].key
this.setting = this.d
setting.update(this.d).then(res => {
this.setting = this.d
})
})
})
},

View File

@@ -1,9 +1,9 @@
<template>
<div class="share" id="share" @click="shareClickEvent">
<div class="left">
<img :src="pic" alt="">
<img :src="pic" alt="" @load="picLoadEvent">
</div>
<div class="right">
<div class="right" id="right">
<div class="title">{{ share.info.name }}</div>
<qrcode-vue id="qr" :value="link" :size="160" level="L" />
<div class="tips">
@@ -79,17 +79,17 @@ export default {
}
}
this.loading = false
this.$nextTick(() => {
const dom = document.getElementById('share')
html2canvas(dom, { useCORS: true, allowTaint: true }).then(res => {
const png = res.toDataURL('image/png')
const p = nativeImage.createFromDataURL(png)
clipboard.writeImage(p)
this.$message.success('已复制到剪贴板,快去分享吧~ 严禁传播违法资源!!!')
})
})
}
})
},
picLoadEvent () {
const dom = document.getElementById('right')
html2canvas(dom, { useCORS: true, allowTaint: true }).then(res => {
const png = res.toDataURL('image/png')
const p = nativeImage.createFromDataURL(png)
clipboard.writeImage(p)
this.$message.success('已复制到剪贴板,快去分享吧~ 严禁传播违法资源!!!')
})
}
},
mounted () {
@@ -108,7 +108,7 @@ export default {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px;
padding: 0px;
z-index: 999;
.left, .right{
width: 50%;
@@ -125,6 +125,7 @@ export default {
}
}
.right{
padding: 10px;
.title{
font-size: 18px;
margin-bottom: 10px;

View File

@@ -80,7 +80,10 @@ export default {
this.detail = {
show: true,
key: e.site,
info: e
info: {
id: e.ids,
name: e.name
}
}
},
playEvent (e) {

View File

@@ -5,7 +5,7 @@ const Axios = require('axios')
const app = express()
app.use(cors())
app.use(express.json())
app.use(express.urlencoded())
app.use(express.urlencoded({ extended: true }))
app.post('/api', async (req, res) => {
const result = await Axios.get(req.body.url)
@@ -15,4 +15,4 @@ app.post('/api', async (req, res) => {
})
})
app.listen(48484)
app.listen(44444)

View File

@@ -2,7 +2,7 @@ import { sites } from '../dexie'
import axios from 'axios'
import parser from 'fast-xml-parser'
const zy = {
ports: 48484, // 端口号
ports: 44444, // 端口号
xmlConfig: { // XML 转 JSON 配置
trimValues: true,
textNodeName: '_t',
@@ -184,7 +184,7 @@ const zy = {
reject(err)
})
} else {
resolve(null)
resolve([])
}
})
})

View File

@@ -22,8 +22,15 @@
<span class="progress" v-show="progress > 0">播放进度: {{progress}}%</span>
</div>
<div class="right">
<span class="min" @click="frameClickEvent('min')"></span>
<span class="close" @click="frameClickEvent('close')"></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:10px;height:16px"><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="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:10px;height:16px"><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>
<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:12px;height:16px"><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>
</div>
</div>
<div class="bottom">
@@ -38,9 +45,11 @@ 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: {
@@ -65,7 +74,8 @@ export default {
detail: {},
m3u8Arr: [],
rate: 1,
progress: 0
progress: 0,
isAlwaysOnTop: win.isAlwaysOnTop()
}
},
methods: {
@@ -79,6 +89,11 @@ export default {
ipcRenderer.send('win')
return false
}
if (e === 'top') {
this.isAlwaysOnTop = !this.isAlwaysOnTop
const win = remote.getCurrentWindow()
win.setAlwaysOnTop(this.isAlwaysOnTop)
}
},
opacityChange (val) {
const win = remote.getCurrentWindow()
@@ -89,10 +104,88 @@ export default {
getUrls () {
mini.find().then(res => {
this.video = res
zy.detail(res.site, res.ids).then(e => {
this.name = e.name
this.detail = e
const dd = e.dl.dd
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()
}
})
})
// zy.detail(res.site, res.ids).then(e => {
// this.name = e.name
// this.detail = e
// const dd = e.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])
// }
// }
// 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]') {
@@ -117,25 +210,12 @@ export default {
m3u8Arr.push(j[0])
}
}
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()
VIDEO_DETAIL_CACHE[cacheKey] = {
list: m3u8Arr,
name: res.name
}
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()
}
})
resolve(m3u8Arr)
})
})
},
@@ -177,6 +257,7 @@ export default {
},
prevEvent () {
if (this.video.index === 0) {
this.$message.info('已是第一集.')
return false
}
history.find({ site: this.video.site, ids: this.video.ids }).then(res => {
@@ -192,6 +273,7 @@ export default {
},
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 => {
@@ -284,8 +366,10 @@ export default {
return false
}
if (e === 'escape') {
this.xg.exitFullscreen()
this.xg.exitCssFullscreen()
if (this.xg.fullscreen) {
this.xg.exitFullscreen()
this.xg.exitCssFullscreen()
}
return false
}
if (e === 'next') {
@@ -351,12 +435,10 @@ export default {
}
}
},
created () {
this.getUrls()
this.mtEvent()
},
mounted () {
this.xg = new Hls(this.config)
this.mtEvent()
this.getUrls()
},
beforeDestroy () {
clearInterval(this.timer)
@@ -427,6 +509,8 @@ html,body{
display: inline-block;
width: 16px;
height: 16px;
text-align: center;
line-height: 16px;
border-radius: 50%;
margin-right: 10px;
cursor: pointer;
@@ -437,6 +521,9 @@ html,body{
&.close{
background-color: #ff5f56;
}
&.top{
background-color: #f3bab7;
}
&:hover{
animation: heartbeat 3s ease-in-out infinite both;
}

View File

@@ -9918,16 +9918,16 @@ xdg-basedir@^4.0.0:
xgplayer-hls.js@^2.2.3:
version "2.2.3"
resolved "https://registry.npmjs.org/xgplayer-hls.js/-/xgplayer-hls.js-2.2.3.tgz#bf538911145346c447528d609fc95dd267a24d81"
resolved "https://registry.yarnpkg.com/xgplayer-hls.js/-/xgplayer-hls.js-2.2.3.tgz#bf538911145346c447528d609fc95dd267a24d81"
integrity sha512-CFsZanBHHRbqTmqYCFFONk76oWwJwbn+8LK/XkwBBrUrqGPQPmrXfjelGjKDDGfZ+w3xReC1nGom3IpN+lLoaQ==
dependencies:
deepmerge "2.0.1"
event-emitter "^0.3.5"
xgplayer@^2.9.8:
version "2.9.8"
resolved "https://registry.npmjs.org/xgplayer/-/xgplayer-2.9.8.tgz#ce6646f8ef99594ca9414449f83f816320c4ec83"
integrity sha512-MICegbLRMNdOa9kRcsY5BVfwKmwvO+quJST/ejSJngdvDrB4E9dX53zhL3OT6KH4n9aCifl5qCYzTRWD6qH22w==
xgplayer@^2.9.10:
version "2.9.10"
resolved "https://registry.yarnpkg.com/xgplayer/-/xgplayer-2.9.10.tgz#4e79b889621f829b773c118ab93da55f829d4490"
integrity sha512-5a7Xm0AY8qPRXZFxrPRErjzCERsENaskQ8Fq5Sy4ht13TMzYp0VIRREU7XF8efpJGcPsOOuFlCiMrqSpYEIAUA==
dependencies:
chalk "^2.3.2"
commander "^2.15.1"