kv-music/package.json
gpulch 8a17bddbc3 feat: add MP3 320kbps download option with ffmpeg.wasm
Implements MP3 320kbps download functionality using ffmpeg.wasm for
industry-standard encoding with libmp3lame.

Features:
- New MP3_320 quality option in download settings UI
- ID3v2.3 metadata writing (title, artist, album, cover art, ISRC, etc.)
- Non-blocking encoding via Web Worker to keep UI responsive
- Proper UTF-16 with BOM text encoding for international characters
- Album artist fallback to track artist (mirrors FLAC/M4A behavior)
- Automatic format detection for downloaded audio
- Year validation to prevent writing NaN to ID3 tags

Implementation:
- mp3-encoder.js: Main encoder module with worker orchestration
- mp3-encoder.worker.js: FFmpeg Web Worker for async encoding
- id3-writer.js: ID3v2.3 tag writer with synchsafe size encoding
- Updates to api.js, metadata.js, utils.js for MP3 support
- Vite config excludes @ffmpeg packages from dep optimization

Technical details:
- Uses @ffmpeg/ffmpeg (libmp3lame 320kbps CBR, 44.1kHz)
- FFmpeg binary lazy-loaded from CDN (~25MB, cached)
- Encoding runs in separate thread (non-blocking UI)
- Proper error handling with distinct encoding vs network errors
- Memory-efficient: transfers ArrayBuffer with zero-copy

Dependencies:
- @ffmpeg/ffmpeg ^0.12.10
- @ffmpeg/util ^0.12.1
- Removed: package-lock.json (project uses bun.lock)

Closes maintainer request to use ffmpeg.wasm instead of lamejs.
2026-02-22 19:13:03 +01:00

60 lines
2.4 KiB
JSON

{
"name": "monochrome",
"type": "module",
"version": "1.0.0",
"description": "[<img src=\"https://github.com/SamidyFR/monochrome/blob/main/assets/512.png?raw=true\" alt=\"Monochrome Logo\">](https://monochrome.samidy.com)",
"main": "sw.js",
"scripts": {
"dev": "vite",
"dev:desktop": "start npm run dev & node scripts/dev-runner.js",
"build": "vite build --mode neutralino && bun x neu build",
"postbuild": "node -e \"const fs = require('fs'); const path = require('path'); const src = 'extensions'; const dest = path.join('dist', 'Monochrome', 'extensions'); if (fs.existsSync(src)) { fs.mkdirSync(dest, { recursive: true }); fs.cpSync(src, dest, { recursive: true }); console.log('Extensions manually copied to ' + dest); }\"",
"preview": "vite preview",
"lint:js": "eslint .",
"lint:css": "stylelint \"**/*.css\"",
"lint:html": "htmlhint \"**/*.html\" --ignore=\"dist/**,legacy/**,node_modules/**\"",
"lint": "npm run lint:js && npm run lint:css && npm run lint:html",
"format": "prettier --write .",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/SamidyFR/monochrome.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/SamidyFR/monochrome/issues"
},
"homepage": "https://github.com/SamidyFR/monochrome#readme",
"devDependencies": {
"@neutralinojs/neu": "^11.7.0",
"eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8",
"globals": "^17.0.0",
"htmlhint": "^1.8.0",
"prettier": "^3.7.4",
"stylelint": "^16.26.1",
"stylelint-config-standard": "^39.0.1",
"stylelint-config-standard-scss": "^16.0.0",
"vite": "^7.3.0",
"vite-plugin-neutralino": "^1.0.3",
"vite-plugin-pwa": "^1.2.0"
},
"overrides": {
"sourcemap-codec": "npm:@jridgewell/sourcemap-codec@^1.4.14",
"source-map": "^0.7.4"
},
"dependencies": {
"@ffmpeg/ffmpeg": "^0.12.10",
"@ffmpeg/util": "^0.12.1",
"@neutralinojs/lib": "^6.5.0",
"butterchurn": "^2.6.7",
"butterchurn-presets": "^2.4.7",
"cookie-session": "^2.1.0",
"dashjs": "^5.1.1",
"jose": "^6.0.11",
"pocketbase": "^0.26.5"
}
}