├── .browserslistrc
├── .eslintrc.js
├── .gitignore
├── README.md
├── babel.config.js
├── package.json
├── public
├── favicon.ico
├── index.html
├── orange.ico
├── orange512.png
└── preload.js
├── show.gif
├── src
├── App.vue
├── assets
│ ├── defaultcur.png
│ └── pointer.png
├── background.js
├── common
│ └── reset.less
├── main.js
├── router
│ └── index.js
├── store
│ └── index.js
└── views
│ └── Home.vue
├── vue.config.js
└── yarn.lock
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true
5 | },
6 | extends: ["plugin:vue/essential", "@vue/prettier"],
7 | rules: {
8 | "no-console": process.env.NODE_ENV === "production" ? "error" : "off",
9 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off"
10 | },
11 | parserOptions: {
12 | parser: "babel-eslint"
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
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 | *.sw?
22 |
23 | #Electron-builder output
24 | /dist_electron
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Local music player
2 |
3 | 
4 |
5 | ## Usage
6 |
7 | Chose orangePlayer to play your music, support **.mp3 .wav .flac .ogg .m4a** .file.
8 |
9 | Get more info to check Here: [https://segmentfault.com/a/1190000037613988](https://segmentfault.com/a/1190000037613988)
10 |
11 | ## Introduce
12 |
13 | 1. Support mac and windows;
14 |
15 | 2. Update the electron version to v11;
16 |
17 | 3. Autoupdate
18 |
19 | ## Project setup
20 |
21 | ```
22 | yarn install
23 | ```
24 |
25 | ### Compiles and hot-reloads for development
26 |
27 | ```
28 | yarn electron:serve
29 | ```
30 |
31 | ### Compiles and minifies for production
32 |
33 | ```
34 | yarn electron:build
35 | ```
36 |
37 | ### Customize configuration
38 |
39 | See [Configuration Reference](https://cli.vuejs.org/config/).
40 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ["@vue/cli-plugin-babel/preset"]
3 | };
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "orange-player",
3 | "version": "0.2.8",
4 | "author": "kerinlin",
5 | "description": "Local wave music player",
6 | "private": true,
7 | "scripts": {
8 | "serve": "vue-cli-service serve",
9 | "build": "vue-cli-service build",
10 | "lint": "vue-cli-service lint",
11 | "electron:build": "vue-cli-service electron:build",
12 | "electron:serve": "vue-cli-service electron:serve",
13 | "electron:publish": "vue-cli-service electron:build -p always",
14 | "postinstall": "electron-builder install-app-deps",
15 | "postuninstall": "electron-builder install-app-deps"
16 | },
17 | "main": "background.js",
18 | "dependencies": {
19 | "core-js": "^3.4.3",
20 | "electron-updater": "^4.3.5",
21 | "normalize.css": "^8.0.1",
22 | "stream-to-blob": "^2.0.1",
23 | "vue": "^2.6.10",
24 | "vue-router": "^3.1.3",
25 | "vuex": "^3.1.2",
26 | "wavesurfer.js": "^4.1.1"
27 | },
28 | "devDependencies": {
29 | "@vue/cli-plugin-babel": "^4.1.0",
30 | "@vue/cli-plugin-eslint": "^4.1.0",
31 | "@vue/cli-service": "^4.1.0",
32 | "@vue/eslint-config-prettier": "^5.0.0",
33 | "babel-eslint": "^10.0.3",
34 | "electron": "^11.0.3",
35 | "eslint": "^5.16.0",
36 | "eslint-plugin-prettier": "^3.1.1",
37 | "eslint-plugin-vue": "^5.0.0",
38 | "less": "^3.0.4",
39 | "less-loader": "^5.0.0",
40 | "lint-staged": "^9.4.3",
41 | "prettier": "^1.19.1",
42 | "vue-cli-plugin-electron-builder": "^2.0.0-rc.5",
43 | "vue-template-compiler": "^2.6.10"
44 | },
45 | "gitHooks": {
46 | "pre-commit": "lint-staged"
47 | },
48 | "lint-staged": {
49 | "*.{js,vue}": [
50 | "vue-cli-service lint",
51 | "git add"
52 | ]
53 | }
54 | }
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kerinlin/localMusicPlayer/2b79bda84170da2775d32795a5f3354039a0b500/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | 橙子播放器【舟舟专属】
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/public/orange.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kerinlin/localMusicPlayer/2b79bda84170da2775d32795a5f3354039a0b500/public/orange.ico
--------------------------------------------------------------------------------
/public/orange512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kerinlin/localMusicPlayer/2b79bda84170da2775d32795a5f3354039a0b500/public/orange512.png
--------------------------------------------------------------------------------
/public/preload.js:
--------------------------------------------------------------------------------
1 | const fs = require("fs");
2 | const path = require("path");
3 | const electron = require("electron");
4 | window.fs = fs;
5 | window.path = path;
6 | window.electron = electron;
7 |
--------------------------------------------------------------------------------
/show.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kerinlin/localMusicPlayer/2b79bda84170da2775d32795a5f3354039a0b500/show.gif
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
25 |
26 |
53 |
--------------------------------------------------------------------------------
/src/assets/defaultcur.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kerinlin/localMusicPlayer/2b79bda84170da2775d32795a5f3354039a0b500/src/assets/defaultcur.png
--------------------------------------------------------------------------------
/src/assets/pointer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kerinlin/localMusicPlayer/2b79bda84170da2775d32795a5f3354039a0b500/src/assets/pointer.png
--------------------------------------------------------------------------------
/src/background.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | const electron = require("electron");
3 | import { app, protocol, BrowserWindow, dialog } from "electron";
4 | const { ipcMain } = require("electron");
5 | const path = require("path");
6 | import {
7 | createProtocol
8 | // installVueDevtools
9 | } from "vue-cli-plugin-electron-builder/lib";
10 | import { autoUpdater } from "electron-updater";
11 | const isDevelopment = process.env.NODE_ENV !== "production";
12 | const globalShortcut = electron.globalShortcut;
13 | // Keep a global reference of the window object, if you don't, the window will
14 | // be closed automatically when the JavaScript object is garbage collected.
15 | let win;
16 |
17 | // Scheme must be registered before the app is ready
18 | protocol.registerSchemesAsPrivileged([
19 | { scheme: "app", privileges: { secure: true, standard: true } }
20 | ]);
21 |
22 | function createWindow() {
23 | // Create the browser window.
24 | win = new BrowserWindow({
25 | width: 584,
26 | height: 361,
27 | autoHideMenuBar: true,
28 | frame: false,
29 | resizable: false,
30 | titleBarStyle: "hidden",
31 | webPreferences: {
32 | nodeIntegration: true,
33 | preload: path.join(app.getAppPath(), "preload.js")
34 | }
35 | });
36 |
37 | if (process.env.WEBPACK_DEV_SERVER_URL) {
38 | // Load the url of the dev server if in development mode
39 | win.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
40 | if (!process.env.IS_TEST) win.webContents.openDevTools();
41 | } else {
42 | createProtocol("app");
43 | // Load the index.html when not in development
44 | win.loadURL("app://./index.html");
45 | autoUpdater.checkForUpdates();
46 | }
47 |
48 | win.on("closed", () => {
49 | win = null;
50 | });
51 | }
52 |
53 | let filePath;
54 |
55 | // windows通过process.argv获取打开文件的路径
56 | if (process.platform === "win32") {
57 | filePath = process.argv[1];
58 | }
59 |
60 | // mac监听open-file事件,获取打开文件的路径
61 | app.on("open-file", (event, path) => {
62 | // win.webContents.send("path", path);
63 | filePath = path;
64 | });
65 |
66 | // 监听渲染进程的获取路径要求,把路径信息返回给渲染进程
67 | ipcMain.on("getPath", () => {
68 | win.webContents.send("path", filePath);
69 | });
70 |
71 | // Quit when all windows are closed.
72 | app.on("window-all-closed", () => {
73 | // On macOS it is common for applications and their menu bar
74 | // to stay active until the user quits explicitly with Cmd + Q
75 | if (process.platform !== "darwin") {
76 | app.quit();
77 | }
78 | });
79 |
80 | app.on("activate", () => {
81 | // On macOS it's common to re-create a window in the app when the
82 | // dock icon is clicked and there are no other windows open.
83 | if (win === null) {
84 | createWindow();
85 | }
86 | });
87 |
88 | // This method will be called when Electron has finished
89 | // initialization and is ready to create browser windows.
90 | // Some APIs can only be used after this event occurs.
91 |
92 | const gotTheLock = app.requestSingleInstanceLock();
93 | if (gotTheLock) {
94 | app.on("second-instance", (event, commandLine, workingDirectory) => {
95 | console.log(event, workingDirectory);
96 | // 监听是否有第二个实例,向渲染进程发送第二个实例的本地路径
97 | win.webContents.send("path", `${commandLine[commandLine.length - 1]}`);
98 | if (win) {
99 | if (win.isMinimized()) win.restore();
100 | win.focus();
101 | }
102 | });
103 |
104 | app.on("ready", async () => {
105 | // 正式环境开控制台方便调试
106 | globalShortcut.register("CommandOrControl+K", function() {
107 | win.webContents.openDevTools();
108 | });
109 | createWindow();
110 | });
111 | } else {
112 | app.quit();
113 | }
114 |
115 | ipcMain.on("close", () => {
116 | win.close();
117 | app.quit();
118 | });
119 | ipcMain.on("minimize", () => {
120 | win.minimize();
121 | });
122 | autoUpdater.on("checking-for-update", () => {});
123 | autoUpdater.on("update-available", () => {
124 | dialog.showMessageBox({
125 | title: "新版本发布",
126 | message: "有新内容更新,稍后将重新为您安装",
127 | buttons: ["确定"],
128 | type: "info",
129 | noLink: true
130 | });
131 | });
132 | // autoUpdater.on("update-not-available", (info) => {});
133 | // autoUpdater.on("error", (err) => {});
134 | // autoUpdater.on("download-progress", (progressObj) => {});
135 | autoUpdater.on("update-downloaded", () => {
136 | autoUpdater.quitAndInstall();
137 | });
138 | // Exit cleanly on request from parent process in development mode.
139 | if (isDevelopment) {
140 | if (process.platform === "win32") {
141 | process.on("message", data => {
142 | if (data === "graceful-exit") {
143 | app.quit();
144 | }
145 | });
146 | } else {
147 | process.on("SIGTERM", () => {
148 | app.quit();
149 | });
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/src/common/reset.less:
--------------------------------------------------------------------------------
1 | body {
2 | cursor: url(../assets/defaultcur.png), default;
3 | -webkit-app-region: drag;
4 | }
5 | button {
6 | -webkit-app-region: no-drag;
7 | }
8 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import App from "./App.vue";
3 | import router from "./router";
4 | import store from "./store";
5 | import "normalize.css";
6 | import "./common/reset.less";
7 | Vue.config.productionTip = false;
8 |
9 | new Vue({
10 | router,
11 | store,
12 | render: h => h(App)
13 | }).$mount("#app");
14 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import VueRouter from "vue-router";
3 | import Home from "../views/Home.vue";
4 |
5 | Vue.use(VueRouter);
6 |
7 | const routes = [
8 | {
9 | path: "/",
10 | name: "home",
11 | component: Home
12 | }
13 | ];
14 |
15 | const router = new VueRouter({
16 | routes
17 | });
18 |
19 | export default router;
20 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import Vuex from "vuex";
3 |
4 | Vue.use(Vuex);
5 |
6 | export default new Vuex.Store({
7 | state: {},
8 | mutations: {},
9 | actions: {},
10 | modules: {}
11 | });
12 |
--------------------------------------------------------------------------------
/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
11 |
12 |
18 |
25 |
31 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
201 |
299 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | lintOnSave: false,
3 | pluginOptions: {
4 | electronBuilder: {
5 | builderOptions: {
6 | appId: "com.electron.zzplayer",
7 | productName: "OrangePlayer",
8 | publish: ["github"],
9 | fileAssociations: [
10 | {
11 | ext: ["mp3", "wav", "flac", "ogg", "m4a"],
12 | name: "music",
13 | role: "Editor"
14 | }
15 | ],
16 | win: {
17 | icon: "public/orange.ico"
18 | },
19 | mac: {
20 | target: "dmg",
21 | icon: "public/orange512.png"
22 | },
23 | nsis: {
24 | oneClick: false, // 是否一键安装,建议为 false,可以让用户点击下一步、下一步、下一步的形式安装程序,如果为true,当用户双击构建好的程序,自动安装程序并打开,即:一键安装
25 | allowToChangeInstallationDirectory: true // 允许修改安装目录,建议为 true,是否允许用户改变安装目录,默认是不允许
26 | }
27 | }
28 | }
29 | }
30 | };
31 |
--------------------------------------------------------------------------------