add music-ibrary n test

This commit is contained in:
Djkato 2023-05-29 21:42:35 +02:00
parent decce4a910
commit d269605f55
20 changed files with 801 additions and 65 deletions

View file

@ -3,8 +3,9 @@
"version": "0.0.0",
"license": "MIT",
"scripts": {
"publish-player": "cd dist/packages/player && npm publish --access=public",
"publish-visualizer": "cd dist/packages/visualizer && npm publish --access=public"
"publish-player": "nx build player && cd dist/packages/player && npm publish --access=public",
"publish-visualizer": "nx build visualizer && cd dist/packages/visualizer && npm publish --access=public",
"publish-library": "nx build music-library && cd dist/packages/music-library && npm publish --access=public"
},
"private": false,
"devDependencies": {

View file

@ -0,0 +1,33 @@
{
"extends": [
"../../.eslintrc.json"
],
"ignorePatterns": [
"!**/*"
],
"overrides": [
{
"files": [
"*.ts",
"*.tsx",
"*.js",
"*.jsx"
],
"rules": {}
},
{
"files": [
"*.ts",
"*.tsx"
],
"rules": {}
},
{
"files": [
"*.js",
"*.jsx"
],
"rules": {}
}
]
}

View file

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>MusicLibraryTest</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<link rel="stylesheet" href="/src/styles.css" />
</head>
<body>
<div class="name-wrapper">
<p>playing:&nbsp;&nbsp;
<p id="text-playing"> ID</p>
</p>
</div>
<div class="wrapper">
<audio src="" id="audio"></audio>
<button id="previous">Previous Song</button>
<button id="play">Play</button>
<button id="pause">Pause</button>
<button id="toggle-play">Toggle Pause/Play</button>
<button id="next">Next Song</button>
<p id="current">-:--</p>
<input type="range" min="0" max="10" value="0" id="seek" step="0.01">
<p id="duration">-:--</p>
<span>
<input type="range" min="0" max="1" value="1" id="volume" step="0.01">
</span>
<button id="mute">Mute</button>
<button id="unmute">Unmute</button>
<button id="toggle-mute">Toggle Mute</button>
</div>
<script type="module" src="/src/db.ts"></script>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

View file

@ -0,0 +1,70 @@
{
"name": "music-library-web-test",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"sourceRoot": "packages/music-library-web-test/src",
"tags": [],
"targets": {
"build": {
"executor": "@nx/vite:build",
"outputs": [
"{options.outputPath}"
],
"defaultConfiguration": "production",
"options": {
"outputPath": "dist/packages/music-library-web-test"
},
"configurations": {
"development": {
"mode": "development"
},
"production": {
"mode": "production"
}
}
},
"serve": {
"executor": "@nx/vite:dev-server",
"defaultConfiguration": "development",
"options": {
"buildTarget": "music-library-web-test:build"
},
"configurations": {
"development": {
"buildTarget": "music-library-web-test:build:development",
"hmr": true
},
"production": {
"buildTarget": "music-library-web-test:build:production",
"hmr": false
}
}
},
"preview": {
"executor": "@nx/vite:preview-server",
"defaultConfiguration": "development",
"options": {
"buildTarget": "music-library-web-test:build"
},
"configurations": {
"development": {
"buildTarget": "music-library-web-test:build:development"
},
"production": {
"buildTarget": "music-library-web-test:build:production"
}
}
},
"lint": {
"executor": "@nx/linter:eslint",
"outputs": [
"{options.outputFile}"
],
"options": {
"lintFilePatterns": [
"packages/music-library-web-test/**/*.ts"
]
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

View file

@ -0,0 +1,50 @@
import { DB, Artist, Song, RefTo, Ref, Platforms } from "@euterpe/music-library";
export const db = new DB
db.add([
//The IDs are added incrementally & are 0 based., so first artists ID added is 0, next 1 etc...
//You can specify the ID manually if you want
new Artist({
name: "Jamie xx",
}),
new Artist({
name: "janz",
}),
new Artist({
name: "Machinedrum",
}),
new Artist({
name: "Tanerélle",
}),
new Artist({
name: "Mono/Poly",
}),
new Artist({
name: "IMANU",
links: [
[Platforms.Spotify, new URL("https://open.spotify.com/artist/5Y7rFm0tiJTVDzGLMzz0W1?si=DRaZyugTTIqlBHDkMGKVqA&nd=1")]
]
})])
db.add([
new Song({
//Refrences are constructed as such. This allows to get to the artist from either collection or song
artists: [new Ref(RefTo.Artists, 2), new Ref(RefTo.Artists, 3), new Ref(RefTo.Artists, 4)],
duration: 252,
name: "Star",
remix_artists: [new Ref(RefTo.Artists, 5)],
url: new URL("http://127.0.0.1:4200/Machinedrum, Tanerelle & Mono Poly - Star (IMANU Remix) final.mp3")
}),
new Song({
//If you don't like guessing the IDs, then this is also a way to do it
artists: [new Ref(RefTo.Artists, db.artists.find((a) => a.name == "Jamie xx")!.id!)],
duration: 331,
name: "Sleep Sound",
url: new URL("http://127.0.0.1:4200/Jamie xx - Sleep Sound.mp3")
}),
new Song({
artists: [new Ref(RefTo.Artists, 1)],
duration: 75,
name: "wish",
url: new URL("http://127.0.0.1:4200/janz - wish.mp3")
})
])

View file

@ -0,0 +1,116 @@
import { MusicPlayerBuilder } from "@euterpe/player";
import { db } from "./db";
import { Artist } from "@euterpe/music-library";
import { DB, Platforms } from "@euterpe/music-library";
const audio_el = document.querySelector("#audio") as HTMLAudioElement
const music_player_builder = MusicPlayerBuilder(audio_el)
music_player_builder.start()
const music_player = music_player_builder.build()
music_player.change_volume(1)
let curr_song_id = 1;
const elem_curr_song = document.querySelector("#text-playing")
music_player.try_new_song_async(db.songs[curr_song_id].url.pathname)
.then(() => {
let is_seeking = false
change_current_song_text(db)
document.querySelector("#previous")?.addEventListener("click", () => {
curr_song_id--
if (curr_song_id < 0) curr_song_id = 2
music_player.try_new_song_async(db.songs[curr_song_id].url.pathname).then((s) => {
change_current_song_text(db)
music_player.play_async().catch((err) => { console.log(err) })
}, (e) => { console.log(e) })
})
document.querySelector("#next")?.addEventListener("click", () => {
curr_song_id++
if (curr_song_id > 2) curr_song_id = 0
music_player.try_new_song_async(db.songs[curr_song_id].url.pathname).then((s) => {
change_current_song_text(db)
music_player.play_async().catch((err) => { console.log(err) })
}, (e) => { console.log(e) })
})
document.querySelector("#play")?.addEventListener("click", () => {
music_player.play_async()
.then(() => { console.log("Playing!") }, (e) => alert("Failed to play, " + e))
})
document.querySelector("#pause")?.addEventListener("click", () => {
music_player.pause()
})
document.querySelector("#mute")?.addEventListener("click", () => {
music_player.mute()
})
document.querySelector("#unmute")?.addEventListener("click", () => {
music_player.unmute()
})
document.querySelector("#toggle-mute")?.addEventListener("click", () => {
music_player.mute_toggle()
})
document.querySelector("#toggle-play")?.addEventListener("click", () => {
music_player.play_toggle_async().then((s) => console.log("toggled play/pause"), (e) => alert("failed to toggle pause/play!" + e))
})
document.querySelector("#volume")?.addEventListener("input", (e) => {
music_player.change_volume(e.target?.valueAsNumber)
})
document.querySelector("#seek")?.addEventListener("mousedown", (e) => {
is_seeking = true;
})
document.querySelector("#seek")?.addEventListener("mouseup", (e) => {
music_player.try_seek_async(e.target?.valueAsNumber).then(() => { console.log("seeked to " + e.target?.valueAsNumber) }, () => {
alert("Failed seeking! " + e)
})
is_seeking = false
})
// Subscriptions to AudioContext changes, eg. time..
music_player.subscribe_to_formatted_duration_time((time) => {
document.querySelector("#duration").innerHTML = time
document.querySelector("#seek").max = "" + music_player.get_current_duration()
})
music_player.subscribe_to_formatted_current_time_tick((time) => {
document.querySelector("#current").innerHTML = time
})
music_player.subscribe_to_time_tick((time) => {
if (is_seeking) return
document.querySelector("#seek").value = "" + time
})
}, (e) => console.log(e))
function change_current_song_text(db: DB) {
const curr_song = db.songs[curr_song_id]
let final_text = ""
for (const artist of curr_song.artists) {
const curr_artist = artist.get(db) as Artist
final_text += curr_artist.name + ", "
}
final_text = final_text.slice(0, final_text.length - 2) // remove trailing ", "
final_text += " - " + curr_song.name
if (curr_song.remix_artists.length > 0) {
final_text += " ("
for (const artist of curr_song.remix_artists) {
const curr_artist = artist.get(db) as Artist
if (curr_artist.links && curr_artist.links.length > 0) {
//returns "found a link! Spotify"
console.log("found a link! " + Platforms[curr_artist.links[0][0]])
const url = curr_artist.links[0][1]
final_text += `<a href=${url}>${curr_artist.name}</a>, `
} else {
final_text += curr_artist.name + ", "
}
}
final_text = final_text.slice(0, final_text.length - 2) // remove trailing ", "
final_text += " Remix)"
}
elem_curr_song!.innerHTML = final_text
}

View file

@ -0,0 +1,23 @@
#volume{
transform: rotate(270deg);
}
body {
width: 100vw;
height:100vh;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.wrapper{
width:80vw;
display: flex;
justify-content: space-between;
}
.name-wrapper{
width:80vw;
display: flex;
justify-content: center;
}

View file

@ -0,0 +1,29 @@
{
"extends": "../../tsconfig.base.json",
"files": [],
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": [
"ESNext",
"DOM"
],
"moduleResolution": "Node",
"strict": true,
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
"noEmit": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"skipLibCheck": true,
"types": [
"vite/client"
]
},
"include": [
"src"
],
}

View file

@ -0,0 +1,33 @@
/// <reference types="vitest" />
import { defineConfig } from "vite"
import viteTsConfigPaths from "vite-tsconfig-paths"
export default defineConfig({
cacheDir: "../../node_modules/.vite/music-library-web-test",
server: {
port: 4200,
host: "localhost"
},
preview: {
port: 4300,
host: "localhost"
},
plugins: [
viteTsConfigPaths({
root: "../../"
})
]
// Uncomment this if you are using workers.
// worker: {
// plugins: [
// viteTsConfigPaths({
// root: '../../',
// }),
// ],
// },
})

View file

@ -1,13 +1,154 @@
# music-library
This library was generated with [Nx](https://nx.dev).
A simple music library, acting as a Local DB as JS Object. Contains everything a person would need to store their music data for website playback.
## How to use:
#### Simple demo using euterpe player [here](https://github.com/euterpe-js/euterpe-source/tree/master/packages/music-library-web-test)
## Building
Recommended to make a db.ts file where one instanciates their database, then exports it for use elsewhere.
Run `nx build music-library` to build the library.
`db.ts`
```ts
import { DB, Artist, Song, RefTo, Ref, Platforms } from "@euterpe/music-library";
export const db = new DB
db.add([
//The IDs are added incrementally & are 0 based., so first artists ID added is 0, next 1 etc...
//You can specify the ID manually if you want
new Artist({
name: "Jamie xx",
}),
new Artist({
name: "Machinedrum",
}),
new Artist({
name: "Tanerélle",
}),
new Artist({
name: "Mono/Poly",
}),
new Artist({
name: "IMANU",
links: [
[Platforms.Spotify, new URL("https://open.spotify.com/artist/5Y7rFm0tiJTVDzGLMzz0W1?si=DRaZyugTTIqlBHDkMGKVqA&nd=1")]
]
})])
db.add([
new Song({
//Refrences are constructed as such. This allows to get to the artist from either collection or song
artists: [new Ref(RefTo.Artists, 2), new Ref(RefTo.Artists, 3), new Ref(RefTo.Artists, 4)],
duration: 252,
name: "Star",
remix_artists: [new Ref(RefTo.Artists, 5)],
url: new URL("http://127.0.0.1:4200/Machinedrum, Tanerelle & Mono Poly - Star (IMANU Remix) final.mp3")
}),
new Song({
//If you don't like guessing the IDs, then this is also a way to do it
artists: [new Ref(RefTo.Artists, db.artists.find((a) => a.name == "Jamie xx")!.id!)],
duration: 331,
name: "Sleep Sound",
url: new URL("http://127.0.0.1:4200/Jamie xx - Sleep Sound.mp3")
}),
])
```
And then we can easily get any data we want elsewhere, like:
`main.ts`
```ts
import { db } from "./db";
let curr_song_id = 1;
// Some buttons in the DOM to act on the library, snippet is using euterpe-js/player
document.querySelector("#previous")?.addEventListener("click", () => {
curr_song_id--
if (curr_song_id < 0) curr_song_id = 2
music_player.try_new_song_async(db.songs[curr_song_id].url.pathname).then((s) => {
change_current_song_text(db)
music_player.play_async().catch((err) => { console.log(err) })
}, (e) => { console.log(e) })
})
document.querySelector("#next")?.addEventListener("click", () => {
curr_song_id++
if (curr_song_id > 2) curr_song_id = 0
music_player.try_new_song_async(db.songs[curr_song_id].url.pathname).then((s) => {
change_current_song_text(db)
music_player.play_async().catch((err) => { console.log(err) })
}, (e) => { console.log(e) })
})
```
Example on how to produce final titles:
* If the current song has multiple titles, add them with `, ` between, then append " - " and song name.
* If the song has remix artists, we add a " (", add all artists with ", " between, and even make them link to artists' links if there are some.
* Results with given db:
- `Machinedrum, Tanerélle, Mono/Poly - Star (<a href="{{spotify link}}">IMANU</a> Remix)`
- `Jamie xx - Sleep Sound`
```ts
function change_current_song_text(db: DB) {
const curr_song = db.songs[curr_song_id]
let final_text = ""
for (const artist of curr_song.artists) {
const curr_artist = artist.get(db) as Artist
final_text += curr_artist.name + ", "
}
final_text = final_text.slice(0, final_text.length - 2) // remove trailing ", "
final_text += " - " + curr_song.name
if (curr_song.remix_artists.length > 0) {
final_text += " ("
for (const artist of curr_song.remix_artists) {
const curr_artist = artist.get(db) as Artist
if (curr_artist.links && curr_artist.links.length > 0) {
//returns "found a link! Spotify"
console.log("found a link! " + Platforms[curr_artist.links[0][0]])
const url = curr_artist.links[0][1]
final_text += `<a href=${url}>${curr_artist.name}</a>, `
} else {
final_text += curr_artist.name + ", "
}
}
final_text = final_text.slice(0, final_text.length - 2) // remove trailing ", "
final_text += " Remix)"
}
elem_curr_song!.innerHTML = final_text
}
```
What data this database stores right now:
```ts
class Song {
name: string
artists: Ref[] //Ref(RefTo.Artist, {ID})
url: URL
duration: number
remix_artists: Ref[] //Ref(RefTo.Artist, {ID})
publish_date?: Date
in_collection?: Ref //Ref(RefTo.Collection, {ID})
cover?: URL
bpm?: number
key?: string
fft_data?: number[]
id?: ID
}
class Artist {
name = ""
pfp?: URL
songs: Ref[] //Ref(RefTo.Song, {ID})
collections: Ref[] //Ref(RefTo.Collection, {ID})
links?: [Platforms, URL][]
id?: ID
}
//can be used as EP, Album etc...
class Collection {
artists: Ref[] //Ref(RefTo.Artist, {ID})
songs: Ref[] //Ref(RefTo.Song, {ID})
cover: URL
duration: number
publish_date?: Date
id?: ID
}
```

View file

@ -1,5 +1,33 @@
{
"name": "@euterpe-js/music-library",
"version": "0.0.1",
"type": "commonjs"
"name": "@euterpe.js/music-library",
"version": "1.0.1",
"type": "module",
"description": "A simple music library, acting as a Local DB as JS Object. Contains everything a person would need to store their music data for website playback.",
"main": "./src/index.js",
"author": {
"name": "Djkáťo",
"email": "djkatovfx@gmail.com"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/euterpe-js/euterpe-source.git"
},
"homepage": "https://github.com/euterpe-js/euterpe-source/tree/master/packages/music-library#readme",
"keywords": [
"audio",
"library",
"music-database",
"audio-player",
"webaudio",
"database",
"db"
],
"exports": {
".": {
"types": "./src/index.d.ts",
"import": "./src/index.js",
"require": "./src/lib/music-library.js"
}
}
}

View file

@ -34,6 +34,12 @@
"packages/music-library/**/*.ts"
]
}
},
"run": {
"dependsOn": [
"build"
],
"command": "node ./dist/packages/music-library/src/index.js"
}
},
"tags": []

View file

@ -1,65 +1,227 @@
import { writeFile, readFile } from "node:fs"
export {
RefTo,
Ref,
Song,
Collection,
DB,
Artist,
Platforms
}
type ID = number
type URL = string
enum RefTo {
Artists,
Songs,
Collections
}
enum Platforms {
Youtube,
Linktree,
Bandcamp,
Spotify,
Portfolio,
BeatPort,
SoundCloud,
Youtube = "Youtube",
Linktree = "Linktree",
Bandcamp = "Bandcamp",
Spotify = "Spotify",
Portfolio = "Portfolio",
BeatPort = "BeatPort",
SoundCloud = "SoundCloud",
Instagram = "Instagram",
Patreon = "Patreon",
Twitter = "Twitter",
Facebook = "Facebook",
}
type Ref<T> = [T, ID]
type Song = {
id: ID,
name: string,
artists: Ref<RefTo.Artists>[],
url: URL,
publish_date?: Date,
remix_artists?: Ref<RefTo.Artists>[],
in_collection?: Ref<RefTo.Collections>,
cover?: URL,
duration: number,
bpm?: number,
key?: string,
class Ref {
constructor(public to: RefTo, public id: ID) { }
get(from: DB) {
switch (this.to) {
case RefTo.Artists: {
return from.artists.find((artist) => artist.id == this.id)
}
case RefTo.Songs: {
return from.songs.find((song) => song.id == this.id)
}
case RefTo.Collections: {
return from.collections.find((col) => col.id = this.id)
}
}
}
}
interface SongConstructor {
name: string
artists: Ref[]
url: URL
duration: number
publish_date?: Date
remix_artists?: Ref[]
in_collection?: Ref
cover?: URL
bpm?: number
key?: string
fft_data?: number[]
id?: ID
}
type Artist = {
id: ID,
name: string,
pfp?: URL,
songs?: Ref<RefTo.Songs>[],
collections?: Ref<RefTo.Collections>[],
links: [Platforms, URL][],
class Song {
name: string
artists: Ref[]
url: URL
duration: number
remix_artists: Ref[]
publish_date?: Date
in_collection?: Ref
cover?: URL
bpm?: number
key?: string
fft_data?: number[]
/**
* The ID is always there, don't worry :)
*/
id?: ID
constructor(data: SongConstructor) {
this.name = data.name
this.artists = data.artists || []
this.url = data.url
this.duration = data.duration
this.publish_date = data.publish_date
this.remix_artists = data.remix_artists || []
this.in_collection = data.in_collection
this.cover = data.cover
this.bpm = data.bpm
this.key = data.key
this.fft_data = data.fft_data
this.id = data.id
}
type Collection = {
id: ID,
publish_date?: Date,
artists: Ref<RefTo.Artists>[],
songs: Ref<RefTo.Songs>[],
cover: URL,
duration: number,
}
type DB = {
artists?: Artist[],
songs?: Song[],
Collections?: Collection[],
}
const db: DB = {}
db.songs?.push(
{
id: 0,
artists: [RefTo.Artists, 0] as Ref<RefTo.Artists>,
duration: 13,
songs: [RefTo.Songs, 0] as Ref<RefTo.Songs>,
name: "Just the two of us",
url: "Huehue" as URL,
} as Song)
interface ArtistConstructor {
name: string,
pfp?: URL
songs?: Ref[]
collections?: Ref[]
links?: [Platforms, URL][]
id?: ID
}
class Artist {
name = ""
pfp?: URL
songs: Ref[]
collections: Ref[]
links?: [Platforms, URL][]
/**
* The ID is always there, don't worry :)
*/
id?: ID
constructor(data: ArtistConstructor) {
this.name = data.name
this.pfp = data.pfp
this.songs = data.songs || []
this.collections = data.collections || []
this.links = data.links
this.id = data.id
}
}
interface CollectionConstructor {
artists: Ref[]
songs: Ref[]
cover: URL
duration: number
publish_date?: Date
id?: ID
}
class Collection {
artists: Ref[]
songs: Ref[]
cover: URL
duration: number
publish_date?: Date
/**
* The ID is always there, don't worry :)
*/
id?: ID
constructor(data: CollectionConstructor) {
this.artists = data.artists
this.songs = data.songs
this.cover = data.cover
this.duration = data.duration
this.publish_date = data.publish_date
this.id = data.id
}
}
class DB {
artists: Artist[] = []
songs: Song[] = []
collections: Collection[] = []
add(song: Song[]): void
add(artist: Artist[]): void
add(collection: Collection[]): void
add(mix: (Song | Artist | Collection)[]): void
add(stuff: Artist[] | Collection[] | Song[] | (Song | Artist | Collection)[]) {
/** All of this adds refrences to the other side of whatever is being added.
* eg. adding song with refrence to artist, adds refrence of song to artist
* and adds incremental ids
*/
for (const input of stuff) {
if (input instanceof Artist) {
const artist = input as Artist
if (!artist.id) artist.id = this.artists.length
this.artists.push(artist)
for (const song_ref of artist.songs) {
const curr_song = song_ref.get(this) as Song
curr_song?.artists.push(new Ref(RefTo.Artists, artist.id))
}
for (const col_ref of artist.collections) {
const curr_col = col_ref.get(this) as Collection
curr_col?.artists.push(new Ref(RefTo.Artists, artist.id))
}
}
else if (input instanceof Collection) {
const col = input as Collection
if (!col.id) col.id = this.collections.length
this.collections.push(col)
for (const song_ref of col.songs) {
const curr_song = song_ref.get(this) as Song
curr_song.in_collection = new Ref(RefTo.Collections, col.id)
}
for (const artist_ref of col.artists) {
const curr_artist = artist_ref.get(this) as Artist
curr_artist.collections.push(new Ref(RefTo.Collections, col.id))
}
}
else if (input instanceof Song) {
const song = input as Song
if (!song.id) song.id = this.songs.length
this.songs.push(song)
if (song.in_collection) {
const curr_col = song.in_collection.get(this) as Collection
curr_col?.songs.push(new Ref(RefTo.Songs, song.id))
}
for (const artist_ref of song.artists) {
const curr_artist = artist_ref.get(this) as Artist
curr_artist.songs.push(new Ref(RefTo.Songs, song.id))
}
}
}
}
}
// const db = new DB
// db.add(
// new Artist({
// name: "djkato",
// })
// )
// db.add(
// new Song({
// name: "Hihaa",
// artists: [new Ref(RefTo.Artists, db.artists.find((a) => a.name == "djkato")!.id!)],
// duration: 123,
// url: new URL("http://Smt.com/efsse.mp3")
// })
// )
// console.dir(db, { depth: null })
// const res = db.artists[0].songs[0].get(db) as Song
// console.log(`${db.artists[0].name} has song ${db.songs[0].name}? : ${res.name} is there!`)

View file

@ -292,7 +292,7 @@ export const MusicPlayer = (audio_context_i: AudioContext, audio_element_i: HTML
controller.abort()
reject(e)
}, { signal: controller.signal })
/*
audio_element.addEventListener("abort", function abort_listener(e) {
controller.abort()
reject(e)
@ -302,6 +302,7 @@ export const MusicPlayer = (audio_context_i: AudioContext, audio_element_i: HTML
controller.abort()
reject(e)
}, { signal: controller.signal })
*/
is_playing = false
})
}

View file

@ -18,7 +18,7 @@
"skipDefaultLibCheck": true,
"baseUrl": ".",
"paths": {
"@euterpe-js/music-library": [
"@euterpe/music-library": [
"packages/music-library/src/index.ts"
],
"@euterpe/player": [