diff --git a/src/components/HlsPlayer.vue b/src/components/HlsPlayer.vue index 52853d8..e2d1b9d 100644 --- a/src/components/HlsPlayer.vue +++ b/src/components/HlsPlayer.vue @@ -51,6 +51,9 @@ export default { } else { const hls = new Hls(); this.hls = hls; + hls.on(Hls.Events.ERROR, (event, data) => { + this.$emit('hls-error', event, data); + }); hls.loadSource(this.source); hls.attachMedia(this.video); this.$once('hook:beforeDestroy', () => { diff --git a/src/layouts/Home.vue b/src/layouts/Home.vue index b6f15df..121aff3 100644 --- a/src/layouts/Home.vue +++ b/src/layouts/Home.vue @@ -132,8 +132,13 @@ import titleBar from 'components/titlebar'; import { mapState, mapMutations, mapGetters } from 'vuex'; import util from 'util'; +import isAbsoluteUrl from 'is-absolute-url'; import { parseString } from 'xml2js'; +import { URL } from 'url'; +import path from 'path'; +import { stringify } from 'query-string'; + const Store = require('electron-store'); const store = new Store(); @@ -232,8 +237,50 @@ export default { this.setCurrentVideo(video); this.$router.push('/video'); }, + directVideo() { + const { BrowserWindow, getCurrentWindow } = this.$q.electron.remote; + const videoInfo = JSON.stringify({ + url: this.keyWord, + }); + const encodeUrl = stringify({ video: videoInfo }); + const parentWindow = getCurrentWindow(); + const win = new BrowserWindow({ + width: 800, + height: 600, + useContentSize: true, + webPreferences: { + nodeIntegration: true, + webSecurity: false, + }, + parent: parentWindow, + }); + win.removeMenu(); + win.loadURL(`${process.env.APP_URL}#/direct-video?${encodeUrl}`); + }, search() { - this.$store.commit('setKeyWord', this.keyWord); + if (isAbsoluteUrl(this.keyWord)) { + try { + const url = new URL(this.keyWord); + const { pathname } = url; + const extname = path.extname(pathname); + if (extname === '.m3u8') { + this.$q.dialog({ + title: '播放', + message: '检测到搜索参数是hls流链接,是否播放', + cancel: true, + persistent: true, + }).onOk(() => { + this.directVideo(); + }).onCancel(() => { + this.$store.commit('setKeyWord', this.keyWord); + }); + } + } catch (error) { + console.error(error); + } + } else { + this.$store.commit('setKeyWord', this.keyWord); + } }, }, computed: { diff --git a/src/pages/directVideo.vue b/src/pages/directVideo.vue new file mode 100644 index 0000000..1ae8e5f --- /dev/null +++ b/src/pages/directVideo.vue @@ -0,0 +1,74 @@ + + + + + diff --git a/src/router/routes.js b/src/router/routes.js index 342db62..abfc0e1 100644 --- a/src/router/routes.js +++ b/src/router/routes.js @@ -16,6 +16,11 @@ const routes = [ component: () => import('layouts/Mini'), children: [{ path: '', component: () => import('pages/MiniVideo') }], }, + { + path: '/direct-video', + component: () => import('layouts/Mini'), + children: [{ path: '', component: () => import('pages/directVideo') }], + }, { path: '/config', component: () => import('layouts/Config'),