Compare commits

...

12 Commits

Author SHA1 Message Date
hunlongyu
203d2c19fd 😂 Mini 窗口支持倍速快捷键 2020-05-25 22:31:10 +08:00
hunlongyu
0ed25643fc 😅 升级依赖 2020-05-25 22:04:18 +08:00
hunlongyu
ba99e65bcb 😅 新增快捷键视频倍速 2020-05-25 22:00:23 +08:00
hunlongyu
169b28ab33 💦 播放速度 2020-05-25 18:23:03 +08:00
hunlongyu
cbcffd7587 😣x86 fail 2020-05-24 14:57:39 +08:00
hunlongyu
fc26c04666 🤨 x86 2020-05-24 14:29:20 +08:00
hunlongyu
e2cda9a100 😃 优化样式 2020-05-24 14:11:14 +08:00
hunlongyu
ffe432d19e 🧡 新增友情链接 2020-05-21 14:27:39 +08:00
hunlongyu
ae31e9ba74 💦 更新挂掉的图片 2020-05-20 14:29:33 +08:00
hunlongyu
24f78563b6 ☯ 新增快捷键说明 2020-05-20 14:00:56 +08:00
hunlongyu
8c0e35e766 🎎 新增全局监听 2020-05-20 11:39:46 +08:00
hunlongyu
f94d00e36c 😂 官网链接 2020-05-18 09:47:11 +08:00
15 changed files with 2073 additions and 1821 deletions

View File

@@ -24,4 +24,4 @@ jobs:
yarn release
shell: pwsh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -2,8 +2,8 @@
<img width="128" src="https://i.loli.net/2020/05/07/9kLvPnWVCp7538c.png" >
</p>
<p align="center">
<a src="http://zyplayer.fun/" target="_blank">官网</a>
<a src="https://github.com/Hunlongyu/ZY-Player/issues" target="_blank">反馈</a>
<a href="http://zyplayer.fun/" target="_blank">官网</a>
<a href="https://github.com/Hunlongyu/ZY-Player/issues" target="_blank">反馈</a>
</p>
<p align="center">
<img src="https://forthebadge.com/images/badges/built-with-love.svg">
@@ -35,9 +35,23 @@
9. 更详细的视频分类
10. 收藏夹同步更新视频追剧.(手动更新)
11. 后台自动更新
12. 全局快捷键
13. 支持演员名称搜索
14. ...
觉得软件不错的, 点击右上角 star 收藏关注一波呀~
<img height="30" src="https://i.loli.net/2020/05/09/cNnvGobekWEqfjZ.jpg">
#### 全局快捷键:
| 快捷键 | 说明 | 主界面 | 小窗口 |
| :----------------------: | ---------- | :----: | :----: |
| `⌘ + ➡``Ctrl + ➡` | 下一集 | √ | √ |
| `⌘ + ⬅``Ctrl + ⬅` | 上一集 | √ | √ |
| `⌘ + ⬆``Ctrl + ⬆` | 减少透明度 | | √ |
| `⌘ + ⬇``Ctrl + ⬇` | 增加透明度 | | √ |
| `Shift + ⬆` | 减少透明度 | √ | √ |
| `Shift + ⬇` | 增加透明度 | √ | √ |
#### 下载:
@@ -49,7 +63,7 @@
1. 浏览 ⇣ ↓
![01浏览.png](https://i.loli.net/2020/05/18/MshDLnXq2CTpoBy.png)
2. 搜索 ⇣ ↓
![02搜索.png](https://i.loli.net/2020/05/18/kAKQpLeRJUID5d6.png)
![02搜索.png](https://i.loli.net/2020/05/20/QgJqDkcjpeiRvBb.png)
3. 详情 ⇣ ↓
![03详情.png](https://i.loli.net/2020/05/18/s7gUj6unEfyYb4Z.png)
4. 播放 ⇣ ↓

View File

@@ -233,7 +233,7 @@
<h4>友情链接</h4>
<ul>
<li><i class="bx bx-chevron-right"></i> <a target="_blank" href="#">Home</a></li>
<li><i class="bx bx-chevron-right"></i> <a target="_blank" href="https://github.com/Hunlongyu/ZY-Player">Github</a></li>
<li><i class="bx bx-chevron-right"></i> <a target="_blank" href="https://www.ghpym.com/zyplayer.html">果核剥壳</a></li>
</ul>
</div>

View File

@@ -1,6 +1,6 @@
{
"name": "zy",
"version": "1.0.1",
"version": "1.0.10",
"private": true,
"author": {
"name": "Hunlongyu",
@@ -23,17 +23,17 @@
"axios": "^0.19.2",
"core-js": "^3.6.5",
"dexie": "^2.0.4",
"electron-updater": "^4.2.5",
"element-ui": "^2.13.1",
"electron-updater": "^4.3.1",
"element-ui": "^2.13.2",
"html2canvas": "^1.0.0-rc.5",
"leancloud-storage": "^4.5.3",
"macaddress": "^0.2.9",
"macaddress": "^0.5.1",
"modern-normalize": "^0.6.0",
"qrcode.vue": "^1.7.0",
"vue": "^2.6.11",
"vue-i18n": "^8.17.0",
"vuex": "^3.1.3",
"xgplayer": "^2.6.24",
"vue-i18n": "^8.17.7",
"vuex": "^3.4.0",
"xgplayer": "^2.7.1",
"xgplayer-hls.js": "^2.2.2"
},
"devDependencies": {
@@ -44,7 +44,7 @@
"@vue/eslint-config-standard": "^5.1.2",
"babel-eslint": "^10.1.0",
"babel-plugin-component": "^1.1.1",
"electron": "^8.3.0",
"electron": "^9.0.0",
"eslint": "^6.7.2",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-node": "^11.1.0",

View File

@@ -93,7 +93,7 @@
width: 120px;
}
&.operate{
width: 120px;
width: 170px;
}
}
}
@@ -133,7 +133,7 @@
width: 120px;
}
&.operate{
width: 120px;
width: 170px;
}
}
}

View File

@@ -8,6 +8,7 @@ import {
import path from 'path'
import { autoUpdater } from 'electron-updater'
const isDevelopment = process.env.NODE_ENV !== 'production'
const globalShortcut = require('electron').globalShortcut
let win
let mini
@@ -20,7 +21,7 @@ function createWindow () {
width: 1080,
height: 720,
frame: false,
resizable: false,
resizable: true,
transparent: true,
webPreferences: {
webSecurity: false,
@@ -74,6 +75,7 @@ function createMini () {
}
app.allowRendererProcessReuse = true
app.commandLine.appendSwitch('disable-features', 'OutOfBlinkCors')
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
@@ -126,6 +128,48 @@ if (!gotTheLock) {
// 创建 win, 加载应用的其余部分, etc...
app.on('ready', () => {
globalShortcut.register('CommandOrControl+right', function () {
if (win) {
win.webContents.send('next', 0)
}
if (mini) {
mini.webContents.send('next', 0)
}
})
globalShortcut.register('CommandOrControl+left', function () {
if (win) {
win.webContents.send('prev', 0)
}
if (mini) {
mini.webContents.send('prev', 0)
}
})
globalShortcut.register('CommandOrControl+up', function () {
if (mini) {
mini.webContents.send('up', 0)
}
})
globalShortcut.register('CommandOrControl+down', function () {
if (mini) {
mini.webContents.send('down', 0)
}
})
globalShortcut.register('shift+up', function () {
if (win) {
win.webContents.send('playbackRateUp', 0)
}
if (mini) {
mini.webContents.send('playbackRateUp', 0)
}
})
globalShortcut.register('shift+down', function () {
if (win) {
win.webContents.send('playbackRateDown', 0)
}
if (mini) {
mini.webContents.send('playbackRateDown', 0)
}
})
if (!process.env.WEBPACK_DEV_SERVER_URL) {
createProtocol('app')
}

View File

@@ -136,10 +136,10 @@ export default {
left: 0;
bottom: 0;
width: 100%;
height: 680px;
height: calc(100% - 40px);
z-index: 999;
.detail-content{
height: 680px;
height: calc(100% - 10px);
padding: 0 60px;
position: relative;
.detail-header{
@@ -157,14 +157,14 @@ export default {
}
}
.detail-body{
height: 630px;
height: calc(100% - 50px);
overflow-y: auto;
.info{
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: wrap;
width: 955px;
width: 100%;
padding: 10px;
border: 1px solid;
border-radius: 2px;
@@ -256,7 +256,7 @@ export default {
.desc{
border: 1px solid;
padding: 10px;
width: 955px;
width: 100%;
margin-bottom: 10px;
border-radius: 2px;
font-size: 14px;
@@ -265,7 +265,7 @@ export default {
.m3u8_urls, .mp4_urls{
border: 1px solid;
padding: 10px;
width: 955px;
width: 100%;
margin-bottom: 10px;
border-radius: 2px;
.title{
@@ -295,10 +295,11 @@ export default {
}
}
.detail-mask{
width: 980px;
height: 600px;
position: absolute;
top: 50px;
left: 0;
width: 100%;
height: calc(100 - 50px);
display: flex;
justify-content: center;
align-items: center;

View File

@@ -59,6 +59,7 @@
<span class="btn" @click.stop="playEvent(i)">{{$t('play')}}</span>
<span class="btn" @click.stop="starEvent(i)">{{$t('star')}}</span>
<span class="btn" @click.stop="shareEvent(i)">{{$t('share')}}</span>
<span class="btn" @click.stop="downloadEvent(i)">{{$t('download')}}</span>
</span>
</li>
</ul>
@@ -80,6 +81,7 @@ import { sites, getSite } from '../lib/site/sites'
import tools from '../lib/site/tools'
import video from '../lib/dexie/video'
import setting from '../lib/dexie/setting'
const { clipboard } = require('electron')
export default {
name: 'film',
data () {
@@ -261,6 +263,33 @@ export default {
v: e
}
},
downloadEvent (e) {
tools.detail_get(e.site, e.detail).then(res => {
if (res.mp4_urls.length > 0) {
const urls = [...res.mp4_urls]
let txt = `${e.name}\n`
for (const i of urls) {
const name = i.split('$')[0]
const url = encodeURI(i.split('$')[1])
txt += (name + ': ' + url + '\n')
}
clipboard.writeText(txt)
this.$m.success('〖MP4〗: ' + this.$t('copy_success'))
return false
}
if (res.m3u8_urls.length > 0) {
const urls = [...res.m3u8_urls]
let txt = `${e.name}\n`
for (const i of urls) {
const name = i.split('$')[0]
const url = encodeURI(i.split('$')[1])
txt += (name + ': ' + url + '\n')
}
clipboard.writeText(txt)
this.$m.success('〖M3U8〗: ' + this.$t('copy_success'))
}
})
},
tbPageChange (e) {
this.tb.loading = true
this.tb.page = e
@@ -277,7 +306,7 @@ export default {
</script>
<style lang="scss" scoped>
.film{
height: 670px;
height: calc(100% - 40px);
width: 100%;
display: flex;
flex-direction: column;
@@ -323,7 +352,7 @@ export default {
}
}
.middle{
height: 620px;
height: calc(100% - 40px);
width: 100%;
margin-top: 10px;
padding-bottom: 0px;

View File

@@ -1,7 +1,8 @@
<template>
<div class="play">
<div class="box">
<div class="title">{{name}}</div>
<div class="title" v-if="length === 1">{{name}}</div>
<div class="title" v-if="length > 1"> {{(video.index + 1)}} {{name}}</div>
<div class="xgBox">
<div id="xg"></div>
</div>
@@ -136,6 +137,7 @@ export default {
playbackRate: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 3, 4, 5]
},
name: '',
length: 0,
timer: null,
scroll: false,
more: true,
@@ -217,11 +219,13 @@ export default {
for (const i of m3) {
arr.push(i.split('$')[1])
}
this.length = arr.length
this.xg.src = arr[this.video.index]
this.showNext = true
} else {
const link = res.m3u8_urls[this.video.index]
const src = link.split('$')[1]
this.length = 1
this.xg.src = src
this.showNext = false
}
@@ -308,6 +312,16 @@ export default {
this.$m.warning(this.$t('last_video'))
}
},
prevEvent () {
const v = { ...this.video }
const i = v.index - 1
if (i > 0) {
this.video.currentTime = 0
this.video.index--
} else {
this.$m.warning(this.$t('first_video'))
}
},
listEvent () {
if (this.right.type === 'list') {
this.right.show = false
@@ -397,6 +411,14 @@ export default {
this.right.historyData = e.reverse()
})
})
},
playbackRateEvent (e) {
let rate = this.xg.playbackRate
if (rate > 0.25) {
rate = rate + e
this.xg.playbackRate = rate
this.$m.success(this.$t('rate') + rate)
}
}
},
mounted () {
@@ -404,13 +426,41 @@ export default {
history.all().then(res => {
this.right.historyData = res
})
ipc.on('next', () => {
if (this.xg) {
if (this.xg.hasStart) {
this.nextEvent()
}
}
})
ipc.on('prev', () => {
if (this.xg) {
if (this.xg.hasStart) {
this.prevEvent()
}
}
})
ipc.on('playbackRateUp', () => {
if (this.xg) {
if (this.xg.hasStart) {
this.playbackRateEvent(0.25)
}
}
})
ipc.on('playbackRateDown', () => {
if (this.xg) {
if (this.xg.hasStart) {
this.playbackRateEvent(-0.25)
}
}
})
}
}
</script>
<style lang="scss" scoped>
.play{
position: relative;
height: 660px;
height: calc(100% - 40px);
width: 100%;
display: flex;
justify-content: center;

View File

@@ -174,7 +174,7 @@ export default {
</script>
<style lang="scss" scoped>
.setting{
height: 660px;
height: calc(100% - 40px);
width: 100%;
padding: 20px 0;
.setting-box{

View File

@@ -6,7 +6,7 @@
<span class="type">{{$t('type')}}</span>
<span class="time">{{$t('time')}}</span>
<span class="from">{{$t('from')}}</span>
<span class="operate" style="width: 170px">{{$t('operate')}}</span>
<span class="operate" style="width: 220px">{{$t('operate')}}</span>
</div>
<div class="tBody zy-scroll">
<ul v-show="!loading">
@@ -15,11 +15,12 @@
<span class="type">{{i.type}}</span>
<span class="time">{{i.time}}</span>
<span class="from">{{i.site | ftSite}}</span>
<span class="operate" style="width: 170px">
<span class="operate" style="width: 220px">
<span class="btn" @click.stop="playEvent(i)">{{$t('play')}}</span>
<span class="btn" @click.stop="deleteEvent(i)">{{$t('delete')}}</span>
<span class="btn" @click.stop="shareEvent(i)">{{$t('share')}}</span>
<span class="btn" @click.stop="updateEvent(i)">{{$t('sync')}}</span>
<span class="btn" @click.stop="downloadEvent(i)">{{$t('download')}}</span>
</span>
</li>
</ul>
@@ -38,6 +39,7 @@ import { mapMutations } from 'vuex'
import tools from '../lib/site/tools'
import video from '../lib/dexie/video'
import { sites, getSite } from '../lib/site/sites'
const { clipboard } = require('electron')
export default {
name: 'star',
data () {
@@ -136,6 +138,33 @@ export default {
}
})
},
downloadEvent (e) {
tools.detail_get(e.site, e.detail).then(res => {
if (res.mp4_urls.length > 0) {
const urls = [...res.mp4_urls]
let txt = `${e.name}\n`
for (const i of urls) {
const name = i.split('$')[0]
const url = encodeURI(i.split('$')[1])
txt += (name + ': ' + url + '\n')
}
clipboard.writeText(txt)
this.$m.success('〖MP4〗: ' + this.$t('copy_success'))
return false
}
if (res.m3u8_urls.length > 0) {
const urls = [...res.m3u8_urls]
let txt = `${e.name}\n`
for (const i of urls) {
const name = i.split('$')[0]
const url = encodeURI(i.split('$')[1])
txt += (name + ': ' + url + '\n')
}
clipboard.writeText(txt)
this.$m.success('〖M3U8〗: ' + this.$t('copy_success'))
}
})
},
getAllStar () {
video.all().then(res => {
this.data = res.reverse()
@@ -150,7 +179,7 @@ export default {
</script>
<style lang="scss" scoped>
.star{
height: 660px;
height: calc(100% - 40px);
width: 100%;
display: flex;
flex-direction: column;

View File

@@ -36,6 +36,7 @@
"delete_success": "Delete successful.",
"delete_failed": "Delete failed.",
"star_success": "Collection success.",
"first_video": "This is the first episode.",
"last_video": "This is the last episode.",
"qr_tips": "Long click recognition.",
"zy_tips": "Prohibit the dissemination of illegal resources.",
@@ -46,5 +47,6 @@
"async_success": "Synchronization succeeded, update found.",
"no_history": "No history data.",
"clearDB": "Reset software",
"clearTips": "Click to clear the database and close the software"
"clearTips": "Click to clear the database and close the software",
"rate": "The current video speed is: "
}

View File

@@ -36,6 +36,7 @@
"delete_success": "删除成功。",
"delete_failed": "删除失败。",
"star_success": "收藏成功。",
"first_video": "这已经是第一集了。",
"last_video": "这已经是最后一集了。",
"qr_tips": "长按二维码,识别播放。",
"zy_tips": "『ZY Player』技术支持严禁传播违法资源。",
@@ -46,5 +47,6 @@
"async_success": "同步成功, 查询到更新。",
"no_history": "无历史记录",
"clearDB": "重置软件",
"clearTips": "软件没有问题,请勿重置软件,否则数据丢失概不负责.点击即清空数据库,并关闭软件."
"clearTips": "软件没有问题,请勿重置软件,否则数据丢失概不负责.点击即清空数据库,并关闭软件.",
"rate": "当前视频播放倍速为:"
}

View File

@@ -130,6 +130,9 @@ export default {
}, 10000)
},
prevEvent () {
if (this.index === 0) {
return false
}
history.find({ detail: this.video.detail }).then(res => {
const v = res
v.index--
@@ -144,6 +147,9 @@ export default {
})
},
nextEvent () {
if (this.index >= this.d.m3u8_urls.length - 1) {
return false
}
history.find({ detail: this.video.detail }).then(res => {
const v = res
v.index++
@@ -156,6 +162,13 @@ export default {
this.index++
})
})
},
playbackRateEvent (e) {
let rate = this.xg.playbackRate
if (rate > 0.25) {
rate = rate + e
this.xg.playbackRate = rate
}
}
},
created () {
@@ -163,6 +176,46 @@ export default {
},
mounted () {
this.xg = new Hls(this.config)
ipc.on('next', () => {
if (this.xg) {
if (this.xg.hasStart) {
this.nextEvent()
}
}
})
ipc.on('prev', () => {
if (this.xg) {
if (this.xg.hasStart) {
this.prevEvent()
}
}
})
ipc.on('up', () => {
if (this.opacity <= 95) {
this.opacity = this.opacity + 5
this.opacityChange(this.opacity)
}
})
ipc.on('down', () => {
if (this.opacity >= 10) {
this.opacity = this.opacity - 5
this.opacityChange(this.opacity)
}
})
ipc.on('playbackRateUp', () => {
if (this.xg) {
if (this.xg.hasStart) {
this.playbackRateEvent(0.25)
}
}
})
ipc.on('playbackRateDown', () => {
if (this.xg) {
if (this.xg.hasStart) {
this.playbackRateEvent(-0.25)
}
}
})
}
}
</script>

3600
yarn.lock

File diff suppressed because it is too large Load Diff