├── .gitignore ├── .vscode └── extensions.json ├── LICENSE ├── README.md ├── docs ├── README.md ├── README_EN.md └── image │ ├── example.png │ ├── logo.png │ └── screenshots.png ├── index.html ├── package.json ├── pnpm-lock.yaml ├── src ├── App.vue ├── assets │ ├── favicon.ico │ ├── vite.svg │ └── vue.svg ├── components │ └── vue-aplayer │ │ ├── APlayer.vue │ │ ├── assets │ │ ├── loading.svg │ │ ├── loop-all.svg │ │ ├── loop-none.svg │ │ ├── loop-one.svg │ │ ├── lrc.svg │ │ ├── menu.svg │ │ ├── order-list.svg │ │ ├── order-random.svg │ │ ├── pause.svg │ │ ├── play.svg │ │ ├── right.svg │ │ ├── skip.svg │ │ ├── volume-down.svg │ │ ├── volume-off.svg │ │ └── volume-up.svg │ │ ├── components │ │ ├── Controller.vue │ │ ├── Icon.vue │ │ ├── List.vue │ │ └── Lyric.vue │ │ ├── index.js │ │ ├── style │ │ └── index.scss │ │ └── utils │ │ └── utils.js ├── main.js └── style.css ├── vite.config.js └── vite.demo.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | # Serverless files 27 | .env 28 | serverless.yml 29 | 30 | # Demo files 31 | demo -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar"] 3 | } 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Worst One 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 |

2 | vue 3 |

4 | 5 |

Vue-APlayer

6 | 7 | > Vue 3.x for [APlayer](https://aplayer.js.org/). 8 | 9 | 项目地址:[**Vue-APlayer**](https://github.com/first19326/APlayer) 10 | 11 | 演示地址:[**Demo**](https://aplayer.worstone.cn) 12 | 13 | ## 介绍 14 | 15 | ![](./docs/image/screenshots.png) 16 | 17 | 使用 Vue 3.x 参考 APlayer 以及 Vue-APlayer 重构的 APlayer。 18 | 19 | 项目中可能存在一些没有发现的问题,如有发现欢迎反馈。 20 | 21 | 在您的项目中使用 Vue-APlayer?[让我知道!](https://github.com/first19326/APlayer/issues/1) 22 | 23 | ## 使用方法 24 | 25 | ```vue 26 | 29 | 39 | ``` 40 | 41 | 由于组件初始化时,歌曲信息为空,所以会加载默认的样式,在歌曲信息获取后自动进行更新。 42 | 43 | 如果想要更好的体验,则参考下面的方式使用。 44 | 45 | ```vue 46 | 49 | 63 | ``` 64 | 65 | ### VitePress 66 | 67 | 通过使用 Vue 的服务器端渲染 (SSR) 功能,VitePress 能够在生产构建期间在 Node.js 中预渲染应用程序。这意味着主题组件中的所有自定义代码都 **需要考虑 SSR 兼容性** 。详情参见 [VitePress 文档 - SSR 兼容性](https://vitepress.dev/zh/guide/ssr-compat#clientonly)。 68 | 69 | 因为 SSR 兼容性的原因,在 VitePress 中可以通过 `defineClientComponent` 方式使用。 70 | 71 | ```vue 72 | 75 | 90 | ``` 91 | 92 | [Docs](./docs/README_EN.md) 93 | 94 | [中文文档](./docs/README.md) 95 | 96 | ## 参考 97 | 98 | - [APlayer](https://github.com/DIYgod/APlayer) : 🍭 Wow, such a beautiful HTML5 music player. 99 | - [Vue-APlayer](https://github.com/SevenOutman/vue-aplayer) : Vue 2.x implementation of APlayer prototype. 100 | 101 | ## 作者 102 | 103 | **Vue-APlayer** © [WorstOne](https://github.com/first19326),在 [MIT](./LICENSE) 许可下发布。 104 | 105 | > 主页 - [WorstOne](https://worstone.cn/) · 博客 - [Live For Code](https://notes.worstone.cn/) · 仓库 - [Github](https://github.com/first19326) 106 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 安装 4 | 5 | 使用 npm: 6 | 7 | ```bash 8 | npm i @worstone/vue-aplayer 9 | ``` 10 | 11 | 使用 pnpm: 12 | 13 | ```bash 14 | pnpm add @worstone/vue-aplayer 15 | ``` 16 | 17 | ## 使用 18 | 19 | ```vue 20 | 23 | 33 | ``` 34 | 35 | 由于组件初始化时歌曲信息为空,所以会加载默认的样式。在存储歌曲信息变量更新后,播放器会自动进行更新。 36 | 37 | 如果想要更好的体验,则参考下面的方式使用。 38 | 39 | ```vue 40 | 43 | 58 | ``` 59 | 60 | ## 参数 61 | 62 | | 名称 | 类型 | 默认值 | 说明 | 63 | | ------------- | --------- | ----------------- | ------------------------------------------------------------ | 64 | | audio | 对象/数组 | - | 音频信息,应该是一个对象或对象数组 | 65 | | audio.name | 字符串 | - | 音频名称 | 66 | | audio.artist | 字符串 | - | 音频艺术家 | 67 | | audio.url | 字符串 | - | 音频链接 | 68 | | audio.cover | 字符串 | - | 音频封面 | 69 | | audio.lrc | 字符串 | - | 音频歌词 | 70 | | audio.theme | 字符串 | - | 切换到此音频时的主题色,比 theme 优先级高 | 71 | | mode | 字符串 | 'normal' | 播放器模式,可选值:'normal','fixed','mini' | 72 | | autoplay | 布尔 | false | 音频自动播放 | 73 | | mutex | 布尔 | true | 互斥,阻止多个播放器同时播放,当前播放器播放时暂停其他播放器,仅处于相同页面时生效。 | 74 | | preload | 字符串 | 'auto' | 预加载,可选值:'none','metadata','auto' | 75 | | theme | 布尔 | '#B7DAFF' | 主题色 | 76 | | autoSwitch | 布尔 | true | 根据音频封面自适应主题色,默认开启,需额外加载 [color-thief.js](https://github.com/lokesh/color-thief/blob/master/src/color-thief.js) | 77 | | loop | 字符串 | 'all' | 音频循环播放,可选值:'all','one','none' | 78 | | order | 字符串 | 'list' | 音频循环顺序,可选值:'list','random' | 79 | | muted | 布尔 | false | 播放器是否静音 | 80 | | volume | 数值 | 0.7 | 默认音量,请注意播放器会记忆用户设置,用户手动设置音量后默认音量即失效 | 81 | | lrcType | 数值 | 1 | 歌词类型,可选值:1,2 | 82 | | lrcShow | 布尔 | true | 歌词默认显示 | 83 | | listFolded | 布尔 | false | 列表默认折叠 | 84 | | listMaxHeight | 数值 | 250 | 列表最大高度 | 85 | | noticeSwitch | 布尔 | true | 通知默认开启,关闭后仅在控制台打印通知内容 | 86 | | storageName | 字符串 | 'aplayer-setting' | 存储播放器设置的 localStorage key | 87 | 88 | 例如: 89 | 90 | ```vue 91 | 94 | 114 | ``` 115 | 116 | ![](./image/example.png) 117 | 118 | ## API 119 | 120 | - `init()`:初始化播放器 121 | - `play()`:播放音频 122 | - `pause()`:暂停音频 123 | - `toggle()`:播放/暂停音频 124 | - `seek(time: number)`:跳转到特定事件,时间的单位为秒 125 | - `mute`:切换播放器静音状态 126 | - `setVolume(volume: number, storage: boolean)`:设置音频音量 127 | - `setTheme(color: string, index: number)`:设置播放器主题色,index 默认为当前音频的 index 128 | - `setMode(mode: string)`:设置播放器模式,mode 取值为 'normal','fixed' 或 'mini' 129 | - `setLoop(loop: string)`:设置播放器音频循环播放,loop 取值为 'all','one' 或 'none' 130 | - `setOrder(order: string)`:设置播放器音频循环顺序,order 取值为 'list' 或 'random' 131 | - `setNotice(text: string, time: number, opacity: number)`:设置通知,时间的单位为毫秒,默认时间 2000 毫秒,默认透明度 0.8,设置时间为 0 可以取消通知自动隐藏 132 | - `skipBack()`:切换到上一首音频 133 | - `skipForward()`:切换到下一首音频 134 | - `destroy()`:销毁播放器 135 | - `showLrc()`:显示歌词 136 | - `hideLrc()`:隐藏歌词 137 | - `toggleLrc()`:显示/隐藏歌词 138 | - `showList()`:显示播放列表 139 | - `hideList()`:隐藏播放列表 140 | - `toggleList()`:显示/隐藏播放列表 141 | - `addList(audios: object | array, clear: boolean)`:添加一个或多个新音频到播放列表 142 | - `removeList(index: number)`:移除播放列表中的一个音频 143 | - `switchList(index: number)`:切换到播放列表里的其他音频 144 | - `clearList()`:清空播放列表 145 | - `audioRef`:原生 audio 146 | - `audioRef.currentTime`:返回音频当前播放时间 147 | - `audioRef.duration`:返回音频总时间 148 | - `audioRef.paused`:返回音频是否暂停 149 | - 支持大多数 [原生 audio 接口](http://www.w3schools.cn/tags/ref_av_dom.asp) 150 | 151 | ## 绑定事件 152 | 153 | ### 音频事件 154 | 155 | - abort 156 | - canplay 157 | - canplaythrough 158 | - durationchange 159 | - emptied 160 | - ended 161 | - error 162 | - loadeddata 163 | - loadedmetadata 164 | - loadstart 165 | - mozaudioavailable 166 | - pause 167 | - play 168 | - playing 169 | - progress 170 | - ratechange 171 | - seeked 172 | - seeking 173 | - stalled 174 | - suspend 175 | - timeupdate 176 | - volumechange 177 | - waiting 178 | 179 | ### 播放器事件 180 | 181 | - listshow 182 | - listhide 183 | - listadd 184 | - listremove 185 | - listswitch 186 | - listclear 187 | - noticeshow 188 | - noticehide 189 | - init 190 | - destroy 191 | - lrcshow 192 | - lrchide 193 | 194 | ## 歌词 195 | 196 | ### LRC 文件方式 197 | 198 | 第一种方式,把歌词放到 LRC 文件里,音频播放时会加载对应的 LRC 文件。 199 | 200 | ```vue 201 | 204 | 217 | ``` 218 | 219 | ### JS 字符串方式 220 | 221 | 第二种方式,把歌词放到 JS 字符串里面。 222 | 223 | ```vue 224 | 227 | 240 | ``` 241 | 242 | ### 歌词格式 243 | 244 | 支持下面格式的歌词: 245 | 246 | `[mm:ss]APlayer` 247 | `[mm:ss.xx]is` 248 | `[mm:ss.xxx]amazing` 249 | `[mm:ss.xx][mm:ss.xx]APlayer` 250 | `[mm:ss.xx]is` 251 | `[mm:ss.xx]amazing[mm:ss.xx]APlayer` 252 | 253 | 254 | ## MSE 支持 255 | 256 | ### HLS 257 | 258 | 需要额外加载 [hls.js](https://github.com/video-dev/hls.js), 259 | 260 | ```html 261 | 262 | ``` 263 | 264 | 或在项目中直接依赖。 265 | 266 | ```vue 267 | 268 | 271 | ``` 272 | 273 | ## 自适应主题颜色 274 | 275 | 需要额外加载 [color-thief.js](https://github.com/lokesh/color-thief/blob/master/src/color-thief.js), 276 | 277 | ```html 278 | 279 | ``` 280 | 281 | 或在项目中直接依赖。 282 | 283 | ```vue 284 | 285 | 288 | ``` 289 | 290 | ## 常见问题 291 | 292 | ### 为什么播放器其他参数不会随着变量进行更新? 293 | 294 | 初始化参数仅在初始化时生效,其他时间只能通过 API 对播放器进行设置。 295 | 296 | ### 为什么播放器不能在手机上自动播放? 297 | 298 | 大多数移动端浏览器禁止了音频自动播放。此外,桌面端的浏览器可能也需要一些设置来实现音频自动播放功能。 299 | 300 | ## 本地开发 301 | 302 | ### 克隆代码 303 | 304 | ``` 305 | git clone git@github.com:first19326/APlayer.git 306 | ``` 307 | 308 | ### 安装依赖 309 | 310 | ```bash 311 | cd APlayer 312 | pnpm install 313 | ``` 314 | 315 | ### 开发模式 316 | 317 | ```bash 318 | pnpm dev 319 | ``` 320 | 321 | ### 编译打包 322 | 323 | ```bash 324 | pnpm build 325 | ``` 326 | 327 | 完成之后,可以在项目的 `dist` 目录看到编译打包好的文件。 328 | -------------------------------------------------------------------------------- /docs/README_EN.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Installation 4 | 5 | Using npm: 6 | 7 | ```bash 8 | npm i @worstone/vue-aplayer 9 | ``` 10 | 11 | Using pnpm: 12 | 13 | ```bash 14 | pnpm add @worstone/vue-aplayer 15 | ``` 16 | 17 | ## Usage 18 | 19 | ```vue 20 | 23 | 33 | ``` 34 | 35 | Audios data is empty during component initialization, so the default style will be loaded. After the audios data variable are updated, the player style will be automatically updated. 36 | 37 | If you want a better experience, refer to the following methods to use it. 38 | 39 | ```vue 40 | 43 | 58 | ``` 59 | 60 | ## Options 61 | 62 | | Name | Type | Default | Description | 63 | | ------------- | ------------ | ----------------- | ------------------------------------------------------------ | 64 | | audio | Object/Array | - | audio info, should be an object or object array | 65 | | audio.name | String | - | audio name | 66 | | audio.artist | String | - | audio artist | 67 | | audio.url | String | - | audio url | 68 | | audio.cover | String | - | audio cover | 69 | | audio.lrc | String | - | audio lrc | 70 | | audio.theme | String | - | main color when switching to this audio, it has priority over the theme | 71 | | mode | String | 'normal' | player mode, values: 'normal', 'fixed', 'mini' | 72 | | autoplay | Boolean | false | audio autoplay | 73 | | mutex | Boolean | true | prevent to play multiple player at the same time, pause other players when this player start play | 74 | | preload | String | 'auto' | values: 'none', 'metadata', 'auto' | 75 | | theme | Boolean | '#B7DAFF' | main color | 76 | | autoSwitch | Boolean | true | self-adapting theme according to cover, it requires the library [color-thief](https://github.com/lokesh/color-thief/blob/master/src/color-thief.js) | 77 | | loop | String | 'all' | player loop play, values: 'all', 'one', 'none' | 78 | | order | String | 'list' | player play order, values: 'list', 'random' | 79 | | muted | Boolean | false | indicate whether player should mute at first | 80 | | volume | Number | 0.7 | default volume, notice that player will remember user setting, default volume will not work after user set volume themselves | 81 | | lrcType | Number | 1 | lrc type, values: 1, 2 | 82 | | lrcShow | Boolean | true | indicate whether lrc should show at first | 83 | | listFolded | Boolean | false | indicate whether list should folded at first | 84 | | listMaxHeight | Number | 250 | list max height | 85 | | noticeSwitch | Boolean | true | notice is enabled by default, only the notice content is printed on the console when disabled | 86 | | storageName | String | 'aplayer-setting' | localStorage key that store player setting | 87 | 88 | For example: 89 | 90 | ```vue 91 | 94 | 114 | ``` 115 | 116 | ![](./image/example.png) 117 | 118 | ## API 119 | 120 | - `init()`: init player 121 | - `play()`: play audio 122 | - `pause()`: pause audio 123 | - `toggle()`: play / pause audio 124 | - `seek(time: number)`: seek to specified time, the unit of time is second 125 | - `mute`: switch player mute status 126 | - `setVolume(volume: number, storage: boolean)`: set audio volume 127 | - `setTheme(color: string, index: number)`: set player theme, the default of index is current audio index 128 | - `setMode(mode: string)`: set player mode, the value of mode should be 'normal', 'fixed' or 'mini' 129 | - `setLoop(loop: string)`: set player loop play, the value of mode should be 'all', 'one' or 'none' 130 | - `setOrder(order: string)`: set player order play, the value of mode should be 'list' or 'random' 131 | - `setNotice(text: string, time: number, opacity: number)`: show message, the unit of time is millisecond, the default of time is 2000, the default of opacity is 0.8, setting time to 0 can disable notice autohide 132 | - `skipBack()`: skip to previous audio 133 | - `skipForward()`: skip to next audio 134 | - `destroy()`: destroy player 135 | - `showLrc()`: show lrc 136 | - `hideLrc()`: hide lrc 137 | - `toggleLrc()`: show / hide lrc 138 | - `showList()`: show list 139 | - `hideList()`: hide list 140 | - `toggleList()`: show / hide list 141 | - `addList(audios: object | array, clear: boolean)`: add new audios to the list 142 | - `removeList(index: number)`: remove an audio from the list 143 | - `switchList(index: number)`: switch to an audio in the list 144 | - `clearList()`: remove all audios from the list 145 | - `audioRef`: native audio 146 | - `audioRef.currentTime`: returns the current playback position 147 | - `audioRef.duration`: returns audio total time 148 | - `audioRef.paused`: returns whether the audio paused 149 | - most [native api](http://www.w3schools.com/tags/ref_av_dom.asp) are supported 150 | 151 | ## Event binding 152 | 153 | ### Audio events 154 | 155 | - abort 156 | - canplay 157 | - canplaythrough 158 | - durationchange 159 | - emptied 160 | - ended 161 | - error 162 | - loadeddata 163 | - loadedmetadata 164 | - loadstart 165 | - mozaudioavailable 166 | - pause 167 | - play 168 | - playing 169 | - progress 170 | - ratechange 171 | - seeked 172 | - seeking 173 | - stalled 174 | - suspend 175 | - timeupdate 176 | - volumechange 177 | - waiting 178 | 179 | ### Player events 180 | 181 | - listshow 182 | - listhide 183 | - listadd 184 | - listremove 185 | - listswitch 186 | - listclear 187 | - noticeshow 188 | - noticehide 189 | - init 190 | - destroy 191 | - lrcshow 192 | - lrchide 193 | 194 | ## LRC 195 | 196 | ### LRC file 197 | 198 | The first way, put LRC to a LRC file, LRC file will be loaded when this audio start to play. 199 | 200 | ```vue 201 | 204 | 217 | ``` 218 | 219 | ### LRC string in JS 220 | 221 | The second way, put LRC to a JS string. 222 | 223 | ```vue 224 | 227 | 240 | ``` 241 | 242 | ### LRC format 243 | 244 | The following LRC format are supported: 245 | 246 | `[mm:ss]APlayer` 247 | `[mm:ss.xx]is` 248 | `[mm:ss.xxx]amazing` 249 | `[mm:ss.xx][mm:ss.xx]APlayer` 250 | `[mm:ss.xx]is` 251 | `[mm:ss.xx]amazing[mm:ss.xx]APlayer` 252 | 253 | ## MSE support 254 | 255 | ### HLS 256 | 257 | It requires the library [hls.js](https://github.com/video-dev/hls.js). 258 | 259 | ```html 260 | 261 | ``` 262 | 263 | or 264 | 265 | ```vue 266 | 267 | 270 | ``` 271 | 272 | 273 | ## Self-adapting theme 274 | 275 | It requires the library [color-thief](https://github.com/lokesh/color-thief/blob/master/src/color-thief.js). 276 | 277 | ```html 278 | 279 | ``` 280 | 281 | or 282 | 283 | ```vue 284 | 285 | 288 | ``` 289 | 290 | ## FAQ 291 | 292 | ### Why do other parameters of the player not update with variables ? 293 | 294 | The initialization parameters only take effect during initialization, at other times, the player can only be set through the API. 295 | 296 | ### Why can't player autoplay in some mobile browsers ? 297 | 298 | Most mobile browsers forbid audio autoplay, you wont be able to achieve it without hacks. In addition, desktop browsers may also require some settings to achieve player autoplay. 299 | 300 | ## Development 301 | 302 | ### Clone Code 303 | 304 | ``` 305 | git clone git@github.com:first19326/APlayer.git 306 | ``` 307 | 308 | ### Install Dependencies 309 | 310 | ```bash 311 | cd APlayer 312 | pnpm install 313 | ``` 314 | 315 | ### Dev Mode 316 | 317 | ```bash 318 | pnpm dev 319 | ``` 320 | 321 | ### Build Release 322 | 323 | ```bash 324 | pnpm build 325 | ``` 326 | 327 | After building, the files will be found in the project's `dist` directory. 328 | -------------------------------------------------------------------------------- /docs/image/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/first19326/APlayer/0952f946a862303767394eae4e9f25ecf082ff47/docs/image/example.png -------------------------------------------------------------------------------- /docs/image/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/first19326/APlayer/0952f946a862303767394eae4e9f25ecf082ff47/docs/image/logo.png -------------------------------------------------------------------------------- /docs/image/screenshots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/first19326/APlayer/0952f946a862303767394eae4e9f25ecf082ff47/docs/image/screenshots.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vue 3.x for APlayer 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@worstone/vue-aplayer", 3 | "version": "1.0.7", 4 | "author": "WorstOne", 5 | "description": "Vue 3.x for APlayer.", 6 | "keywords": [ 7 | "Vue", 8 | "Vue 3.x", 9 | "APlayer", 10 | "Vue-APlayer", 11 | "Component", 12 | "Vue-Component" 13 | ], 14 | "type": "module", 15 | "main": "./dist/vue-aplayer.cjs", 16 | "module": "./dist/vue-aplayer.js", 17 | "files": [ 18 | "dist" 19 | ], 20 | "sideEffects": [ 21 | "**/*.css" 22 | ], 23 | "scripts": { 24 | "dev": "vite", 25 | "build": "vite build", 26 | "build:demo": "vite build --config vite.demo.config.js", 27 | "preview": "vite preview" 28 | }, 29 | "dependencies": { 30 | "smoothscroll": "^0.4.0", 31 | "vue": "^3.4.35" 32 | }, 33 | "devDependencies": { 34 | "@vitejs/plugin-vue": "^4.6.2", 35 | "@worstone/vue-aplayer": "^1.0.7", 36 | "sass": "^1.77.8", 37 | "terser": "^5.31.3", 38 | "vite": "^5.3.5", 39 | "vite-svg-loader": "^5.1.0" 40 | }, 41 | "repository": { 42 | "type": "git", 43 | "url": "git+https://github.com/first19326/APlayer.git" 44 | }, 45 | "homepage": "https://github.com/first19326/APlayer#readme", 46 | "bugs": { 47 | "url": "https://github.com/first19326/APlayer/issues" 48 | }, 49 | "directories": { 50 | "doc": "docs" 51 | }, 52 | "license": "MIT" 53 | } -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | dependencies: 8 | smoothscroll: 9 | specifier: ^0.4.0 10 | version: 0.4.0 11 | vue: 12 | specifier: ^3.4.35 13 | version: 3.4.35 14 | 15 | devDependencies: 16 | '@vitejs/plugin-vue': 17 | specifier: ^4.6.2 18 | version: 4.6.2(vite@5.3.5)(vue@3.4.35) 19 | '@worstone/vue-aplayer': 20 | specifier: ^1.0.7 21 | version: 1.0.7 22 | sass: 23 | specifier: ^1.77.8 24 | version: 1.77.8 25 | terser: 26 | specifier: ^5.31.3 27 | version: 5.31.3 28 | vite: 29 | specifier: ^5.3.5 30 | version: 5.3.5(sass@1.77.8)(terser@5.31.3) 31 | vite-svg-loader: 32 | specifier: ^5.1.0 33 | version: 5.1.0(vue@3.4.35) 34 | 35 | packages: 36 | 37 | /@babel/helper-string-parser@7.24.8: 38 | resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} 39 | engines: {node: '>=6.9.0'} 40 | 41 | /@babel/helper-validator-identifier@7.24.7: 42 | resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} 43 | engines: {node: '>=6.9.0'} 44 | 45 | /@babel/parser@7.25.3: 46 | resolution: {integrity: sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==} 47 | engines: {node: '>=6.0.0'} 48 | hasBin: true 49 | dependencies: 50 | '@babel/types': 7.25.2 51 | 52 | /@babel/types@7.25.2: 53 | resolution: {integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==} 54 | engines: {node: '>=6.9.0'} 55 | dependencies: 56 | '@babel/helper-string-parser': 7.24.8 57 | '@babel/helper-validator-identifier': 7.24.7 58 | to-fast-properties: 2.0.0 59 | 60 | /@esbuild/aix-ppc64@0.21.5: 61 | resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} 62 | engines: {node: '>=12'} 63 | cpu: [ppc64] 64 | os: [aix] 65 | requiresBuild: true 66 | dev: true 67 | optional: true 68 | 69 | /@esbuild/android-arm64@0.21.5: 70 | resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} 71 | engines: {node: '>=12'} 72 | cpu: [arm64] 73 | os: [android] 74 | requiresBuild: true 75 | dev: true 76 | optional: true 77 | 78 | /@esbuild/android-arm@0.21.5: 79 | resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} 80 | engines: {node: '>=12'} 81 | cpu: [arm] 82 | os: [android] 83 | requiresBuild: true 84 | dev: true 85 | optional: true 86 | 87 | /@esbuild/android-x64@0.21.5: 88 | resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} 89 | engines: {node: '>=12'} 90 | cpu: [x64] 91 | os: [android] 92 | requiresBuild: true 93 | dev: true 94 | optional: true 95 | 96 | /@esbuild/darwin-arm64@0.21.5: 97 | resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} 98 | engines: {node: '>=12'} 99 | cpu: [arm64] 100 | os: [darwin] 101 | requiresBuild: true 102 | dev: true 103 | optional: true 104 | 105 | /@esbuild/darwin-x64@0.21.5: 106 | resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} 107 | engines: {node: '>=12'} 108 | cpu: [x64] 109 | os: [darwin] 110 | requiresBuild: true 111 | dev: true 112 | optional: true 113 | 114 | /@esbuild/freebsd-arm64@0.21.5: 115 | resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} 116 | engines: {node: '>=12'} 117 | cpu: [arm64] 118 | os: [freebsd] 119 | requiresBuild: true 120 | dev: true 121 | optional: true 122 | 123 | /@esbuild/freebsd-x64@0.21.5: 124 | resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} 125 | engines: {node: '>=12'} 126 | cpu: [x64] 127 | os: [freebsd] 128 | requiresBuild: true 129 | dev: true 130 | optional: true 131 | 132 | /@esbuild/linux-arm64@0.21.5: 133 | resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} 134 | engines: {node: '>=12'} 135 | cpu: [arm64] 136 | os: [linux] 137 | requiresBuild: true 138 | dev: true 139 | optional: true 140 | 141 | /@esbuild/linux-arm@0.21.5: 142 | resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} 143 | engines: {node: '>=12'} 144 | cpu: [arm] 145 | os: [linux] 146 | requiresBuild: true 147 | dev: true 148 | optional: true 149 | 150 | /@esbuild/linux-ia32@0.21.5: 151 | resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} 152 | engines: {node: '>=12'} 153 | cpu: [ia32] 154 | os: [linux] 155 | requiresBuild: true 156 | dev: true 157 | optional: true 158 | 159 | /@esbuild/linux-loong64@0.21.5: 160 | resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} 161 | engines: {node: '>=12'} 162 | cpu: [loong64] 163 | os: [linux] 164 | requiresBuild: true 165 | dev: true 166 | optional: true 167 | 168 | /@esbuild/linux-mips64el@0.21.5: 169 | resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} 170 | engines: {node: '>=12'} 171 | cpu: [mips64el] 172 | os: [linux] 173 | requiresBuild: true 174 | dev: true 175 | optional: true 176 | 177 | /@esbuild/linux-ppc64@0.21.5: 178 | resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} 179 | engines: {node: '>=12'} 180 | cpu: [ppc64] 181 | os: [linux] 182 | requiresBuild: true 183 | dev: true 184 | optional: true 185 | 186 | /@esbuild/linux-riscv64@0.21.5: 187 | resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} 188 | engines: {node: '>=12'} 189 | cpu: [riscv64] 190 | os: [linux] 191 | requiresBuild: true 192 | dev: true 193 | optional: true 194 | 195 | /@esbuild/linux-s390x@0.21.5: 196 | resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} 197 | engines: {node: '>=12'} 198 | cpu: [s390x] 199 | os: [linux] 200 | requiresBuild: true 201 | dev: true 202 | optional: true 203 | 204 | /@esbuild/linux-x64@0.21.5: 205 | resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} 206 | engines: {node: '>=12'} 207 | cpu: [x64] 208 | os: [linux] 209 | requiresBuild: true 210 | dev: true 211 | optional: true 212 | 213 | /@esbuild/netbsd-x64@0.21.5: 214 | resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} 215 | engines: {node: '>=12'} 216 | cpu: [x64] 217 | os: [netbsd] 218 | requiresBuild: true 219 | dev: true 220 | optional: true 221 | 222 | /@esbuild/openbsd-x64@0.21.5: 223 | resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} 224 | engines: {node: '>=12'} 225 | cpu: [x64] 226 | os: [openbsd] 227 | requiresBuild: true 228 | dev: true 229 | optional: true 230 | 231 | /@esbuild/sunos-x64@0.21.5: 232 | resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} 233 | engines: {node: '>=12'} 234 | cpu: [x64] 235 | os: [sunos] 236 | requiresBuild: true 237 | dev: true 238 | optional: true 239 | 240 | /@esbuild/win32-arm64@0.21.5: 241 | resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} 242 | engines: {node: '>=12'} 243 | cpu: [arm64] 244 | os: [win32] 245 | requiresBuild: true 246 | dev: true 247 | optional: true 248 | 249 | /@esbuild/win32-ia32@0.21.5: 250 | resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} 251 | engines: {node: '>=12'} 252 | cpu: [ia32] 253 | os: [win32] 254 | requiresBuild: true 255 | dev: true 256 | optional: true 257 | 258 | /@esbuild/win32-x64@0.21.5: 259 | resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} 260 | engines: {node: '>=12'} 261 | cpu: [x64] 262 | os: [win32] 263 | requiresBuild: true 264 | dev: true 265 | optional: true 266 | 267 | /@jridgewell/gen-mapping@0.3.5: 268 | resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} 269 | engines: {node: '>=6.0.0'} 270 | dependencies: 271 | '@jridgewell/set-array': 1.2.1 272 | '@jridgewell/sourcemap-codec': 1.5.0 273 | '@jridgewell/trace-mapping': 0.3.25 274 | dev: true 275 | 276 | /@jridgewell/resolve-uri@3.1.2: 277 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 278 | engines: {node: '>=6.0.0'} 279 | dev: true 280 | 281 | /@jridgewell/set-array@1.2.1: 282 | resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} 283 | engines: {node: '>=6.0.0'} 284 | dev: true 285 | 286 | /@jridgewell/source-map@0.3.6: 287 | resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} 288 | dependencies: 289 | '@jridgewell/gen-mapping': 0.3.5 290 | '@jridgewell/trace-mapping': 0.3.25 291 | dev: true 292 | 293 | /@jridgewell/sourcemap-codec@1.5.0: 294 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} 295 | 296 | /@jridgewell/trace-mapping@0.3.25: 297 | resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} 298 | dependencies: 299 | '@jridgewell/resolve-uri': 3.1.2 300 | '@jridgewell/sourcemap-codec': 1.5.0 301 | dev: true 302 | 303 | /@rollup/rollup-android-arm-eabi@4.19.2: 304 | resolution: {integrity: sha512-OHflWINKtoCFSpm/WmuQaWW4jeX+3Qt3XQDepkkiFTsoxFc5BpF3Z5aDxFZgBqRjO6ATP5+b1iilp4kGIZVWlA==} 305 | cpu: [arm] 306 | os: [android] 307 | requiresBuild: true 308 | dev: true 309 | optional: true 310 | 311 | /@rollup/rollup-android-arm64@4.19.2: 312 | resolution: {integrity: sha512-k0OC/b14rNzMLDOE6QMBCjDRm3fQOHAL8Ldc9bxEWvMo4Ty9RY6rWmGetNTWhPo+/+FNd1lsQYRd0/1OSix36A==} 313 | cpu: [arm64] 314 | os: [android] 315 | requiresBuild: true 316 | dev: true 317 | optional: true 318 | 319 | /@rollup/rollup-darwin-arm64@4.19.2: 320 | resolution: {integrity: sha512-IIARRgWCNWMTeQH+kr/gFTHJccKzwEaI0YSvtqkEBPj7AshElFq89TyreKNFAGh5frLfDCbodnq+Ye3dqGKPBw==} 321 | cpu: [arm64] 322 | os: [darwin] 323 | requiresBuild: true 324 | dev: true 325 | optional: true 326 | 327 | /@rollup/rollup-darwin-x64@4.19.2: 328 | resolution: {integrity: sha512-52udDMFDv54BTAdnw+KXNF45QCvcJOcYGl3vQkp4vARyrcdI/cXH8VXTEv/8QWfd6Fru8QQuw1b2uNersXOL0g==} 329 | cpu: [x64] 330 | os: [darwin] 331 | requiresBuild: true 332 | dev: true 333 | optional: true 334 | 335 | /@rollup/rollup-linux-arm-gnueabihf@4.19.2: 336 | resolution: {integrity: sha512-r+SI2t8srMPYZeoa1w0o/AfoVt9akI1ihgazGYPQGRilVAkuzMGiTtexNZkrPkQsyFrvqq/ni8f3zOnHw4hUbA==} 337 | cpu: [arm] 338 | os: [linux] 339 | libc: [glibc] 340 | requiresBuild: true 341 | dev: true 342 | optional: true 343 | 344 | /@rollup/rollup-linux-arm-musleabihf@4.19.2: 345 | resolution: {integrity: sha512-+tYiL4QVjtI3KliKBGtUU7yhw0GMcJJuB9mLTCEauHEsqfk49gtUBXGtGP3h1LW8MbaTY6rSFIQV1XOBps1gBA==} 346 | cpu: [arm] 347 | os: [linux] 348 | libc: [musl] 349 | requiresBuild: true 350 | dev: true 351 | optional: true 352 | 353 | /@rollup/rollup-linux-arm64-gnu@4.19.2: 354 | resolution: {integrity: sha512-OR5DcvZiYN75mXDNQQxlQPTv4D+uNCUsmSCSY2FolLf9W5I4DSoJyg7z9Ea3TjKfhPSGgMJiey1aWvlWuBzMtg==} 355 | cpu: [arm64] 356 | os: [linux] 357 | libc: [glibc] 358 | requiresBuild: true 359 | dev: true 360 | optional: true 361 | 362 | /@rollup/rollup-linux-arm64-musl@4.19.2: 363 | resolution: {integrity: sha512-Hw3jSfWdUSauEYFBSFIte6I8m6jOj+3vifLg8EU3lreWulAUpch4JBjDMtlKosrBzkr0kwKgL9iCfjA8L3geoA==} 364 | cpu: [arm64] 365 | os: [linux] 366 | libc: [musl] 367 | requiresBuild: true 368 | dev: true 369 | optional: true 370 | 371 | /@rollup/rollup-linux-powerpc64le-gnu@4.19.2: 372 | resolution: {integrity: sha512-rhjvoPBhBwVnJRq/+hi2Q3EMiVF538/o9dBuj9TVLclo9DuONqt5xfWSaE6MYiFKpo/lFPJ/iSI72rYWw5Hc7w==} 373 | cpu: [ppc64] 374 | os: [linux] 375 | libc: [glibc] 376 | requiresBuild: true 377 | dev: true 378 | optional: true 379 | 380 | /@rollup/rollup-linux-riscv64-gnu@4.19.2: 381 | resolution: {integrity: sha512-EAz6vjPwHHs2qOCnpQkw4xs14XJq84I81sDRGPEjKPFVPBw7fwvtwhVjcZR6SLydCv8zNK8YGFblKWd/vRmP8g==} 382 | cpu: [riscv64] 383 | os: [linux] 384 | libc: [glibc] 385 | requiresBuild: true 386 | dev: true 387 | optional: true 388 | 389 | /@rollup/rollup-linux-s390x-gnu@4.19.2: 390 | resolution: {integrity: sha512-IJSUX1xb8k/zN9j2I7B5Re6B0NNJDJ1+soezjNojhT8DEVeDNptq2jgycCOpRhyGj0+xBn7Cq+PK7Q+nd2hxLA==} 391 | cpu: [s390x] 392 | os: [linux] 393 | libc: [glibc] 394 | requiresBuild: true 395 | dev: true 396 | optional: true 397 | 398 | /@rollup/rollup-linux-x64-gnu@4.19.2: 399 | resolution: {integrity: sha512-OgaToJ8jSxTpgGkZSkwKE+JQGihdcaqnyHEFOSAU45utQ+yLruE1dkonB2SDI8t375wOKgNn8pQvaWY9kPzxDQ==} 400 | cpu: [x64] 401 | os: [linux] 402 | libc: [glibc] 403 | requiresBuild: true 404 | dev: true 405 | optional: true 406 | 407 | /@rollup/rollup-linux-x64-musl@4.19.2: 408 | resolution: {integrity: sha512-5V3mPpWkB066XZZBgSd1lwozBk7tmOkKtquyCJ6T4LN3mzKENXyBwWNQn8d0Ci81hvlBw5RoFgleVpL6aScLYg==} 409 | cpu: [x64] 410 | os: [linux] 411 | libc: [musl] 412 | requiresBuild: true 413 | dev: true 414 | optional: true 415 | 416 | /@rollup/rollup-win32-arm64-msvc@4.19.2: 417 | resolution: {integrity: sha512-ayVstadfLeeXI9zUPiKRVT8qF55hm7hKa+0N1V6Vj+OTNFfKSoUxyZvzVvgtBxqSb5URQ8sK6fhwxr9/MLmxdA==} 418 | cpu: [arm64] 419 | os: [win32] 420 | requiresBuild: true 421 | dev: true 422 | optional: true 423 | 424 | /@rollup/rollup-win32-ia32-msvc@4.19.2: 425 | resolution: {integrity: sha512-Mda7iG4fOLHNsPqjWSjANvNZYoW034yxgrndof0DwCy0D3FvTjeNo+HGE6oGWgvcLZNLlcp0hLEFcRs+UGsMLg==} 426 | cpu: [ia32] 427 | os: [win32] 428 | requiresBuild: true 429 | dev: true 430 | optional: true 431 | 432 | /@rollup/rollup-win32-x64-msvc@4.19.2: 433 | resolution: {integrity: sha512-DPi0ubYhSow/00YqmG1jWm3qt1F8aXziHc/UNy8bo9cpCacqhuWu+iSq/fp2SyEQK7iYTZ60fBU9cat3MXTjIQ==} 434 | cpu: [x64] 435 | os: [win32] 436 | requiresBuild: true 437 | dev: true 438 | optional: true 439 | 440 | /@trysound/sax@0.2.0: 441 | resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} 442 | engines: {node: '>=10.13.0'} 443 | dev: true 444 | 445 | /@types/estree@1.0.5: 446 | resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} 447 | dev: true 448 | 449 | /@vitejs/plugin-vue@4.6.2(vite@5.3.5)(vue@3.4.35): 450 | resolution: {integrity: sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==} 451 | engines: {node: ^14.18.0 || >=16.0.0} 452 | peerDependencies: 453 | vite: ^4.0.0 || ^5.0.0 454 | vue: ^3.2.25 455 | dependencies: 456 | vite: 5.3.5(sass@1.77.8)(terser@5.31.3) 457 | vue: 3.4.35 458 | dev: true 459 | 460 | /@vue/compiler-core@3.4.35: 461 | resolution: {integrity: sha512-gKp0zGoLnMYtw4uS/SJRRO7rsVggLjvot3mcctlMXunYNsX+aRJDqqw/lV5/gHK91nvaAAlWFgdVl020AW1Prg==} 462 | dependencies: 463 | '@babel/parser': 7.25.3 464 | '@vue/shared': 3.4.35 465 | entities: 4.5.0 466 | estree-walker: 2.0.2 467 | source-map-js: 1.2.0 468 | 469 | /@vue/compiler-dom@3.4.35: 470 | resolution: {integrity: sha512-pWIZRL76/oE/VMhdv/ovZfmuooEni6JPG1BFe7oLk5DZRo/ImydXijoZl/4kh2406boRQ7lxTYzbZEEXEhj9NQ==} 471 | dependencies: 472 | '@vue/compiler-core': 3.4.35 473 | '@vue/shared': 3.4.35 474 | 475 | /@vue/compiler-sfc@3.4.35: 476 | resolution: {integrity: sha512-xacnRS/h/FCsjsMfxBkzjoNxyxEyKyZfBch/P4vkLRvYJwe5ChXmZZrj8Dsed/752H2Q3JE8kYu9Uyha9J6PgA==} 477 | dependencies: 478 | '@babel/parser': 7.25.3 479 | '@vue/compiler-core': 3.4.35 480 | '@vue/compiler-dom': 3.4.35 481 | '@vue/compiler-ssr': 3.4.35 482 | '@vue/shared': 3.4.35 483 | estree-walker: 2.0.2 484 | magic-string: 0.30.11 485 | postcss: 8.4.40 486 | source-map-js: 1.2.0 487 | 488 | /@vue/compiler-ssr@3.4.35: 489 | resolution: {integrity: sha512-7iynB+0KB1AAJKk/biENTV5cRGHRdbdaD7Mx3nWcm1W8bVD6QmnH3B4AHhQQ1qZHhqFwzEzMwiytXm3PX1e60A==} 490 | dependencies: 491 | '@vue/compiler-dom': 3.4.35 492 | '@vue/shared': 3.4.35 493 | 494 | /@vue/reactivity@3.4.35: 495 | resolution: {integrity: sha512-Ggtz7ZZHakriKioveJtPlStYardwQH6VCs9V13/4qjHSQb/teE30LVJNrbBVs4+aoYGtTQKJbTe4CWGxVZrvEw==} 496 | dependencies: 497 | '@vue/shared': 3.4.35 498 | 499 | /@vue/runtime-core@3.4.35: 500 | resolution: {integrity: sha512-D+BAjFoWwT5wtITpSxwqfWZiBClhBbR+bm0VQlWYFOadUUXFo+5wbe9ErXhLvwguPiLZdEF13QAWi2vP3ZD5tA==} 501 | dependencies: 502 | '@vue/reactivity': 3.4.35 503 | '@vue/shared': 3.4.35 504 | 505 | /@vue/runtime-dom@3.4.35: 506 | resolution: {integrity: sha512-yGOlbos+MVhlS5NWBF2HDNgblG8e2MY3+GigHEyR/dREAluvI5tuUUgie3/9XeqhPE4LF0i2wjlduh5thnfOqw==} 507 | dependencies: 508 | '@vue/reactivity': 3.4.35 509 | '@vue/runtime-core': 3.4.35 510 | '@vue/shared': 3.4.35 511 | csstype: 3.1.3 512 | 513 | /@vue/server-renderer@3.4.35(vue@3.4.35): 514 | resolution: {integrity: sha512-iZ0e/u9mRE4T8tNhlo0tbA+gzVkgv8r5BX6s1kRbOZqfpq14qoIvCZ5gIgraOmYkMYrSEZgkkojFPr+Nyq/Mnw==} 515 | peerDependencies: 516 | vue: 3.4.35 517 | dependencies: 518 | '@vue/compiler-ssr': 3.4.35 519 | '@vue/shared': 3.4.35 520 | vue: 3.4.35 521 | 522 | /@vue/shared@3.4.35: 523 | resolution: {integrity: sha512-hvuhBYYDe+b1G8KHxsQ0diDqDMA8D9laxWZhNAjE83VZb5UDaXl9Xnz7cGdDSyiHM90qqI/CyGMcpBpiDy6VVQ==} 524 | 525 | /@worstone/vue-aplayer@1.0.7: 526 | resolution: {integrity: sha512-ACkSnXy83LplvCB/KHww8p5OYwvQaQIXUjHkkboWYXYrg48R6b9y9ogJYw0KnZDtZK3z0hZESRN5PtRC6BhRZw==} 527 | dependencies: 528 | smoothscroll: 0.4.0 529 | vue: 3.4.35 530 | transitivePeerDependencies: 531 | - typescript 532 | dev: true 533 | 534 | /acorn@8.12.1: 535 | resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} 536 | engines: {node: '>=0.4.0'} 537 | hasBin: true 538 | dev: true 539 | 540 | /anymatch@3.1.3: 541 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} 542 | engines: {node: '>= 8'} 543 | dependencies: 544 | normalize-path: 3.0.0 545 | picomatch: 2.3.1 546 | dev: true 547 | 548 | /binary-extensions@2.3.0: 549 | resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} 550 | engines: {node: '>=8'} 551 | dev: true 552 | 553 | /boolbase@1.0.0: 554 | resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} 555 | dev: true 556 | 557 | /braces@3.0.3: 558 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 559 | engines: {node: '>=8'} 560 | dependencies: 561 | fill-range: 7.1.1 562 | dev: true 563 | 564 | /buffer-from@1.1.2: 565 | resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} 566 | dev: true 567 | 568 | /chokidar@3.6.0: 569 | resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} 570 | engines: {node: '>= 8.10.0'} 571 | dependencies: 572 | anymatch: 3.1.3 573 | braces: 3.0.3 574 | glob-parent: 5.1.2 575 | is-binary-path: 2.1.0 576 | is-glob: 4.0.3 577 | normalize-path: 3.0.0 578 | readdirp: 3.6.0 579 | optionalDependencies: 580 | fsevents: 2.3.3 581 | dev: true 582 | 583 | /commander@2.20.3: 584 | resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} 585 | dev: true 586 | 587 | /commander@7.2.0: 588 | resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} 589 | engines: {node: '>= 10'} 590 | dev: true 591 | 592 | /css-select@5.1.0: 593 | resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} 594 | dependencies: 595 | boolbase: 1.0.0 596 | css-what: 6.1.0 597 | domhandler: 5.0.3 598 | domutils: 3.1.0 599 | nth-check: 2.1.1 600 | dev: true 601 | 602 | /css-tree@2.2.1: 603 | resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} 604 | engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} 605 | dependencies: 606 | mdn-data: 2.0.28 607 | source-map-js: 1.2.0 608 | dev: true 609 | 610 | /css-tree@2.3.1: 611 | resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} 612 | engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} 613 | dependencies: 614 | mdn-data: 2.0.30 615 | source-map-js: 1.2.0 616 | dev: true 617 | 618 | /css-what@6.1.0: 619 | resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} 620 | engines: {node: '>= 6'} 621 | dev: true 622 | 623 | /csso@5.0.5: 624 | resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} 625 | engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} 626 | dependencies: 627 | css-tree: 2.2.1 628 | dev: true 629 | 630 | /csstype@3.1.3: 631 | resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} 632 | 633 | /dom-serializer@2.0.0: 634 | resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} 635 | dependencies: 636 | domelementtype: 2.3.0 637 | domhandler: 5.0.3 638 | entities: 4.5.0 639 | dev: true 640 | 641 | /domelementtype@2.3.0: 642 | resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} 643 | dev: true 644 | 645 | /domhandler@5.0.3: 646 | resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} 647 | engines: {node: '>= 4'} 648 | dependencies: 649 | domelementtype: 2.3.0 650 | dev: true 651 | 652 | /domutils@3.1.0: 653 | resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} 654 | dependencies: 655 | dom-serializer: 2.0.0 656 | domelementtype: 2.3.0 657 | domhandler: 5.0.3 658 | dev: true 659 | 660 | /entities@4.5.0: 661 | resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} 662 | engines: {node: '>=0.12'} 663 | 664 | /esbuild@0.21.5: 665 | resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} 666 | engines: {node: '>=12'} 667 | hasBin: true 668 | requiresBuild: true 669 | optionalDependencies: 670 | '@esbuild/aix-ppc64': 0.21.5 671 | '@esbuild/android-arm': 0.21.5 672 | '@esbuild/android-arm64': 0.21.5 673 | '@esbuild/android-x64': 0.21.5 674 | '@esbuild/darwin-arm64': 0.21.5 675 | '@esbuild/darwin-x64': 0.21.5 676 | '@esbuild/freebsd-arm64': 0.21.5 677 | '@esbuild/freebsd-x64': 0.21.5 678 | '@esbuild/linux-arm': 0.21.5 679 | '@esbuild/linux-arm64': 0.21.5 680 | '@esbuild/linux-ia32': 0.21.5 681 | '@esbuild/linux-loong64': 0.21.5 682 | '@esbuild/linux-mips64el': 0.21.5 683 | '@esbuild/linux-ppc64': 0.21.5 684 | '@esbuild/linux-riscv64': 0.21.5 685 | '@esbuild/linux-s390x': 0.21.5 686 | '@esbuild/linux-x64': 0.21.5 687 | '@esbuild/netbsd-x64': 0.21.5 688 | '@esbuild/openbsd-x64': 0.21.5 689 | '@esbuild/sunos-x64': 0.21.5 690 | '@esbuild/win32-arm64': 0.21.5 691 | '@esbuild/win32-ia32': 0.21.5 692 | '@esbuild/win32-x64': 0.21.5 693 | dev: true 694 | 695 | /estree-walker@2.0.2: 696 | resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} 697 | 698 | /fill-range@7.1.1: 699 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 700 | engines: {node: '>=8'} 701 | dependencies: 702 | to-regex-range: 5.0.1 703 | dev: true 704 | 705 | /fsevents@2.3.3: 706 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 707 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 708 | os: [darwin] 709 | requiresBuild: true 710 | dev: true 711 | optional: true 712 | 713 | /glob-parent@5.1.2: 714 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 715 | engines: {node: '>= 6'} 716 | dependencies: 717 | is-glob: 4.0.3 718 | dev: true 719 | 720 | /immutable@4.3.7: 721 | resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} 722 | dev: true 723 | 724 | /is-binary-path@2.1.0: 725 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 726 | engines: {node: '>=8'} 727 | dependencies: 728 | binary-extensions: 2.3.0 729 | dev: true 730 | 731 | /is-extglob@2.1.1: 732 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 733 | engines: {node: '>=0.10.0'} 734 | dev: true 735 | 736 | /is-glob@4.0.3: 737 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 738 | engines: {node: '>=0.10.0'} 739 | dependencies: 740 | is-extglob: 2.1.1 741 | dev: true 742 | 743 | /is-number@7.0.0: 744 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 745 | engines: {node: '>=0.12.0'} 746 | dev: true 747 | 748 | /magic-string@0.30.11: 749 | resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} 750 | dependencies: 751 | '@jridgewell/sourcemap-codec': 1.5.0 752 | 753 | /mdn-data@2.0.28: 754 | resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} 755 | dev: true 756 | 757 | /mdn-data@2.0.30: 758 | resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} 759 | dev: true 760 | 761 | /nanoid@3.3.7: 762 | resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} 763 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 764 | hasBin: true 765 | 766 | /normalize-path@3.0.0: 767 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 768 | engines: {node: '>=0.10.0'} 769 | dev: true 770 | 771 | /nth-check@2.1.1: 772 | resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} 773 | dependencies: 774 | boolbase: 1.0.0 775 | dev: true 776 | 777 | /picocolors@1.0.1: 778 | resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} 779 | 780 | /picomatch@2.3.1: 781 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 782 | engines: {node: '>=8.6'} 783 | dev: true 784 | 785 | /postcss@8.4.40: 786 | resolution: {integrity: sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==} 787 | engines: {node: ^10 || ^12 || >=14} 788 | dependencies: 789 | nanoid: 3.3.7 790 | picocolors: 1.0.1 791 | source-map-js: 1.2.0 792 | 793 | /readdirp@3.6.0: 794 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 795 | engines: {node: '>=8.10.0'} 796 | dependencies: 797 | picomatch: 2.3.1 798 | dev: true 799 | 800 | /rollup@4.19.2: 801 | resolution: {integrity: sha512-6/jgnN1svF9PjNYJ4ya3l+cqutg49vOZ4rVgsDKxdl+5gpGPnByFXWGyfH9YGx9i3nfBwSu1Iyu6vGwFFA0BdQ==} 802 | engines: {node: '>=18.0.0', npm: '>=8.0.0'} 803 | hasBin: true 804 | dependencies: 805 | '@types/estree': 1.0.5 806 | optionalDependencies: 807 | '@rollup/rollup-android-arm-eabi': 4.19.2 808 | '@rollup/rollup-android-arm64': 4.19.2 809 | '@rollup/rollup-darwin-arm64': 4.19.2 810 | '@rollup/rollup-darwin-x64': 4.19.2 811 | '@rollup/rollup-linux-arm-gnueabihf': 4.19.2 812 | '@rollup/rollup-linux-arm-musleabihf': 4.19.2 813 | '@rollup/rollup-linux-arm64-gnu': 4.19.2 814 | '@rollup/rollup-linux-arm64-musl': 4.19.2 815 | '@rollup/rollup-linux-powerpc64le-gnu': 4.19.2 816 | '@rollup/rollup-linux-riscv64-gnu': 4.19.2 817 | '@rollup/rollup-linux-s390x-gnu': 4.19.2 818 | '@rollup/rollup-linux-x64-gnu': 4.19.2 819 | '@rollup/rollup-linux-x64-musl': 4.19.2 820 | '@rollup/rollup-win32-arm64-msvc': 4.19.2 821 | '@rollup/rollup-win32-ia32-msvc': 4.19.2 822 | '@rollup/rollup-win32-x64-msvc': 4.19.2 823 | fsevents: 2.3.3 824 | dev: true 825 | 826 | /sass@1.77.8: 827 | resolution: {integrity: sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==} 828 | engines: {node: '>=14.0.0'} 829 | hasBin: true 830 | dependencies: 831 | chokidar: 3.6.0 832 | immutable: 4.3.7 833 | source-map-js: 1.2.0 834 | dev: true 835 | 836 | /smoothscroll@0.4.0: 837 | resolution: {integrity: sha512-sggQ3U2Un38b3+q/j1P4Y4fCboCtoUIaBYoge+Lb6Xg1H8RTIif/hugVr+ErMtIDpvBbhQfTjtiTeYAfbw1ZGQ==} 838 | 839 | /source-map-js@1.2.0: 840 | resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} 841 | engines: {node: '>=0.10.0'} 842 | 843 | /source-map-support@0.5.21: 844 | resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} 845 | dependencies: 846 | buffer-from: 1.1.2 847 | source-map: 0.6.1 848 | dev: true 849 | 850 | /source-map@0.6.1: 851 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 852 | engines: {node: '>=0.10.0'} 853 | dev: true 854 | 855 | /svgo@3.3.2: 856 | resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} 857 | engines: {node: '>=14.0.0'} 858 | hasBin: true 859 | dependencies: 860 | '@trysound/sax': 0.2.0 861 | commander: 7.2.0 862 | css-select: 5.1.0 863 | css-tree: 2.3.1 864 | css-what: 6.1.0 865 | csso: 5.0.5 866 | picocolors: 1.0.1 867 | dev: true 868 | 869 | /terser@5.31.3: 870 | resolution: {integrity: sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==} 871 | engines: {node: '>=10'} 872 | hasBin: true 873 | dependencies: 874 | '@jridgewell/source-map': 0.3.6 875 | acorn: 8.12.1 876 | commander: 2.20.3 877 | source-map-support: 0.5.21 878 | dev: true 879 | 880 | /to-fast-properties@2.0.0: 881 | resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} 882 | engines: {node: '>=4'} 883 | 884 | /to-regex-range@5.0.1: 885 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 886 | engines: {node: '>=8.0'} 887 | dependencies: 888 | is-number: 7.0.0 889 | dev: true 890 | 891 | /vite-svg-loader@5.1.0(vue@3.4.35): 892 | resolution: {integrity: sha512-M/wqwtOEjgb956/+m5ZrYT/Iq6Hax0OakWbokj8+9PXOnB7b/4AxESHieEtnNEy7ZpjsjYW1/5nK8fATQMmRxw==} 893 | peerDependencies: 894 | vue: '>=3.2.13' 895 | dependencies: 896 | svgo: 3.3.2 897 | vue: 3.4.35 898 | dev: true 899 | 900 | /vite@5.3.5(sass@1.77.8)(terser@5.31.3): 901 | resolution: {integrity: sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==} 902 | engines: {node: ^18.0.0 || >=20.0.0} 903 | hasBin: true 904 | peerDependencies: 905 | '@types/node': ^18.0.0 || >=20.0.0 906 | less: '*' 907 | lightningcss: ^1.21.0 908 | sass: '*' 909 | stylus: '*' 910 | sugarss: '*' 911 | terser: ^5.4.0 912 | peerDependenciesMeta: 913 | '@types/node': 914 | optional: true 915 | less: 916 | optional: true 917 | lightningcss: 918 | optional: true 919 | sass: 920 | optional: true 921 | stylus: 922 | optional: true 923 | sugarss: 924 | optional: true 925 | terser: 926 | optional: true 927 | dependencies: 928 | esbuild: 0.21.5 929 | postcss: 8.4.40 930 | rollup: 4.19.2 931 | sass: 1.77.8 932 | terser: 5.31.3 933 | optionalDependencies: 934 | fsevents: 2.3.3 935 | dev: true 936 | 937 | /vue@3.4.35: 938 | resolution: {integrity: sha512-+fl/GLmI4GPileHftVlCdB7fUL4aziPcqTudpTGXCT8s+iZWuOCeNEB5haX6Uz2IpRrbEXOgIFbe+XciCuGbNQ==} 939 | peerDependencies: 940 | typescript: '*' 941 | peerDependenciesMeta: 942 | typescript: 943 | optional: true 944 | dependencies: 945 | '@vue/compiler-dom': 3.4.35 946 | '@vue/compiler-sfc': 3.4.35 947 | '@vue/runtime-dom': 3.4.35 948 | '@vue/server-renderer': 3.4.35(vue@3.4.35) 949 | '@vue/shared': 3.4.35 950 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 67 | 161 | -------------------------------------------------------------------------------- /src/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/first19326/APlayer/0952f946a862303767394eae4e9f25ecf082ff47/src/assets/favicon.ico -------------------------------------------------------------------------------- /src/assets/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/vue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/APlayer.vue: -------------------------------------------------------------------------------- 1 | 33 | 729 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/assets/loading.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/assets/loop-all.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/assets/loop-none.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/assets/loop-one.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/assets/lrc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/assets/menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/assets/order-list.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/assets/order-random.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/assets/pause.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/assets/play.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/assets/right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/assets/skip.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/assets/volume-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/assets/volume-off.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/assets/volume-up.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/components/Controller.vue: -------------------------------------------------------------------------------- 1 | 55 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/components/Icon.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/components/List.vue: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/components/Lyric.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /src/components/vue-aplayer/index.js: -------------------------------------------------------------------------------- 1 | import APlayer from "./APlayer.vue"; 2 | 3 | APlayer.install = (app) => { 4 | app.component(APlayer.name, APlayer); 5 | } 6 | 7 | export default APlayer; -------------------------------------------------------------------------------- /src/components/vue-aplayer/style/index.scss: -------------------------------------------------------------------------------- 1 | $aplayer-height: 66px; 2 | $lrc-height: 30px; 3 | $aplayer-height-lrc: $aplayer-height + $lrc-height - 6; 4 | 5 | .aplayer { 6 | position: relative; 7 | margin: 5px; 8 | width: 100%; 9 | line-height: initial; 10 | border-radius: 2px; 11 | font-family: Arial, Helvetica, sans-serif; 12 | box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.07), 0 1px 5px 0 rgba(0, 0, 0, 0.1); 13 | overflow: hidden; 14 | user-select: none; 15 | 16 | * { 17 | box-sizing: content-box; 18 | } 19 | 20 | svg { 21 | width: 100%; 22 | height: 100%; 23 | 24 | path, 25 | circle { 26 | fill: #FFF; 27 | } 28 | } 29 | 30 | &.aplayer-withlist { 31 | .aplayer-info { 32 | border-bottom: 1px solid #E9E9E9; 33 | } 34 | .aplayer-list { 35 | display: block; 36 | } 37 | .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon.aplayer-icon-menu { 38 | display: inline; 39 | } 40 | .aplayer-icon-order { 41 | display: inline; 42 | } 43 | } 44 | 45 | &.aplayer-withlrc { 46 | .aplayer-pic { 47 | width: $aplayer-height-lrc; 48 | height: $aplayer-height-lrc; 49 | } 50 | .aplayer-info { 51 | margin-left: $aplayer-height-lrc; 52 | padding: 10px 7px 0 7px; 53 | height: $aplayer-height-lrc; 54 | } 55 | .aplayer-lrc { 56 | display: block; 57 | } 58 | } 59 | 60 | &.aplayer-mini { 61 | width: $aplayer-height; 62 | 63 | .aplayer-info { 64 | display: none; 65 | } 66 | .aplayer-list { 67 | display: none; 68 | } 69 | .aplayer-pic, 70 | .aplayer-body { 71 | width: $aplayer-height; 72 | height: $aplayer-height; 73 | } 74 | } 75 | 76 | &.aplayer-fixed { 77 | position: fixed; 78 | bottom: 0; 79 | left: 0; 80 | right: 0; 81 | margin: 0; 82 | max-width: 400px; 83 | z-index: 99; 84 | overflow: visible; 85 | box-shadow: none; 86 | 87 | .aplayer-list { 88 | margin-bottom: 65px; 89 | max-width: 398px; 90 | border: 1px solid #EEE; 91 | border-bottom: none; 92 | } 93 | 94 | .aplayer-body { 95 | position: fixed; 96 | bottom: 0; 97 | left: 0; 98 | right: 0; 99 | margin: 0; 100 | padding-right: 18px; 101 | max-width: 400px; 102 | z-index: 99; 103 | transition: all 0.3s ease; 104 | } 105 | 106 | .aplayer-lrc { 107 | display: block; 108 | position: fixed; 109 | bottom: 10px; 110 | left: 0; 111 | right: 0; 112 | margin: 0; 113 | z-index: 98; 114 | pointer-events: none; 115 | text-shadow: -1px -1px 0 #FFF; 116 | 117 | &:before, 118 | &:after { 119 | display: none; 120 | } 121 | } 122 | 123 | .aplayer-info { 124 | transform: scaleX(1); 125 | transform-origin: 0 0; 126 | transition: all 0.3s ease; 127 | border-top: 1px solid #E9E9E9; 128 | border-right: 1px solid #E9E9E9; 129 | border-bottom: none; 130 | 131 | .aplayer-music { 132 | width: calc(100% - 105px); 133 | } 134 | } 135 | 136 | .aplayer-miniswitcher { 137 | display: block; 138 | } 139 | 140 | &.aplayer-mini { 141 | .aplayer-info { 142 | display: block; 143 | transform: scaleX(0); 144 | } 145 | .aplayer-body { 146 | width: $aplayer-height !important; 147 | } 148 | 149 | .aplayer-miniswitcher .aplayer-icon { 150 | transform: rotateY(0); 151 | } 152 | } 153 | 154 | .aplayer-icon-back, 155 | .aplayer-icon-play, 156 | .aplayer-icon-forward, 157 | .aplayer-icon-lrc { 158 | display: inline-block; 159 | } 160 | 161 | .aplayer-icon-back, 162 | .aplayer-icon-play, 163 | .aplayer-icon-forward, 164 | .aplayer-icon-menu { 165 | position: absolute; 166 | bottom: 27px; 167 | width: 20px; 168 | height: 20px; 169 | } 170 | 171 | .aplayer-icon-back { 172 | right: 75px; 173 | } 174 | 175 | .aplayer-icon-play { 176 | right: 50px; 177 | } 178 | 179 | .aplayer-icon-forward { 180 | right: 25px; 181 | } 182 | 183 | .aplayer-icon-menu { 184 | right: 0; 185 | } 186 | } 187 | 188 | &.aplayer-mobile { 189 | .aplayer-icon-volume-down { 190 | display: none; 191 | } 192 | } 193 | 194 | &.aplayer-narrow { 195 | .aplayer-icon-order, 196 | .aplayer-icon-loop { 197 | display: none; 198 | } 199 | } 200 | 201 | &.aplayer-loading { 202 | .aplayer-info .aplayer-controller .aplayer-loading-icon { 203 | display: block; 204 | } 205 | 206 | .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played .aplayer-thumb { 207 | transform: scale(1); 208 | } 209 | } 210 | 211 | .aplayer-body { 212 | position: relative; 213 | background: #FFF; 214 | } 215 | 216 | .aplayer-icon { 217 | display: inline-block; 218 | margin: 0; 219 | padding: 0; 220 | width: 15px; 221 | height: 15px; 222 | opacity: .8; 223 | background-color: transparent; 224 | border: none; 225 | outline: none; 226 | vertical-align: middle; 227 | font-size: 12px; 228 | cursor: pointer; 229 | 230 | path { 231 | transition: all .2s ease-in-out; 232 | } 233 | } 234 | 235 | .aplayer-icon-order, 236 | .aplayer-icon-back, 237 | .aplayer-icon-play, 238 | .aplayer-icon-forward, 239 | .aplayer-icon-lrc { 240 | display: none; 241 | } 242 | 243 | .aplayer-icon-lrc-inactivity { 244 | svg { 245 | opacity: 0.4; 246 | } 247 | } 248 | 249 | .aplayer-icon-forward { 250 | transform: rotate(180deg); 251 | } 252 | 253 | .aplayer-lrc-content { 254 | display: none; 255 | } 256 | 257 | .aplayer-pic { 258 | position: relative; 259 | float: left; 260 | width: $aplayer-height; 261 | height: $aplayer-height; 262 | background-size: cover; 263 | background-position: center; 264 | transition: all 0.3s ease; 265 | cursor: pointer; 266 | 267 | &:hover .aplayer-button { 268 | opacity: 1; 269 | } 270 | 271 | .aplayer-button { 272 | position: absolute; 273 | opacity: 0.8; 274 | background: rgba(0, 0, 0, 0.2); 275 | border-radius: 50%; 276 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 277 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); 278 | transition: all 0.1s ease; 279 | 280 | path { 281 | fill: #FFF; 282 | } 283 | } 284 | 285 | .aplayer-hide { 286 | display: none; 287 | } 288 | 289 | .aplayer-play { 290 | bottom: 50%; 291 | right: 50%; 292 | margin: 0 -15px -15px 0; 293 | width: 26px; 294 | height: 26px; 295 | border: 2px solid #FFF; 296 | 297 | svg { 298 | position: absolute; 299 | top: 3px; 300 | left: 4px; 301 | width: 20px; 302 | height: 20px; 303 | } 304 | } 305 | 306 | .aplayer-pause { 307 | bottom: 4px; 308 | right: 4px; 309 | width: 16px; 310 | height: 16px; 311 | border: 2px solid #FFF; 312 | 313 | svg { 314 | position: absolute; 315 | top: 2px; 316 | left: 2px; 317 | width: 12px; 318 | height: 12px; 319 | } 320 | } 321 | } 322 | 323 | .aplayer-info { 324 | margin-left: $aplayer-height; 325 | padding: 14px 7px 0 10px; 326 | height: $aplayer-height; 327 | box-sizing: border-box; 328 | 329 | .aplayer-music { 330 | margin: 0 0 13px 5px; 331 | padding-bottom: 2px; 332 | height: 20px; 333 | overflow: hidden; 334 | white-space: nowrap; 335 | text-overflow: ellipsis; 336 | user-select: text; 337 | cursor: default; 338 | 339 | .aplayer-title { 340 | font-size: 14px; 341 | } 342 | 343 | .aplayer-author { 344 | font-size: 12px; 345 | color: #666; 346 | } 347 | } 348 | 349 | .aplayer-controller { 350 | position: relative; 351 | display: flex; 352 | align-items: center; 353 | bottom: 4px; 354 | 355 | .aplayer-bar-wrap { 356 | margin: 0 0 0 5px; 357 | padding: 4px 0; 358 | flex: 1; 359 | cursor: pointer !important; 360 | 361 | &:hover { 362 | .aplayer-bar .aplayer-played .aplayer-thumb { 363 | transform: scale(1); 364 | } 365 | } 366 | 367 | .aplayer-bar { 368 | position: relative; 369 | width: 100%; 370 | height: 2px; 371 | background: #CDCDCD; 372 | 373 | .aplayer-loaded { 374 | position: absolute; 375 | top: 0; 376 | bottom: 0; 377 | left: 0; 378 | height: 2px; 379 | background: #AAA; 380 | transition: all 0.5s ease; 381 | } 382 | 383 | .aplayer-played { 384 | position: absolute; 385 | top: 0; 386 | bottom: 0; 387 | left: 0; 388 | height: 2px; 389 | 390 | .aplayer-thumb { 391 | position: absolute; 392 | top: 0; 393 | right: 5px; 394 | margin-top: -4px; 395 | margin-right: -10px; 396 | width: 10px; 397 | height: 10px; 398 | border-radius: 50%; 399 | cursor: pointer; 400 | transition: all .3s ease-in-out; 401 | transform: scale(0); 402 | } 403 | } 404 | } 405 | } 406 | 407 | .aplayer-time { 408 | position: relative; 409 | right: 0; 410 | padding-left: 7px; 411 | height: 17px; 412 | color: #999; 413 | font-size: 11px; 414 | 415 | .aplayer-time-inner { 416 | vertical-align: middle; 417 | } 418 | 419 | .aplayer-icon { 420 | cursor: pointer; 421 | transition: all 0.2s ease; 422 | 423 | path { 424 | fill: #666; 425 | } 426 | 427 | &.aplayer-icon-order { 428 | margin-left: 5px; 429 | } 430 | 431 | &.aplayer-icon-loop { 432 | margin: 0 5px; 433 | } 434 | 435 | &:hover { 436 | path { 437 | fill: #000; 438 | } 439 | } 440 | 441 | &.aplayer-icon-menu { 442 | display: none; 443 | } 444 | } 445 | 446 | &.aplayer-time-narrow { 447 | .aplayer-icon-mode { 448 | display: none; 449 | } 450 | 451 | .aplayer-icon-menu { 452 | display: none; 453 | } 454 | } 455 | } 456 | 457 | .aplayer-volume-wrap { 458 | position: relative; 459 | display: inline-block; 460 | margin-left: 7px; 461 | cursor: pointer !important; 462 | 463 | &:hover .aplayer-volume-bar-wrap { 464 | height: 40px; 465 | } 466 | 467 | .aplayer-volume-bar-wrap { 468 | position: absolute; 469 | bottom: 15px; 470 | right: -3px; 471 | width: 25px; 472 | height: 0; 473 | z-index: 99; 474 | overflow: hidden; 475 | transition: all .2s ease-in-out; 476 | 477 | &.aplayer-volume-bar-wrap-active { 478 | height: 40px; 479 | } 480 | 481 | .aplayer-volume-bar { 482 | position: absolute; 483 | bottom: 0; 484 | right: 10px; 485 | width: 5px; 486 | height: 35px; 487 | background: #AAA; 488 | border-radius: 2.5px; 489 | overflow: hidden; 490 | 491 | .aplayer-volume { 492 | position: absolute; 493 | bottom: 0; 494 | right: 0; 495 | width: 5px; 496 | transition: all 0.1s ease; 497 | } 498 | } 499 | } 500 | } 501 | 502 | .aplayer-loading-icon { 503 | display: none; 504 | 505 | svg { 506 | position: absolute; 507 | animation: rotate 1s linear infinite; 508 | } 509 | } 510 | } 511 | } 512 | 513 | .aplayer-lrc { 514 | display: none; 515 | position: relative; 516 | margin: -10px 0 7px; 517 | height: $lrc-height; 518 | text-align: center; 519 | overflow: hidden; 520 | 521 | &:before { 522 | display: block; 523 | position: absolute; 524 | top: 0; 525 | z-index: 1; 526 | width: 100%; 527 | height: 10%; 528 | content: ' '; 529 | background: -moz-linear-gradient(top, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); 530 | background: -webkit-linear-gradient(top, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); 531 | background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); 532 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FFFFFF', endColorstr='#00FFFFFF',GradientType=0 ); 533 | overflow: hidden; 534 | } 535 | 536 | &:after { 537 | display: block; 538 | position: absolute; 539 | bottom: 0; 540 | z-index: 1; 541 | width: 100%; 542 | height: 33%; 543 | content: ' '; 544 | background: -moz-linear-gradient(top, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.8) 100%); 545 | background: -webkit-linear-gradient(top, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.8) 100%); 546 | background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.8) 100%); 547 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00FFFFFF', endColorstr='#CCFFFFFF',GradientType=0 ); 548 | overflow: hidden; 549 | } 550 | 551 | p { 552 | margin: 0 !important; 553 | padding: 0 !important; 554 | height: 16px !important; 555 | line-height: 16px !important; 556 | opacity: 0.4; 557 | color: #666; 558 | font-size: 12px; 559 | transition: all 0.5s ease-out; 560 | overflow: hidden; 561 | 562 | &.aplayer-lrc-current { 563 | height: initial !important; 564 | min-height: 16px; 565 | opacity: 1; 566 | overflow: visible; 567 | } 568 | } 569 | 570 | &.aplayer-lrc-hide { 571 | display: none; 572 | } 573 | 574 | .aplayer-lrc-contents { 575 | width: 100%; 576 | transition: all 0.5s ease-out; 577 | user-select: text; 578 | cursor: default; 579 | } 580 | } 581 | 582 | .aplayer-list { 583 | display: none; 584 | background: #FFF; 585 | transition: all 0.5s ease; 586 | will-change: height; 587 | overflow: hidden; 588 | 589 | &.aplayer-list-hide { 590 | max-height: 0 !important; 591 | border-top: 0 solid #EEE; 592 | } 593 | 594 | ol { 595 | list-style-type: none; 596 | margin: 0; 597 | padding: 0; 598 | overflow-y: auto; 599 | 600 | &::-webkit-scrollbar { 601 | width: 5px; 602 | } 603 | 604 | &::-webkit-scrollbar-thumb { 605 | background-color: #EEE; 606 | border-radius: 3px; 607 | } 608 | 609 | &::-webkit-scrollbar-thumb:hover { 610 | background-color: #CCC; 611 | } 612 | 613 | li { 614 | position: relative; 615 | margin: 0; 616 | padding: 0 15px; 617 | height: 32px; 618 | line-height: 32px; 619 | border-top: 1px solid #E9E9E9; 620 | font-size: 12px; 621 | cursor: pointer; 622 | transition: all 0.2s ease; 623 | overflow: hidden; 624 | 625 | &:first-child { 626 | border-top: none; 627 | } 628 | 629 | &:hover { 630 | background: #EFEFEF; 631 | } 632 | 633 | &.aplayer-list-light { 634 | background: #E9E9E9; 635 | 636 | .aplayer-list-cur { 637 | display: inline-block; 638 | } 639 | } 640 | 641 | .aplayer-list-cur { 642 | display: none; 643 | position: absolute; 644 | top: 5px; 645 | left: 0; 646 | width: 3px; 647 | height: 22px; 648 | cursor: pointer; 649 | } 650 | .aplayer-list-index { 651 | margin-right: 12px; 652 | color: #666; 653 | cursor: pointer; 654 | } 655 | .aplayer-list-author { 656 | float: right; 657 | color: #666; 658 | cursor: pointer; 659 | } 660 | } 661 | } 662 | } 663 | 664 | .aplayer-notice { 665 | opacity: 0; 666 | position: absolute; 667 | top: 50%; 668 | left: 50%; 669 | z-index: 1; 670 | padding: 5px 10px; 671 | background-color: #F4F4F5; 672 | border-radius: 4px; 673 | color: #909399; 674 | font-size: 12px; 675 | transform: translate(-50%, -50%); 676 | transition: all .3s ease-in-out; 677 | overflow: hidden; 678 | pointer-events: none; 679 | } 680 | 681 | .aplayer-miniswitcher { 682 | display: none; 683 | position: absolute; 684 | top: 0; 685 | bottom: 0; 686 | right: 0; 687 | width: 18px; 688 | height: 100%; 689 | background: #E6E6E6; 690 | border-radius: 0 2px 2px 0; 691 | 692 | .aplayer-icon { 693 | height: 100%; 694 | width: 100%; 695 | transform: rotateY(180deg); 696 | transition: all 0.3s ease; 697 | 698 | path { 699 | fill: #666; 700 | } 701 | 702 | &:hover { 703 | path { 704 | fill: #000; 705 | } 706 | } 707 | } 708 | } 709 | } 710 | 711 | @keyframes aplayer-roll { 712 | 0% { left: 0 } 713 | 100% { left: -100% } 714 | } 715 | 716 | @keyframes rotate { 717 | 0% { 718 | transform: rotate(0) 719 | } 720 | 100% { 721 | transform: rotate(360deg) 722 | } 723 | } -------------------------------------------------------------------------------- /src/components/vue-aplayer/utils/utils.js: -------------------------------------------------------------------------------- 1 | const isMobile = /mobile/i.test(window.navigator.userAgent); 2 | 3 | const utils = { 4 | isMobile: isMobile, 5 | eventsName: { 6 | moveStart: isMobile ? 'touchstart' : 'mousedown', 7 | moving: isMobile ? 'touchmove' : 'mousemove', 8 | moveEnd: isMobile ? 'touchend' : 'mouseup', 9 | }, 10 | storage: { 11 | set: (key, value) => { 12 | localStorage.setItem(key, value); 13 | }, 14 | get: (key) => { 15 | localStorage.getItem(key); 16 | } 17 | }, 18 | /** 19 | * Parse Second to Time String 20 | * 21 | * @param {Number} second 22 | * @return {String} 00:00 or 00:00:00 23 | */ 24 | secondToTime: (second) => { 25 | const strMap = (num) => (num < 10 ? '0' + num : '' + num); 26 | const hour = Math.floor(second / 3600); 27 | const min = Math.floor((second - hour * 3600) / 60); 28 | const sec = Math.floor(second - hour * 3600 - min * 60); 29 | return (hour > 0 ? [hour, min, sec] : [min, sec]).map(strMap).join(':'); 30 | }, 31 | randomOrder: (length) => { 32 | function shuffle(arr) { 33 | for (let i = arr.length - 1; i >= 0; i--) { 34 | const randomIndex = Math.floor(Math.random() * (i + 1)); 35 | const itemAtIndex = arr[randomIndex]; 36 | arr[randomIndex] = arr[i]; 37 | arr[i] = itemAtIndex; 38 | } 39 | return arr; 40 | } 41 | return shuffle( 42 | [...Array(length)].map(function(item, i) { 43 | return i; 44 | }) 45 | ); 46 | }, 47 | /** 48 | * Parse Lyric String to Array 49 | * 50 | * @param {String} lyricStr 51 | * @return {Array} [[0, "APlayer"], [1.2, "is"], [34.56, "Amazing"]] 52 | */ 53 | parse (lyricStr) { 54 | if (lyricStr) { 55 | lyricStr = lyricStr.replace(/([^\]^\n])\[/g, (match, p) => p + '\n['); 56 | let lyricArr = lyricStr.split('\n'); 57 | let lyricParseArr = []; 58 | for (let i = 0; i < lyricArr.length; i++) { 59 | // match lrc time 60 | const lrcTimes = lyricArr[i].match(/\[(\d{2}):(\d{2})(\.(\d{2,3}))?]/g); 61 | // match lrc text 62 | const lrcText = lyricArr[i] 63 | .replace(/.*\[(\d{2}):(\d{2})(\.(\d{2,3}))?]/g, '') 64 | .replace(/<(\d{2}):(\d{2})(\.(\d{2,3}))?>/g, '') 65 | .replace(/^\s+|\s+$/g, ''); 66 | 67 | if (lrcTimes) { 68 | // handle multiple time tag 69 | for (let j = 0; j < lrcTimes.length; j++) { 70 | const oneTime = /\[(\d{2}):(\d{2})(\.(\d{2,3}))?]/.exec(lrcTimes[j]); 71 | const min2sec = oneTime[1] * 60; 72 | const sec2sec = parseInt(oneTime[2]); 73 | const msec2sec = oneTime[4] ? parseInt(oneTime[4]) / ((oneTime[4] + '').length === 2 ? 100 : 1000) : 0; 74 | const lrcTime = min2sec + sec2sec + msec2sec; 75 | lyricParseArr.push([lrcTime, lrcText]); 76 | } 77 | } 78 | } 79 | // sort by time 80 | lyricParseArr = lyricParseArr.filter((item) => item[1]); 81 | lyricParseArr.sort((a, b) => a[0] - b[0]); 82 | 83 | return lyricParseArr; 84 | } else { 85 | return []; 86 | } 87 | }, 88 | }; 89 | 90 | export default utils; -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import './style.css' 3 | import App from './App.vue' 4 | 5 | createApp(App).mount('#app') -------------------------------------------------------------------------------- /src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: rgba(255, 255, 255, 0.87); 8 | background-color: #242424; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | } 15 | 16 | a { 17 | font-weight: 500; 18 | color: #646CFF; 19 | text-decoration: inherit; 20 | } 21 | a:hover { 22 | color: #535BF2; 23 | } 24 | 25 | body { 26 | margin: 0; 27 | display: flex; 28 | place-items: center; 29 | min-width: 475px; 30 | min-height: 100vh; 31 | } 32 | 33 | h1 { 34 | font-size: 3.2em; 35 | line-height: 1.1; 36 | } 37 | 38 | button { 39 | border-radius: 8px; 40 | border: 1px solid transparent; 41 | padding: 0.6em 1.2em; 42 | font-size: 1em; 43 | font-weight: 500; 44 | font-family: inherit; 45 | background-color: #1A1A1A; 46 | cursor: pointer; 47 | transition: border-color 0.25s; 48 | } 49 | button:hover { 50 | border-color: #646CFF; 51 | } 52 | button:focus, 53 | button:focus-visible { 54 | outline: 4px auto -webkit-focus-ring-color; 55 | } 56 | 57 | .card { 58 | padding: 2em; 59 | } 60 | 61 | #app { 62 | display: flex; 63 | flex-direction: column; 64 | align-content: center; 65 | justify-content: center; 66 | align-items: center; 67 | flex-wrap: nowrap; 68 | width: 100%; 69 | } 70 | 71 | @media (prefers-color-scheme: light) { 72 | :root { 73 | color: #213547; 74 | background-color: #FFFFFF; 75 | } 76 | a:hover { 77 | color: #747BFF; 78 | } 79 | button { 80 | background-color: #F9F9F9; 81 | } 82 | } -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import viteSVGLoader from 'vite-svg-loader'; 3 | import vue from '@vitejs/plugin-vue'; 4 | import { resolve } from 'path'; 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [vue(), viteSVGLoader()], 9 | build: { 10 | outDir: 'dist', 11 | sourcemap: true, 12 | lib: { 13 | entry: resolve(__dirname, 'src/components/vue-aplayer/index.js'), 14 | name: 'APlayer', 15 | fileName: 'vue-aplayer', 16 | formats: ['es', 'cjs'], 17 | }, 18 | rollupOptions: { 19 | external: ['vue'], 20 | output: { 21 | globals: { 22 | vue: 'Vue', 23 | }, 24 | intro: 'import "./style.css";', 25 | } 26 | }, 27 | } 28 | }) -------------------------------------------------------------------------------- /vite.demo.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import viteSVGLoader from 'vite-svg-loader'; 3 | import vue from '@vitejs/plugin-vue'; 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [vue(), viteSVGLoader()], 8 | build: { 9 | outDir: "demo", 10 | minify: "terser", 11 | } 12 | }) --------------------------------------------------------------------------------