Changeset 834bcc3 in Klonkt for src/routes/admin-audio.js
- Timestamp:
- 06/23/2026 06:14:27 PM (3 months ago)
- Branches:
- main
- Children:
- d774679
- Parents:
- bb42dfb
- File:
-
- 1 edited
-
src/routes/admin-audio.js (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/routes/admin-audio.js
rbb42dfb r834bcc3 38 38 const ALLOWED_AUDIO_EXT = new Set(['.mp3', '.m4a', '.mp4', '.aac', '.oga', '.ogg', '.opus', '.flac', '.wav', '.webm']); 39 39 const ALLOWED_COVER_EXT = new Set(['.jpg', '.jpeg', '.png', '.webp', '.gif']); 40 const MAX_AUDIO_BYTES = 50 * 1024 * 1024; // 50 MB — gecomprimeerde formaten(mp3/m4a/ogg/…)41 const MAX_WAV_BYTES = 100 * 1024 * 1024; // 100 MB — WAV is ongecomprimeerd, dus ruimer40 const MAX_AUDIO_BYTES = 50 * 1024 * 1024; // 50 MB — compressed formats (mp3/m4a/ogg/…) 41 const MAX_WAV_BYTES = 100 * 1024 * 1024; // 100 MB — WAV is uncompressed, so a higher limit 42 42 const MAX_COVER_BYTES = 5 * 1024 * 1024; // 5 MB 43 43 44 // Per- bestand bovengrens op basis van extensie. multer's globale limiet is de45 // h oogste (WAV); de echte controle per type gebeurt in de upload-handler.44 // Per-file upper limit based on extension. multer's global limit is the 45 // highest (WAV); the real per-type check happens in the upload handler. 46 46 const audioByteLimitFor = (ext) => (ext.toLowerCase() === '.wav' ? MAX_WAV_BYTES : MAX_AUDIO_BYTES); 47 47 … … 59 59 const upload = multer({ 60 60 storage, 61 limits: { fileSize: MAX_WAV_BYTES }, // h oogste bovengrens (WAV) — per-type check in de handler61 limits: { fileSize: MAX_WAV_BYTES }, // highest upper bound (WAV) — per-type check in the handler 62 62 fileFilter: (req, file, cb) => { 63 63 const ext = path.extname(file.originalname).toLowerCase(); … … 73 73 const router = express.Router(); 74 74 75 // "Open in" -platformlinks per track: alleen https + de juiste host accepteren76 // (href komt ongeescaped in de view → scheme/host-guard tegen misbruik).75 // "Open in" platform links per track: only https + the correct host accepted 76 // (href arrives unescaped in the view → scheme/host guard against abuse). 77 77 const LINK_DOMAINS = { 78 78 spotify: ['spotify.com'], … … 86 86 const h = new URL(u).hostname.toLowerCase(); 87 87 if (domains.some((d) => h === d || h.endsWith('.' + d))) return u; 88 } catch (e) { /* ongeldigeURL */ }88 } catch (e) { /* invalid URL */ } 89 89 return null; 90 90 } … … 148 148 } 149 149 150 // Per-type audio size check. multer's global e limiet was de WAV-bovengrens151 // (100MB); gecomprimeerde formaten blijven op50MB.150 // Per-type audio size check. multer's global limit was the WAV upper bound 151 // (100MB); compressed formats stay at 50MB. 152 152 const audioExt = path.extname(audioFile.originalname).toLowerCase(); 153 153 const audioLimit = audioByteLimitFor(audioExt); … … 185 185 const finalArtist = artist?.trim() || null; 186 186 const finalAlbum = album?.trim() || null; 187 // Eigenaarschap/licentie. credit valt terug op de artiest; deze gaan zowel de188 // DB in als de ID3-tags van de mp3 (copyright + comment).187 // Ownership/licence. credit falls back to the artist; these go both into the 188 // DB and into the ID3 tags of the mp3 (copyright + comment). 189 189 const finalCredit = (req.body.credit || '').trim() || finalArtist || null; 190 190 const finalLicense = (req.body.license || '').trim() || null; … … 231 231 `).run(mediaId, site.id, transcoded.filename, transcoded.mimeType, transcoded.size, transcoded.path); 232 232 233 // Du ur automatisch: primair uit de transcode (ffmpeg codecData), anders een234 // optionele client-side waarde (bulk-uploader leest <audio>.duration uit),235 // anders NULL (UI toont dan '—:—', handmatig bij te werken in de editor).233 // Duration automatically: primarily from the transcode (ffmpeg codecData), then 234 // an optional client-side value (bulk uploader reads <audio>.duration), 235 // otherwise NULL (UI then shows '—:—', editable manually in the editor). 236 236 const clientDur = req.body.duration != null ? parseInt(req.body.duration, 10) : NaN; 237 237 const finalDuration = … … 275 275 }); 276 276 277 // Download- voor-email per track aan/uit (premium #2). Zonder-JS toggle vanaf de278 // audio -beheerlijst → flip + terug.277 // Download-for-email per track on/off (premium #2). No-JS toggle from the 278 // audio admin list → flip + back. 279 279 router.post('/:id/downloadable', requireGod, (req, res) => { 280 280 const site = res.locals.site; … … 394 394 395 395 /** GET /admin/audio/api/:id — single track with all metadata */ 396 // Maak een track ZONDER audiobestand (alleen titel + open-in links). Verschijnt397 // in albums/playlists in de lijst, met open-in-iconen maar zonder afspeelknop.396 // Create a track WITHOUT an audio file (title + open-in links only). Appears 397 // in albums/playlists in the list, with open-in icons but no play button. 398 398 router.post('/create-link', requireGod, express.json(), (req, res) => { 399 399 const site = res.locals.site; … … 507 507 } 508 508 509 // Verse rij + (als tag-velden wijzigden) de mp3 her-taggen, zodat de eigenaar/510 // licen tie ook IN het bestand staat (ID3) en meereist bij een download.509 // Fresh row + (if tag fields changed) retag the mp3, so that the owner/ 510 // licence is also IN the file (ID3) and travels with it on download. 511 511 const fresh = db.prepare(` 512 512 SELECT t.id, t.title, t.artist, t.album, t.duration, t.cover_url, t.credit, t.license, m.storage_path … … 527 527 } }); 528 528 } catch (e) { 529 console.warn('[admin-audio] ID3 her-taggen mislukt (DB is wel bijgewerkt):', e.message);529 console.warn('[admin-audio] ID3 retag failed (DB was still updated):', e.message); 530 530 } 531 531 }
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)