├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── .postcssrc.js ├── .prettierrc ├── .stylintrc ├── .travis.yml ├── LICENSE ├── README.md ├── babel.config.js ├── package.json ├── quasar.conf.js ├── screenshot ├── download-sorce.gif ├── download.gif ├── import-source.gif └── unzip.gif ├── src-electron ├── icons │ ├── icon.icns │ ├── icon.ico │ ├── icons │ │ ├── mac │ │ │ └── icon.icns │ │ ├── png │ │ │ ├── 1024x1024.png │ │ │ ├── 128x128.png │ │ │ ├── 16x16.png │ │ │ ├── 24x24.png │ │ │ ├── 256x256.png │ │ │ ├── 32x32.png │ │ │ ├── 48x48.png │ │ │ ├── 512x512.png │ │ │ └── 64x64.png │ │ └── win │ │ │ └── icon.ico │ └── linux-512x512.png └── main-process │ ├── electron-main.dev.js │ └── electron-main.js ├── src ├── App.vue ├── api │ ├── promise │ │ ├── maccms-v10.d.ts │ │ ├── maccms-v10.js │ │ ├── maccms-v8.d.ts │ │ └── maccms-v8.js │ └── rx │ │ ├── maccms-v10.d.ts │ │ ├── maccms-v10.js │ │ ├── maccms-v8.d.ts │ │ └── maccms-v8.js ├── assets │ ├── quasar-logo-full.svg │ └── sad.svg ├── boot │ ├── .gitkeep │ ├── axios.js │ ├── electron-store.js │ ├── i18n.js │ ├── vue-navigation.js │ └── vue-rx.js ├── components │ ├── .gitkeep │ ├── HlsPlayer.vue │ ├── footerContent.vue │ ├── scrollWarp.vue │ ├── titleBar.vue │ └── viewArea.vue ├── css │ ├── app.styl │ └── quasar.variables.styl ├── i18n │ ├── en-us │ │ └── index.js │ └── index.js ├── index.template.html ├── layouts │ ├── Config.vue │ ├── Home.vue │ ├── Import.vue │ └── Mini.vue ├── pages │ ├── Error404.vue │ ├── Index.vue │ ├── MiniVideo.vue │ ├── Video.vue │ ├── VideoList.vue │ ├── config │ │ ├── components │ │ │ └── dndSort.vue │ │ └── index.vue │ └── directVideo.vue ├── router │ ├── index.js │ └── routes.js ├── statics │ ├── app-logo-128x128.png │ └── icons │ │ ├── apple-icon-120x120.png │ │ ├── apple-icon-152x152.png │ │ ├── apple-icon-167x167.png │ │ ├── apple-icon-180x180.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ ├── favicon.ico │ │ ├── icon-128x128.png │ │ ├── icon-192x192.png │ │ ├── icon-256x256.png │ │ ├── icon-384x384.png │ │ ├── icon-512x512.png │ │ ├── ms-icon-144x144.png │ │ └── safari-pinned-tab.svg ├── store │ ├── index.js │ ├── module │ │ ├── app.js │ │ ├── site.js │ │ └── video.js │ └── plugin │ │ └── index.js └── utils │ ├── promise │ └── parse-xml.js │ └── rx │ └── parse-xml.js └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /dist 2 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | parserOptions: { 5 | parser: 'babel-eslint', 6 | sourceType: 'module' 7 | }, 8 | 9 | env: { 10 | browser: true 11 | }, 12 | 13 | // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention 14 | // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules. 15 | extends: [ 16 | 'plugin:vue/essential', 17 | 'airbnb-base' 18 | ], 19 | 20 | // required to lint *.vue files 21 | plugins: [ 22 | 'vue' 23 | ], 24 | 25 | globals: { 26 | 'ga': true, // Google Analytics 27 | 'cordova': true, 28 | '__statics': true, 29 | 'process': true 30 | }, 31 | 32 | // add your custom rules here 33 | rules: { 34 | 'no-param-reassign': 'off', 35 | 36 | 'import/first': 'off', 37 | 'import/named': 'error', 38 | 'import/namespace': 'error', 39 | 'import/default': 'error', 40 | 'import/export': 'error', 41 | 'import/extensions': 'off', 42 | 'import/no-unresolved': 'off', 43 | 'import/no-extraneous-dependencies': 'off', 44 | 'import/prefer-default-export': 'off', 45 | 'prefer-promise-reject-errors': 'off', 46 | 'max-len': 'off', 47 | 48 | // allow console.log during development only 49 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 50 | // allow debugger during development only 51 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .quasar 2 | .DS_Store 3 | .thumbs.db 4 | node_modules 5 | /dist 6 | /src-cordova/node_modules 7 | /src-cordova/platforms 8 | /src-cordova/plugins 9 | /src-cordova/www 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | 22 | hls-source/ 23 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | plugins: [ 5 | // to edit target browsers: use "browserslist" field in package.json 6 | require('autoprefixer') 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "semi": true, 4 | "singleQuote": true, 5 | "tabWidth": 2, 6 | "trailingComma": "es5", 7 | "arrowParens": "always" 8 | } 9 | -------------------------------------------------------------------------------- /.stylintrc: -------------------------------------------------------------------------------- 1 | { 2 | "blocks": "never", 3 | "brackets": "never", 4 | "colons": "never", 5 | "colors": "always", 6 | "commaSpace": "always", 7 | "commentSpace": "always", 8 | "cssLiteral": "never", 9 | "depthLimit": false, 10 | "duplicates": true, 11 | "efficient": "always", 12 | "extendPref": false, 13 | "globalDupe": true, 14 | "indentPref": 2, 15 | "leadingZero": "never", 16 | "maxErrors": false, 17 | "maxWarnings": false, 18 | "mixed": false, 19 | "namingConvention": false, 20 | "namingConventionStrict": false, 21 | "none": "never", 22 | "noImportant": false, 23 | "parenSpace": "never", 24 | "placeholder": false, 25 | "prefixVarsWithDollar": "always", 26 | "quotePref": "single", 27 | "semicolons": "never", 28 | "sortOrder": false, 29 | "stackedProperties": "never", 30 | "trailingWhitespace": "never", 31 | "universal": "never", 32 | "valid": true, 33 | "zeroUnits": "never", 34 | "zIndexNormalize": false 35 | } 36 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | matrix: 2 | include: 3 | - os: osx 4 | osx_image: xcode10.2 5 | language: node_js 6 | node_js: '10' 7 | env: 8 | - ELECTRON_CACHE=$HOME/.cache/electron 9 | - ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder 10 | 11 | - os: linux 12 | services: docker 13 | language: generic 14 | 15 | cache: 16 | directories: 17 | - node_modules 18 | - $HOME/.cache/electron 19 | - $HOME/.cache/electron-builder 20 | 21 | before_install: 22 | - | 23 | if [ "$TRAVIS_OS_NAME" == "linux" ]; then 24 | # download aliyun OSS Linux client 25 | wget -nc http://gosspublic.alicdn.com/ossutil/1.6.5/ossutil64 26 | chmod 755 ossutil64 27 | # config aliyun OSS Linux client https://help.aliyun.com/document_detail/50455.html 28 | ./ossutil64 config -e "${OSS_ENDPOINT}" -i "${OSS_AKI}" -k "${OSS_AKS}" 29 | else 30 | # download aliyun OSS Linux client 31 | wget -nc http://gosspublic.alicdn.com/ossutil/1.6.5/ossutilmac64 32 | chmod 755 ossutilmac64 33 | # config aliyun OSS Linux client https://help.aliyun.com/document_detail/50455.html 34 | ./ossutilmac64 config -e "${OSS_ENDPOINT}" -i "${OSS_AKI}" -k "${OSS_AKS}" 35 | fi 36 | 37 | script: 38 | - | 39 | rm -rf yarn.lock 40 | if [ "$TRAVIS_OS_NAME" == "linux" ]; then 41 | docker run --rm \ 42 | --env-file <(env | grep -vE '\r|\n' | grep -iE 'DEBUG|NODE_|ELECTRON_|YARN_|NPM_|CI|CIRCLE|TRAVIS_TAG|TRAVIS|TRAVIS_REPO_|TRAVIS_BUILD_|TRAVIS_BRANCH|TRAVIS_PULL_REQUEST_|APPVEYOR_|CSC_|GH_|GITHUB_|BT_|AWS_|STRIP|BUILD_') \ 43 | --env ELECTRON_CACHE="/root/.cache/electron" \ 44 | --env ELECTRON_BUILDER_CACHE="/root/.cache/electron-builder" \ 45 | -v ${PWD}:/project \ 46 | -v ~/.cache/electron:/root/.cache/electron \ 47 | -v ~/.cache/electron-builder:/root/.cache/electron-builder \ 48 | electronuserland/builder:wine \ 49 | /bin/bash -c "npm install && npm run electron:build -- --bundler builder --target linux" 50 | ls dist/electron/Packaged/ 51 | linux_file=`ls dist/electron/Packaged/ | grep '.AppImage$'` 52 | ./ossutil64 cp "dist/electron/Packaged/${linux_file}" "${BUCKET}/${linux_file}" -f 53 | 54 | docker run --rm \ 55 | --env-file <(env | grep -vE '\r|\n' | grep -iE 'DEBUG|NODE_|ELECTRON_|YARN_|NPM_|CI|CIRCLE|TRAVIS_TAG|TRAVIS|TRAVIS_REPO_|TRAVIS_BUILD_|TRAVIS_BRANCH|TRAVIS_PULL_REQUEST_|APPVEYOR_|CSC_|GH_|GITHUB_|BT_|AWS_|STRIP|BUILD_') \ 56 | --env ELECTRON_CACHE="/root/.cache/electron" \ 57 | --env ELECTRON_BUILDER_CACHE="/root/.cache/electron-builder" \ 58 | -v ${PWD}:/project \ 59 | -v ~/.cache/electron:/root/.cache/electron \ 60 | -v ~/.cache/electron-builder:/root/.cache/electron-builder \ 61 | electronuserland/builder:wine \ 62 | /bin/bash -c "npm install && npm run electron:build -- --bundler builder --target win" 63 | ls dist/electron/Packaged/ 64 | for i in `ls dist/electron/Packaged/ | grep 'win.zip$'`; 65 | do 66 | ./ossutil64 cp "dist/electron/Packaged/$i" "${BUCKET}/$i" -f 67 | done 68 | else 69 | npm run electron:build 70 | ls dist/electron/Packaged/ 71 | osx_file=`ls dist/electron/Packaged/ | grep '.dmg$'` 72 | ./ossutilmac64 cp "dist/electron/Packaged/${osx_file}" "${BUCKET}/${osx_file}" -f 73 | fi 74 | 75 | before_cache: 76 | - rm -rf $HOME/.cache/electron-builder/wine 77 | 78 | branches: 79 | except: 80 | - 'dev' 81 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 ZyqGitHub1 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # h-player-v2 2 | 3 | ## 关于 h-player-v2 4 | 5 | h-player-v2 是基于 Quasar Framework 开发应用程序,通过 electron 包装,实现hls视频流的在线播放。 6 | 7 | ## 功能特色 8 | 9 | + 支持视频源导入 10 | + 支持分类浏览与搜索 11 | + 特色多窗口播放模式 12 | 13 | ## Get Started 14 | 15 | ```bash 16 | # 安装依赖 17 | yarn install 18 | # 启动开发服务器 19 | yarn electron:serve 20 | # 编译二进制包 21 | yarn electron:build 22 | ``` 23 | 24 | > ### Note 25 | > 26 | > 1. 资源采集网的配置信息位于src\store\module\site.js 27 | 28 | ### Customize Configuration 29 | 30 | See [Configuration Reference](https://quasar.dev/quasar-cli/quasar-conf-js). 31 | 32 | ## Windows Release 33 | 34 | 对于 windows 用户提供了编译完成的应用,请到 [release](https://github.com/ZyqGitHub1/h-player-v2/releases) 页面下载最新版本 35 | 36 | ## 使用方法: 37 | 38 | 1. 到release下载最新版本的压缩包 点击查看gif 39 | 2. 解压文件到任意目录 点击查看gif 40 | 3. 运行解压目录下的h-player.exe文件 41 | 4. 未导入视频源时会显示导入视频源界面 42 | 5. 点击`暂无视频源,点击选择文件导入`按钮 43 | 6. 选择视频源文件导入。 点击查看gif ***示例文件位于[gist](https://gist.github.com/ZyqGitHub1/104becf19ebb84f601e3d32b59418944)*** 点击查看gif 44 | 7. have fun 45 | 46 | > ### Note 47 | > 48 | > 1. 视频源只需导入一次,可以在设置界面重新导入或清空视频源 49 | > 2. 如果下载示例视频源文件出现网络问题,请参考 [#14](https://github.com/ZyqGitHub1/h-player-v2/issues/14#issuecomment-517104860) 50 | 51 | ## TODO 52 | 53 | - [x] 高亮当前分类 54 | - [x] 页面缓存 55 | - [x] 独立窗口播放 56 | - [x] 持久化配置文件 57 | - [x] 支持导入视频源 58 | - [ ] http/https 功能优化 59 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@quasar/babel-preset-app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "h-player", 3 | "version": "0.9.5", 4 | "description": "A Quasar Framework app", 5 | "productName": "h-player", 6 | "cordovaId": "org.cordova.quasar.app", 7 | "author": "zyq ", 8 | "private": true, 9 | "scripts": { 10 | "electron:serve": "quasar dev -m electron", 11 | "electron:build": "quasar build -m electron", 12 | "lint": "eslint --ext .js,.vue src", 13 | "test": "echo \"No test specified\" && exit 0" 14 | }, 15 | "dependencies": { 16 | "@quasar/extras": "^1.3.1", 17 | "axios": "^0.19.0", 18 | "electron-store": "^5.0.0", 19 | "electron-util": "^0.12.1", 20 | "fs-extra": "^8.1.0", 21 | "hls.js": "^0.12.4", 22 | "lodash": "^4.17.15", 23 | "normalize-url": "^4.3.0", 24 | "plyr": "^3.5.6", 25 | "quasar": "^1.1.2", 26 | "query-string": "^6.8.3", 27 | "rxjs": "^6.5.3", 28 | "semver": "^6.3.0", 29 | "vue-i18n": "^8.14.1", 30 | "vue-navigation": "^1.1.4", 31 | "vue-rx": "^6.2.0", 32 | "vuedraggable": "^2.23.0", 33 | "xml2js": "^0.4.22" 34 | }, 35 | "devDependencies": { 36 | "@quasar/app": "^1.1.0", 37 | "@vue/eslint-config-airbnb": "^4.0.0", 38 | "babel-eslint": "^10.0.3", 39 | "devtron": "^1.4.0", 40 | "electron": "^6.0.9", 41 | "electron-builder": "^21.2.0", 42 | "electron-debug": "^3.0.0", 43 | "electron-devtools-installer": "^2.2.4", 44 | "electron-packager": "^14.0.6", 45 | "eslint": "^6.4.0", 46 | "eslint-loader": "^3.0.0", 47 | "eslint-plugin-vue": "^5.0.0" 48 | }, 49 | "engines": { 50 | "node": ">= 8.9.0", 51 | "npm": ">= 5.6.0", 52 | "yarn": ">= 1.6.0" 53 | }, 54 | "browserslist": [ 55 | "last 1 version, not dead, ie >= 11" 56 | ] 57 | } 58 | -------------------------------------------------------------------------------- /quasar.conf.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable global-require */ 2 | /* eslint-disable no-unused-vars */ 3 | /* eslint-disable func-names */ 4 | // Configuration for your app 5 | // https://quasar.dev/quasar-cli/quasar-conf-js 6 | 7 | const webpack = require('webpack'); 8 | 9 | module.exports = function (ctx) { 10 | return { 11 | // app boot file (/src/boot) 12 | // --> boot files are part of "main.js" 13 | boot: ['i18n', 'axios', 'vue-navigation', 'electron-store', 'vue-rx'], 14 | 15 | css: ['app.styl'], 16 | 17 | extras: [ 18 | // 'ionicons-v4', 19 | // 'mdi-v3', 20 | // 'fontawesome-v5', 21 | // 'eva-icons', 22 | // 'themify', 23 | // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both! 24 | 25 | 'roboto-font', // optional, you are not bound to it 26 | 'material-icons', // optional, you are not bound to it 27 | ], 28 | 29 | framework: { 30 | // iconSet: 'ionicons-v4', 31 | lang: 'zh-hans', // Quasar language 32 | 33 | // all: true, // --- includes everything; for dev only! 34 | 35 | components: [ 36 | 'QAvatar', 37 | 'QTabs', 38 | 'QTab', 39 | 'QFooter', 40 | 'QLayout', 41 | 'QHeader', 42 | 'QDrawer', 43 | 'QPageContainer', 44 | 'QPage', 45 | 'QToolbar', 46 | 'QToolbarTitle', 47 | 'QBtn', 48 | 'QIcon', 49 | 'QList', 50 | 'QItem', 51 | 'QItemSection', 52 | 'QItemLabel', 53 | 'QImg', 54 | 'QCard', 55 | 'QCardSection', 56 | 'QPagination', 57 | 'QInnerLoading', 58 | 'QSpinnerGears', 59 | 'QScrollArea', 60 | 'QForm', 61 | 'QToggle', 62 | 'QPageSticky', 63 | 'QInput', 64 | 'QSeparator', 65 | 'QChip', 66 | 'QTooltip', 67 | 'QBar', 68 | 'QSpace', 69 | // table 70 | 'QTable', 71 | 'QTh', 72 | 'QTr', 73 | 'QTd', 74 | 'QExpansionItem', 75 | 'QPopupEdit', 76 | 'QDialog', 77 | 'QCardActions', 78 | ], 79 | 80 | directives: ['Ripple', 'ClosePopup'], 81 | 82 | // Quasar plugins 83 | plugins: ['Notify', 'Loading', 'LoadingBar', 'Dialog'], 84 | config: { 85 | loadingBar: { 86 | color: 'purple', 87 | size: '5px', 88 | position: 'bottom', 89 | skipHijack: true, 90 | }, 91 | }, 92 | }, 93 | 94 | supportIE: false, 95 | 96 | build: { 97 | scopeHoisting: true, 98 | // vueRouterMode: 'history', 99 | // vueCompiler: true, 100 | // gzip: true, 101 | // analyze: true, 102 | // extractCSS: false, 103 | extendWebpack(cfg) { 104 | cfg.module.rules.push({ 105 | enforce: 'pre', 106 | test: /\.(js|vue)$/, 107 | loader: 'eslint-loader', 108 | exclude: /node_modules/, 109 | options: { 110 | formatter: require('eslint').CLIEngine.getFormatter('stylish'), 111 | }, 112 | }); 113 | }, 114 | }, 115 | 116 | devServer: { 117 | // https: true, 118 | // port: 8080, 119 | open: true, // opens browser window automatically 120 | }, 121 | 122 | // animations: 'all', // --- includes all animations 123 | animations: [], 124 | 125 | ssr: { 126 | pwa: false, 127 | }, 128 | 129 | pwa: { 130 | // workboxPluginMode: 'InjectManifest', 131 | // workboxOptions: {}, // only for NON InjectManifest 132 | manifest: { 133 | // name: 'h-player', 134 | // short_name: 'h-player', 135 | // description: 'A Quasar Framework app', 136 | display: 'standalone', 137 | orientation: 'portrait', 138 | background_color: '#ffffff', 139 | theme_color: '#027be3', 140 | icons: [ 141 | { 142 | src: 'statics/icons/icon-128x128.png', 143 | sizes: '128x128', 144 | type: 'image/png', 145 | }, 146 | { 147 | src: 'statics/icons/icon-192x192.png', 148 | sizes: '192x192', 149 | type: 'image/png', 150 | }, 151 | { 152 | src: 'statics/icons/icon-256x256.png', 153 | sizes: '256x256', 154 | type: 'image/png', 155 | }, 156 | { 157 | src: 'statics/icons/icon-384x384.png', 158 | sizes: '384x384', 159 | type: 'image/png', 160 | }, 161 | { 162 | src: 'statics/icons/icon-512x512.png', 163 | sizes: '512x512', 164 | type: 'image/png', 165 | }, 166 | ], 167 | }, 168 | }, 169 | 170 | cordova: { 171 | // id: 'org.cordova.quasar.app', 172 | // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing 173 | }, 174 | 175 | electron: { 176 | bundler: 'builder', // 'builder' or 'packager' 177 | 178 | extendWebpack(cfg) { 179 | // do something with Electron main process Webpack cfg 180 | // chainWebpack also available besides this extendWebpack 181 | }, 182 | 183 | chainWebpack(chain) { 184 | // fix Critical dependency 185 | // see https://github.com/Automattic/mongoose/issues/7476 and https://github.com/webpack/webpack/issues/196#issuecomment-71925726 186 | chain 187 | .plugin('ContextReplacementPlugin') 188 | .use(webpack.ContextReplacementPlugin, [/.*/]) 189 | .end(); 190 | }, 191 | 192 | packager: { 193 | // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options 194 | // OS X / Mac App Store 195 | // appBundleId: '', 196 | // appCategoryType: '', 197 | // osxSign: '', 198 | // protocol: 'myapp://path', 199 | // Windows only 200 | // win32metadata: { ... } 201 | }, 202 | 203 | builder: { 204 | // https://www.electron.build/configuration/configuration 205 | appId: 'com.electron.h-player', 206 | mac: { 207 | category: 'public.app-category.video', 208 | target: 'dmg', 209 | }, 210 | win: { 211 | target: [ 212 | { 213 | target: 'zip', 214 | arch: [ 215 | 'x64', 216 | 'ia32', 217 | ], 218 | }, 219 | ], 220 | }, 221 | linux: { 222 | target: 'AppImage', 223 | }, 224 | }, 225 | }, 226 | }; 227 | }; 228 | -------------------------------------------------------------------------------- /screenshot/download-sorce.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/screenshot/download-sorce.gif -------------------------------------------------------------------------------- /screenshot/download.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/screenshot/download.gif -------------------------------------------------------------------------------- /screenshot/import-source.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/screenshot/import-source.gif -------------------------------------------------------------------------------- /screenshot/unzip.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/screenshot/unzip.gif -------------------------------------------------------------------------------- /src-electron/icons/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src-electron/icons/icon.icns -------------------------------------------------------------------------------- /src-electron/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src-electron/icons/icon.ico -------------------------------------------------------------------------------- /src-electron/icons/icons/mac/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src-electron/icons/icons/mac/icon.icns -------------------------------------------------------------------------------- /src-electron/icons/icons/png/1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src-electron/icons/icons/png/1024x1024.png -------------------------------------------------------------------------------- /src-electron/icons/icons/png/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src-electron/icons/icons/png/128x128.png -------------------------------------------------------------------------------- /src-electron/icons/icons/png/16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src-electron/icons/icons/png/16x16.png -------------------------------------------------------------------------------- /src-electron/icons/icons/png/24x24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src-electron/icons/icons/png/24x24.png -------------------------------------------------------------------------------- /src-electron/icons/icons/png/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src-electron/icons/icons/png/256x256.png -------------------------------------------------------------------------------- /src-electron/icons/icons/png/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src-electron/icons/icons/png/32x32.png -------------------------------------------------------------------------------- /src-electron/icons/icons/png/48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src-electron/icons/icons/png/48x48.png -------------------------------------------------------------------------------- /src-electron/icons/icons/png/512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src-electron/icons/icons/png/512x512.png -------------------------------------------------------------------------------- /src-electron/icons/icons/png/64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src-electron/icons/icons/png/64x64.png -------------------------------------------------------------------------------- /src-electron/icons/icons/win/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src-electron/icons/icons/win/icon.ico -------------------------------------------------------------------------------- /src-electron/icons/linux-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src-electron/icons/linux-512x512.png -------------------------------------------------------------------------------- /src-electron/main-process/electron-main.dev.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable global-require */ 2 | /** 3 | * This file is used specifically and only for development. It installs 4 | * `electron-debug` & `vue-devtools`. There shouldn't be any need to 5 | * modify this file, but it can be used to extend your development 6 | * environment. 7 | */ 8 | 9 | const electronDebug = require('electron-debug'); 10 | 11 | // Install `electron-debug` with `devtron` 12 | electronDebug({ showDevTools: true }); 13 | 14 | // Install `vue-devtools` 15 | require('electron').app.on('ready', () => { 16 | const installExtension = require('electron-devtools-installer'); 17 | installExtension.default(installExtension.VUEJS_DEVTOOLS) 18 | .then(() => {}) 19 | .catch((err) => { 20 | console.log('Unable to install `vue-devtools`: \n', err); 21 | }); 22 | }); 23 | 24 | // Require `main` process to boot app 25 | require('./electron-main'); 26 | -------------------------------------------------------------------------------- /src-electron/main-process/electron-main.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable global-require */ 2 | /* eslint-disable no-underscore-dangle */ 3 | import { app, BrowserWindow } from 'electron'; 4 | 5 | const { ipcMain } = require('electron'); 6 | 7 | /** 8 | * Set `__statics` path to static files in production; 9 | * The reason we are setting it here is that the path needs to be evaluated at runtime 10 | */ 11 | if (process.env.PROD) { 12 | global.__statics = require('path').join(__dirname, 'statics').replace(/\\/g, '\\\\'); 13 | } 14 | 15 | let mainWindow; 16 | 17 | function createWindow() { 18 | /** 19 | * Initial window options 20 | */ 21 | mainWindow = new BrowserWindow({ 22 | width: 1000, 23 | height: 600, 24 | useContentSize: true, 25 | frame: false, 26 | webPreferences: { 27 | nodeIntegration: true, 28 | webSecurity: false, 29 | }, 30 | }); 31 | 32 | mainWindow.loadURL(process.env.APP_URL); 33 | 34 | mainWindow.removeMenu(); 35 | 36 | mainWindow.on('closed', () => { 37 | mainWindow = null; 38 | }); 39 | 40 | ipcMain.on('from-mini', (event, arg) => { 41 | mainWindow.webContents.send('from-mini', arg); 42 | }); 43 | } 44 | 45 | app.on('ready', createWindow); 46 | 47 | app.on('window-all-closed', () => { 48 | if (process.platform !== 'darwin') { 49 | app.quit(); 50 | } 51 | }); 52 | 53 | app.on('activate', () => { 54 | if (mainWindow === null) { 55 | createWindow(); 56 | } 57 | }); 58 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 34 | 35 | 37 | -------------------------------------------------------------------------------- /src/api/promise/maccms-v10.d.ts: -------------------------------------------------------------------------------- 1 | export interface getListQuery { 2 | /** 3 | action 4 | Default: list 5 | */ 6 | ac?: string; 7 | 8 | /** 9 | 返回数据类型 10 | Default: xml 11 | */ 12 | at?: string; 13 | 14 | /** 15 | 类别ID 16 | */ 17 | t?: string; 18 | 19 | /** 20 | 页码 21 | */ 22 | pg?: string; 23 | 24 | /** 25 | 搜索关键字 26 | */ 27 | wd?: string; 28 | 29 | /** 30 | 几小时内的数据 31 | */ 32 | h?: string; 33 | } 34 | 35 | export function getList(apt: string, query: getListQuery): Promise; 36 | 37 | export interface getDetailQuery { 38 | /** 39 | action 40 | Default: detail 41 | */ 42 | ac?: string; 43 | 44 | /** 45 | 返回数据类型 46 | Default: xml 47 | */ 48 | at?: string; 49 | 50 | /** 51 | 类别ID 52 | */ 53 | t?: string; 54 | 55 | /** 56 | 页码 57 | */ 58 | pg?: string; 59 | 60 | /** 61 | 数据ID,多个ID逗号分割 62 | */ 63 | ids?: string; 64 | 65 | /** 66 | 几小时内的数据 67 | */ 68 | h?: string; 69 | } 70 | 71 | export function getDetail(apt: string, query: getDetailQuery): Promise; 72 | -------------------------------------------------------------------------------- /src/api/promise/maccms-v10.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { stringify } from 'query-string'; 3 | 4 | export async function getList(api, query) { 5 | const defaultParams = { 6 | ac: 'list', 7 | at: 'xml', 8 | }; 9 | const params = Object.assign(defaultParams, query); 10 | const response = await axios.get(api, { 11 | params, 12 | }); 13 | return response; 14 | } 15 | 16 | export async function getDetail(api, query) { 17 | const defaultParams = { 18 | ac: 'detail', 19 | at: 'xml', 20 | }; 21 | const params = Object.assign(defaultParams, query); 22 | const response = await axios.get(api, { 23 | params, 24 | paramsSerializer(qs) { 25 | return stringify(qs, { 26 | arrayFormat: 'comma', 27 | }); 28 | }, 29 | }); 30 | return response; 31 | } 32 | -------------------------------------------------------------------------------- /src/api/promise/maccms-v8.d.ts: -------------------------------------------------------------------------------- 1 | export interface getListQuery { 2 | /** 3 | action 4 | Default: list 5 | */ 6 | ac?: string; 7 | 8 | /** 9 | 类别ID 10 | */ 11 | t?: string; 12 | 13 | /** 14 | 页码 15 | */ 16 | pg?: string; 17 | 18 | /** 19 | 搜索关键字 20 | */ 21 | wd?: string; 22 | 23 | /** 24 | 几小时内的数据 25 | */ 26 | h?: string; 27 | } 28 | 29 | export function getList(apt: string, query: getListQuery): Promise; 30 | 31 | export interface getDetailQuery { 32 | /** 33 | action 34 | Default: videolist 35 | */ 36 | ac?: string; 37 | 38 | /** 39 | 类别ID 40 | */ 41 | t?: string; 42 | 43 | /** 44 | 页码 45 | */ 46 | pg?: string; 47 | 48 | /** 49 | 数据ID,多个ID逗号分割 50 | */ 51 | ids?: string; 52 | 53 | /** 54 | 几小时内的数据 55 | */ 56 | h?: string; 57 | } 58 | 59 | export function getDetail(apt: string, query: getDetailQuery): Promise; 60 | -------------------------------------------------------------------------------- /src/api/promise/maccms-v8.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { stringify } from 'query-string'; 3 | 4 | export async function getList(api, query) { 5 | const defaultParams = { 6 | ac: 'list', 7 | }; 8 | const params = Object.assign(defaultParams, query); 9 | const response = await axios.get(api, { 10 | params, 11 | }); 12 | return response; 13 | } 14 | 15 | export async function getDetail(api, query) { 16 | const defaultParams = { 17 | ac: 'videolist', 18 | }; 19 | const params = Object.assign(defaultParams, query); 20 | const response = await axios.get(api, { 21 | params, 22 | paramsSerializer(qs) { 23 | return stringify(qs, { 24 | arrayFormat: 'comma', 25 | }); 26 | }, 27 | }); 28 | return response; 29 | } 30 | -------------------------------------------------------------------------------- /src/api/rx/maccms-v10.d.ts: -------------------------------------------------------------------------------- 1 | export interface getListQuery { 2 | /** 3 | action 4 | Default: list 5 | */ 6 | ac?: string; 7 | 8 | /** 9 | 返回数据类型 10 | Default: xml 11 | */ 12 | at?: string; 13 | 14 | /** 15 | 类别ID 16 | */ 17 | t?: string; 18 | 19 | /** 20 | 页码 21 | */ 22 | pg?: string; 23 | 24 | /** 25 | 搜索关键字 26 | */ 27 | wd?: string; 28 | 29 | /** 30 | 几小时内的数据 31 | */ 32 | h?: string; 33 | } 34 | 35 | export function getList(apt: string, query: getListQuery): any; 36 | 37 | export interface getDetailQuery { 38 | /** 39 | action 40 | Default: detail 41 | */ 42 | ac?: string; 43 | 44 | /** 45 | 返回数据类型 46 | Default: xml 47 | */ 48 | at?: string; 49 | 50 | /** 51 | 类别ID 52 | */ 53 | t?: string; 54 | 55 | /** 56 | 页码 57 | */ 58 | pg?: string; 59 | 60 | /** 61 | 数据ID,多个ID逗号分割 62 | */ 63 | ids?: string; 64 | 65 | /** 66 | 几小时内的数据 67 | */ 68 | h?: string; 69 | } 70 | 71 | export function getDetail(apt: string, query: getDetailQuery): any; 72 | -------------------------------------------------------------------------------- /src/api/rx/maccms-v10.js: -------------------------------------------------------------------------------- 1 | import { from } from 'rxjs'; 2 | import axios from 'axios'; 3 | import { stringify } from 'query-string'; 4 | 5 | export function getList(api, query) { 6 | const defaultParams = { 7 | ac: 'list', 8 | at: 'xml', 9 | }; 10 | const params = Object.assign(defaultParams, query); 11 | return from( 12 | axios.get(api, { 13 | params, 14 | }), 15 | ); 16 | } 17 | 18 | export function getDetail(api, query) { 19 | const defaultParams = { 20 | ac: 'detail', 21 | at: 'xml', 22 | }; 23 | const params = Object.assign(defaultParams, query); 24 | return from( 25 | axios.get(api, { 26 | params, 27 | paramsSerializer(qs) { 28 | return stringify(qs, { 29 | arrayFormat: 'comma', 30 | }); 31 | }, 32 | }), 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /src/api/rx/maccms-v8.d.ts: -------------------------------------------------------------------------------- 1 | export interface getListQuery { 2 | /** 3 | action 4 | Default: list 5 | */ 6 | ac?: string; 7 | 8 | /** 9 | 类别ID 10 | */ 11 | t?: string; 12 | 13 | /** 14 | 页码 15 | */ 16 | pg?: string; 17 | 18 | /** 19 | 搜索关键字 20 | */ 21 | wd?: string; 22 | 23 | /** 24 | 几小时内的数据 25 | */ 26 | h?: string; 27 | } 28 | 29 | export function getList(apt: string, query: getListQuery): any; 30 | 31 | export interface getDetailQuery { 32 | /** 33 | action 34 | Default: videolist 35 | */ 36 | ac?: string; 37 | 38 | /** 39 | 类别ID 40 | */ 41 | t?: string; 42 | 43 | /** 44 | 页码 45 | */ 46 | pg?: string; 47 | 48 | /** 49 | 数据ID,多个ID逗号分割 50 | */ 51 | ids?: string; 52 | 53 | /** 54 | 几小时内的数据 55 | */ 56 | h?: string; 57 | } 58 | 59 | export function getDetail(apt: string, query: getDetailQuery): any; 60 | -------------------------------------------------------------------------------- /src/api/rx/maccms-v8.js: -------------------------------------------------------------------------------- 1 | import { from } from 'rxjs'; 2 | import axios from 'axios'; 3 | import { stringify } from 'query-string'; 4 | 5 | export function getList(api, query) { 6 | const defaultParams = { 7 | ac: 'list', 8 | }; 9 | const params = Object.assign(defaultParams, query); 10 | return from( 11 | axios.get(api, { 12 | params, 13 | }), 14 | ); 15 | } 16 | 17 | export function getDetail(api, query) { 18 | const defaultParams = { 19 | ac: 'videolist', 20 | }; 21 | const params = Object.assign(defaultParams, query); 22 | return from( 23 | axios.get(api, { 24 | params, 25 | paramsSerializer(qs) { 26 | return stringify(qs, { 27 | arrayFormat: 'comma', 28 | }); 29 | }, 30 | }), 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /src/assets/quasar-logo-full.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 63 | 66 | 69 | 75 | 79 | 83 | 87 | 91 | 95 | 99 | 103 | 104 | 105 | 106 | 107 | 113 | 118 | 126 | 133 | 142 | 151 | 160 | 169 | 178 | 187 | 188 | 189 | 190 | 191 | 192 | -------------------------------------------------------------------------------- /src/assets/sad.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/boot/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src/boot/.gitkeep -------------------------------------------------------------------------------- /src/boot/axios.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | export default async ({ Vue }) => { 4 | Vue.prototype.$axios = axios; 5 | }; 6 | -------------------------------------------------------------------------------- /src/boot/electron-store.js: -------------------------------------------------------------------------------- 1 | const Store = require('electron-store'); 2 | 3 | const store = new Store(); 4 | 5 | // "async" is optional 6 | export default async ({ Vue }) => { 7 | Vue.prototype.$electronStore = store; 8 | }; 9 | -------------------------------------------------------------------------------- /src/boot/i18n.js: -------------------------------------------------------------------------------- 1 | import VueI18n from 'vue-i18n'; 2 | import messages from 'src/i18n'; 3 | 4 | export default async ({ app, Vue }) => { 5 | Vue.use(VueI18n); 6 | 7 | // Set i18n instance on app 8 | app.i18n = new VueI18n({ 9 | locale: 'en-us', 10 | fallbackLocale: 'en-us', 11 | messages, 12 | }); 13 | }; 14 | -------------------------------------------------------------------------------- /src/boot/vue-navigation.js: -------------------------------------------------------------------------------- 1 | import Navigation from 'vue-navigation'; 2 | 3 | // "async" is optional 4 | export default async ({ router, Vue, store }) => { 5 | Vue.use(Navigation, { router, store }); 6 | }; 7 | -------------------------------------------------------------------------------- /src/boot/vue-rx.js: -------------------------------------------------------------------------------- 1 | import VueRx from 'vue-rx'; 2 | 3 | // "async" is optional 4 | export default async ({ Vue }) => { 5 | Vue.use(VueRx); 6 | }; 7 | -------------------------------------------------------------------------------- /src/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src/components/.gitkeep -------------------------------------------------------------------------------- /src/components/HlsPlayer.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 95 | 96 | 117 | -------------------------------------------------------------------------------- /src/components/footerContent.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | H 9 | 10 | 11 | 18 | 19 | 20 | 21 | 47 | 48 | 50 | -------------------------------------------------------------------------------- /src/components/scrollWarp.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /src/components/titleBar.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | H 7 | H-PLAYER 8 | 9 | 10 | 11 | 19 | 20 | 26 | 32 | 38 | 39 | 40 | 41 | 82 | 83 | 85 | -------------------------------------------------------------------------------- /src/components/viewArea.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 39 | 40 | 42 | -------------------------------------------------------------------------------- /src/css/app.styl: -------------------------------------------------------------------------------- 1 | html 2 | overflow hidden 3 | -------------------------------------------------------------------------------- /src/css/quasar.variables.styl: -------------------------------------------------------------------------------- 1 | // Quasar Stylus Variables 2 | // -------------------------------------------------- 3 | // To customize the look and feel of this app, you can override 4 | // the Stylus variables found in Quasar's source Stylus files. 5 | 6 | // Check documentation for full list of Quasar variables 7 | 8 | // It's highly recommended to change the default colors 9 | // to match your app's branding. 10 | // Tip: Use the "Theme Builder" on Quasar's documentation website. 11 | 12 | $primary = #027BE3 13 | $secondary = #26A69A 14 | $accent = #9C27B0 15 | 16 | $positive = #21BA45 17 | $negative = #C10015 18 | $info = #31CCEC 19 | $warning = #F2C037 20 | -------------------------------------------------------------------------------- /src/i18n/en-us/index.js: -------------------------------------------------------------------------------- 1 | // This is just an example, 2 | // so you can safely delete all default props below 3 | 4 | export default { 5 | failed: 'Action failed', 6 | success: 'Action was successful', 7 | }; 8 | -------------------------------------------------------------------------------- /src/i18n/index.js: -------------------------------------------------------------------------------- 1 | import enUS from './en-us'; 2 | 3 | export default { 4 | 'en-us': enUS, 5 | }; 6 | -------------------------------------------------------------------------------- /src/index.template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= htmlWebpackPlugin.options.productName %> 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/layouts/Config.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 14 | 15 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /src/layouts/Home.vue: -------------------------------------------------------------------------------- 1 | 2 | 6 | 10 | 11 | 12 | 13 | 20 | 21 | 22 | 23 | 32 | 33 | 37 | 43 | 44 | 45 | 46 | 47 | 51 | 57 | 58 | 59 | 60 | 65 | 69 | 73 | 74 | 82 | {{ classInfo._ }} 83 | 84 | 85 | 86 | 87 | 91 | 92 | 93 | 97 | 98 | 103 | 加载分类失败 104 | 105 | 106 | 107 | 108 | 109 | 110 | 118 | 119 | 120 | 121 | 125 | 126 | 127 | 128 | 129 | 130 | 408 | 409 | 410 | -------------------------------------------------------------------------------- /src/layouts/Import.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 19 | 或前往 20 | 26 | 页面手动添加 27 | 28 | 29 | 30 | 31 | 32 | 33 | 70 | 71 | 73 | -------------------------------------------------------------------------------- /src/layouts/Mini.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 20 | -------------------------------------------------------------------------------- /src/pages/Error404.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | Sorry, nothing here...(404) 10 | Go back 15 | 16 | 17 | 18 | 23 | -------------------------------------------------------------------------------- /src/pages/Index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 15 | -------------------------------------------------------------------------------- /src/pages/MiniVideo.vue: -------------------------------------------------------------------------------- 1 | 2 | 6 | 11 | 15 | 21 | 22 | 23 | 24 | 25 | 97 | 98 | 103 | -------------------------------------------------------------------------------- /src/pages/Video.vue: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 18 | 19 | 25 | 26 | 27 | 演员: {{currentVideo.actor[0]}} 28 | 地区: {{currentVideo.area[0]}} 29 | 简介: {{currentVideo.des[0]}} 30 | 导演: {{currentVideo.director[0]}} 31 | 语言: {{currentVideo.lang[0]}} 32 | 时间: {{currentVideo.last[0]}} 33 | 备注: {{currentVideo.note[0]}} 34 | 35 | 图片: 36 | 41 | 42 | 评分: {{currentVideo.state[0]}} 43 | 类型: {{currentVideo.type[0]}} 44 | 年份: {{currentVideo.year[0]}} 45 | 46 | 47 | 48 | 54 | 59 | 正在播放 64 | 71 | 72 | 73 | 77 | 83 | 84 | 88 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 268 | 269 | 271 | -------------------------------------------------------------------------------- /src/pages/VideoList.vue: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 16 | 暂无数据 17 | 18 | 19 | 23 | 24 | 29 | 加载数据失败 30 | 31 | 32 | 37 | 38 | 39 | 45 | 46 | 55 | 60 | {{video.name[0]}} 63 | 64 | 65 | Cannot load image 66 | {{video.name[0]}} 69 | 70 | 71 | 72 | 73 | 74 | 83 | 88 | {{video.name[0]}} 91 | 92 | 93 | Cannot load image 94 | {{video.name[0]}} 97 | 98 | 99 | 100 | 101 | 102 | 103 | {{video.name[0]}} 104 | {{video.name[0]}} 105 | 106 | {{video.type[0]}} 112 | {{video.last[0]}} 118 | 119 | 120 | 121 | 122 | 128 | 129 | 130 | 131 | 132 | 136 | 137 | 138 | 139 | 140 | 141 | 233 | 234 | 244 | -------------------------------------------------------------------------------- /src/pages/config/components/dndSort.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 15 | 20 | 21 | {{ element.name }} 22 | 23 | 24 | 25 | 26 | 27 | 28 | 69 | 70 | 103 | -------------------------------------------------------------------------------- /src/pages/config/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 视频源设置 9 | 10 | 11 | 16 | 17 | 18 | 26 | 27 | 35 | 43 | 44 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {{ props.row.id }} 62 | 66 | {{ props.row.name }} 67 | 71 | 77 | 78 | 79 | 83 | {{ props.row.uri }} 84 | 88 | 94 | 95 | 96 | 100 | {{ props.row.httpApi }} 101 | 105 | 110 | 111 | 112 | 116 | {{ props.row.httpsApi }} 117 | 121 | 126 | 127 | 128 | 132 | {{ props.row.type }} 133 | 137 | 142 | 143 | 144 | 148 | 155 | 156 | 157 | 158 | 159 | 163 | 164 | 165 | 添加视频源 166 | 167 | 174 | 175 | 179 | 186 | 190 | 196 | 202 | 206 | 207 | 211 | 216 | 221 | 222 | 223 | 224 | 228 | 229 | 230 | 拖动排序 231 | 232 | 239 | 240 | 244 | 245 | 246 | 250 | 255 | 261 | 262 | 263 | 264 | 265 | 266 | 271 | 272 | 273 | 278 | 282 | 283 | 284 | 289 | 清空视频源后需要重新导入或添加,请确定已备份当前视频源 290 | 291 | 292 | 293 | 299 | 306 | 307 | 308 | 309 | 310 | 全局设置 311 | 312 | 313 | 317 | 318 | 319 | 323 | 324 | 325 | 331 | 332 | 软件信息 333 | 334 | 335 | 336 | 当前版本: 337 | {{currentVersion}} 341 | 342 | 343 | 最新版本: 344 | {{latestVersion}} 348 | 349 | 350 | 351 | 358 | 359 | 360 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 584 | 585 | 586 | -------------------------------------------------------------------------------- /src/pages/directVideo.vue: -------------------------------------------------------------------------------- 1 | 2 | 6 | 12 | 13 | 14 | 15 | 74 | 75 | 80 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VueRouter from 'vue-router'; 3 | 4 | import routes from './routes'; 5 | 6 | Vue.use(VueRouter); 7 | 8 | /* 9 | * If not building with SSR mode, you can 10 | * directly export the Router instantiation 11 | */ 12 | 13 | export default function (/* { store, ssrContext } */) { 14 | const Router = new VueRouter({ 15 | scrollBehavior: () => ({ x: 0, y: 0 }), 16 | routes, 17 | 18 | // Leave these as is and change from quasar.conf.js instead! 19 | // quasar.conf.js -> build -> vueRouterMode 20 | // quasar.conf.js -> build -> publicPath 21 | mode: process.env.VUE_ROUTER_MODE, 22 | base: process.env.VUE_ROUTER_BASE, 23 | }); 24 | 25 | return Router; 26 | } 27 | -------------------------------------------------------------------------------- /src/router/routes.js: -------------------------------------------------------------------------------- 1 | const routes = [ 2 | { 3 | path: '/import', 4 | component: () => import('layouts/Import'), 5 | }, 6 | { 7 | path: '/', 8 | component: () => import('layouts/Home'), 9 | children: [ 10 | { path: '', component: () => import('pages/VideoList') }, 11 | { path: 'video', component: () => import('pages/Video') }, 12 | ], 13 | }, 14 | { 15 | path: '/mini-video', 16 | component: () => import('layouts/Mini'), 17 | children: [{ path: '', component: () => import('pages/MiniVideo') }], 18 | }, 19 | { 20 | path: '/direct-video', 21 | component: () => import('layouts/Mini'), 22 | children: [{ path: '', component: () => import('pages/directVideo') }], 23 | }, 24 | { 25 | path: '/config', 26 | component: () => import('layouts/Config'), 27 | children: [{ path: '', component: () => import('pages/config') }], 28 | }, 29 | ]; 30 | 31 | // Always leave this as last one 32 | if (process.env.MODE !== 'ssr') { 33 | routes.push({ 34 | path: '*', 35 | component: () => import('pages/Error404'), 36 | }); 37 | } 38 | 39 | export default routes; 40 | -------------------------------------------------------------------------------- /src/statics/app-logo-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src/statics/app-logo-128x128.png -------------------------------------------------------------------------------- /src/statics/icons/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src/statics/icons/apple-icon-120x120.png -------------------------------------------------------------------------------- /src/statics/icons/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src/statics/icons/apple-icon-152x152.png -------------------------------------------------------------------------------- /src/statics/icons/apple-icon-167x167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src/statics/icons/apple-icon-167x167.png -------------------------------------------------------------------------------- /src/statics/icons/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src/statics/icons/apple-icon-180x180.png -------------------------------------------------------------------------------- /src/statics/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src/statics/icons/favicon-16x16.png -------------------------------------------------------------------------------- /src/statics/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src/statics/icons/favicon-32x32.png -------------------------------------------------------------------------------- /src/statics/icons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src/statics/icons/favicon-96x96.png -------------------------------------------------------------------------------- /src/statics/icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src/statics/icons/favicon.ico -------------------------------------------------------------------------------- /src/statics/icons/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src/statics/icons/icon-128x128.png -------------------------------------------------------------------------------- /src/statics/icons/icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src/statics/icons/icon-192x192.png -------------------------------------------------------------------------------- /src/statics/icons/icon-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src/statics/icons/icon-256x256.png -------------------------------------------------------------------------------- /src/statics/icons/icon-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src/statics/icons/icon-384x384.png -------------------------------------------------------------------------------- /src/statics/icons/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src/statics/icons/icon-512x512.png -------------------------------------------------------------------------------- /src/statics/icons/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZyqGitHub1/h-player-v2/f4698fda0dfc1b85419ffcedd98a365a65a617f7/src/statics/icons/ms-icon-144x144.png -------------------------------------------------------------------------------- /src/statics/icons/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Vuex from 'vuex'; 3 | 4 | import createLogger from 'vuex/dist/logger'; 5 | import site from './module/site'; 6 | import video from './module/video'; 7 | import app from './module/app'; 8 | 9 | 10 | Vue.use(Vuex); 11 | 12 | /* 13 | * If not building with SSR mode, you can 14 | * directly export the Store instantiation 15 | */ 16 | 17 | export default function (/* { ssrContext } */) { 18 | const Store = new Vuex.Store({ 19 | modules: { 20 | site, 21 | video, 22 | app, 23 | }, 24 | 25 | plugins: [createLogger()], 26 | 27 | // enable strict mode (adds overhead!) 28 | // for dev mode only 29 | strict: process.env.DEV, 30 | }); 31 | 32 | return Store; 33 | } 34 | -------------------------------------------------------------------------------- /src/store/module/app.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import Store from 'electron-store'; 3 | import pkg from '../../../package.json'; 4 | 5 | const store = new Store(); 6 | 7 | export default { 8 | state: { 9 | https: true, 10 | loadImage: true, 11 | currentVersion: pkg.version, 12 | latestVersion: '0.0.0', 13 | }, 14 | mutations: { 15 | setHttps(state, status) { 16 | state.https = status; 17 | store.set('settings', { 18 | https: state.https, 19 | loadImage: state.loadImage, 20 | }); 21 | }, 22 | setLoadImage(state, status) { 23 | state.loadImage = status; 24 | store.set('settings', { 25 | https: state.https, 26 | loadImage: state.loadImage, 27 | }); 28 | }, 29 | setLatestVersion(state, latestVersion) { 30 | state.latestVersion = latestVersion; 31 | }, 32 | setSettings(state, settings) { 33 | state.https = settings.https; 34 | state.loadImage = settings.loadImage; 35 | store.set('settings', settings); 36 | }, 37 | }, 38 | actions: { 39 | getLatestVersion(context) { 40 | return axios 41 | .get( 42 | 'https://api.github.com/repos/ZyqGitHub1/h-player-v2/releases/latest', 43 | ) 44 | .then((response) => { 45 | const tag = response.data.tag_name; 46 | context.commit('setLatestVersion', tag); 47 | return response; 48 | }); 49 | }, 50 | loadSettings(context) { 51 | const settings = store.get('settings'); 52 | console.log('store->app->action.loadSettings'); 53 | console.log(settings); 54 | if (!settings) { 55 | context.commit('setSettings', { 56 | https: true, 57 | loadImage: true, 58 | }); 59 | } else { 60 | context.commit('setSettings', settings); 61 | } 62 | 63 | return settings; 64 | }, 65 | }, 66 | }; 67 | -------------------------------------------------------------------------------- /src/store/module/site.js: -------------------------------------------------------------------------------- 1 | import Store from 'electron-store'; 2 | 3 | const store = new Store(); 4 | 5 | export default { 6 | state: { 7 | siteList: [], 8 | currentSiteId: 1, 9 | currentClass: '', 10 | keyWord: '', 11 | }, 12 | mutations: { 13 | setCurrentSiteId(state, currentSiteId) { 14 | state.currentSiteId = currentSiteId; 15 | }, 16 | setCurrentClass(state, currentClass) { 17 | state.currentClass = currentClass; 18 | }, 19 | setKeyWord(state, keyWord) { 20 | state.keyWord = keyWord; 21 | }, 22 | setSiteList(state, siteList) { 23 | if (!Array.isArray(siteList)) { 24 | state.siteList = []; 25 | } else { 26 | state.siteList = siteList; 27 | } 28 | store.set('siteList', state.siteList); 29 | }, 30 | }, 31 | getters: { 32 | currentSite: state => state.siteList.find(item => item.id === state.currentSiteId), 33 | }, 34 | actions: { 35 | loadSiteList(context) { 36 | const storeSiteList = store.get('siteList'); 37 | if (!Array.isArray(storeSiteList)) { 38 | context.commit('setSiteList', []); 39 | } else { 40 | context.commit('setSiteList', storeSiteList); 41 | } 42 | 43 | 44 | return storeSiteList; 45 | }, 46 | }, 47 | }; 48 | -------------------------------------------------------------------------------- /src/store/module/video.js: -------------------------------------------------------------------------------- 1 | export default { 2 | state: { 3 | currentVideo: { 4 | actor: '', 5 | area: '', 6 | des: '', 7 | director: '', 8 | dl: '', 9 | id: '', 10 | lang: '', 11 | last: '', 12 | name: '', 13 | note: '', 14 | pic: '', 15 | state: '', 16 | tid: '', 17 | type: '', 18 | year: '', 19 | }, 20 | }, 21 | mutations: { 22 | setCurrentVideo(state, currentVideo) { 23 | state.currentVideo = currentVideo; 24 | }, 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /src/store/plugin/index.js: -------------------------------------------------------------------------------- 1 | export const vuexPlugin = (store) => { 2 | // 当 store 初始化后调用 3 | store.subscribe((mutation, state) => { 4 | // 每次 mutation 之后调用 5 | // mutation 的格式为 { type, payload } 6 | console.log('mutation.type', mutation.type); 7 | console.log('mutation.payload', mutation.payload); 8 | console.log(state); 9 | }); 10 | }; 11 | -------------------------------------------------------------------------------- /src/utils/promise/parse-xml.js: -------------------------------------------------------------------------------- 1 | import { parseStringPromise } from 'xml2js'; 2 | 3 | export function parseXML(string, options) { 4 | const encodeXml = string.replace(/&/g, '&'); 5 | const defaultOptions = { 6 | explicitArray: true, 7 | }; 8 | const mergedOptions = Object.assign(defaultOptions, options); 9 | return parseStringPromise(encodeXml, mergedOptions); 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/rx/parse-xml.js: -------------------------------------------------------------------------------- 1 | import { from } from 'rxjs'; 2 | import { parseStringPromise } from 'xml2js'; 3 | 4 | 5 | export function parseXML(string, options) { 6 | const encodeXml = string.replace(/&/g, '&'); 7 | const defaultOptions = { 8 | explicitArray: true, 9 | }; 10 | const mergedOptions = Object.assign(defaultOptions, options); 11 | return from(parseStringPromise(encodeXml, mergedOptions)); 12 | } 13 | --------------------------------------------------------------------------------
4 | 8 |
Sorry, nothing here...(404)