mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 22:41:09 +02:00
docs+test: add audio format docs and shared-storage utils tests
- Document all supported audio formats in mukke CLAUDE.md with browser compatibility matrix and notes on formats needing transcoding - Add utils.test.ts for shared-storage: MIME type mappings, audio extension validation, and AUDIO_EXTENSIONS completeness checks (19 tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7a1ae1284c
commit
99091ecf9e
2 changed files with 95 additions and 0 deletions
|
|
@ -120,6 +120,28 @@ pnpm --filter @mukke/landing dev # Landing page
|
|||
{ id, lyricsId, lineNumber, text, startTime, endTime }
|
||||
```
|
||||
|
||||
## Supported Audio Formats
|
||||
|
||||
Playback uses HTML5 Audio (browser-native codec support). Upload accepts any `audio/*` MIME type.
|
||||
|
||||
| Format | Extensions | Browser Playback | Notes |
|
||||
|--------|-----------|-----------------|-------|
|
||||
| MP3 | `.mp3` | All browsers | ID3 tag read/write supported |
|
||||
| WAV | `.wav` | All browsers | Uncompressed PCM |
|
||||
| OGG Vorbis | `.ogg` | Chrome, Firefox, Edge | No Safari support |
|
||||
| FLAC | `.flac` | All modern browsers | Lossless |
|
||||
| AAC/M4A | `.aac`, `.m4a` | All browsers | Common iOS format |
|
||||
| OPUS | `.opus` | Chrome, Firefox, Edge | Best quality/size ratio |
|
||||
| WebM | `.webm` | Chrome, Firefox, Edge | Container format |
|
||||
| AIFF | `.aiff`, `.aif` | Safari, Chrome | Common macOS format |
|
||||
| WMA | `.wma` | Edge only | Legacy Windows format |
|
||||
| ALAC | `.alac` | Safari | Apple Lossless |
|
||||
| APE | `.ape` | None natively | Monkey's Audio (upload/metadata only) |
|
||||
| WavPack | `.wv` | None natively | Hybrid lossless (upload/metadata only) |
|
||||
| DSF/DFF | `.dsf`, `.dff` | None natively | DSD audio (upload/metadata only) |
|
||||
|
||||
**Note:** Formats without native browser playback can be uploaded and have metadata extracted (via `music-metadata`), but require server-side transcoding for playback (not yet implemented).
|
||||
|
||||
## Key Technologies
|
||||
|
||||
| Component | Technology |
|
||||
|
|
|
|||
73
packages/shared-storage/src/utils.test.ts
Normal file
73
packages/shared-storage/src/utils.test.ts
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
import { describe, it, expect } from 'vitest';
|
||||
import { getContentType, validateFileExtension, AUDIO_EXTENSIONS } from './utils';
|
||||
|
||||
describe('getContentType', () => {
|
||||
describe('audio formats', () => {
|
||||
const audioMappings: [string, string][] = [
|
||||
['.mp3', 'audio/mpeg'],
|
||||
['.wav', 'audio/wav'],
|
||||
['.ogg', 'audio/ogg'],
|
||||
['.m4a', 'audio/mp4'],
|
||||
['.aac', 'audio/aac'],
|
||||
['.flac', 'audio/flac'],
|
||||
['.aiff', 'audio/aiff'],
|
||||
['.aif', 'audio/aiff'],
|
||||
['.opus', 'audio/opus'],
|
||||
['.wma', 'audio/x-ms-wma'],
|
||||
['.alac', 'audio/mp4'],
|
||||
['.ape', 'audio/x-ape'],
|
||||
['.wv', 'audio/x-wavpack'],
|
||||
['.dsf', 'audio/dsf'],
|
||||
['.dff', 'audio/dff'],
|
||||
];
|
||||
|
||||
it.each(audioMappings)('%s → %s', (ext, expected) => {
|
||||
expect(getContentType(`song${ext}`)).toBe(expected);
|
||||
});
|
||||
|
||||
it('handles uppercase extensions', () => {
|
||||
expect(getContentType('song.FLAC')).toBe('audio/flac');
|
||||
expect(getContentType('song.M4A')).toBe('audio/mp4');
|
||||
});
|
||||
|
||||
it('returns application/octet-stream for unknown extensions', () => {
|
||||
expect(getContentType('song.xyz')).toBe('application/octet-stream');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('AUDIO_EXTENSIONS', () => {
|
||||
it('contains all common audio formats', () => {
|
||||
const expected = [
|
||||
'.mp3',
|
||||
'.wav',
|
||||
'.ogg',
|
||||
'.m4a',
|
||||
'.aac',
|
||||
'.flac',
|
||||
'.aiff',
|
||||
'.aif',
|
||||
'.opus',
|
||||
'.wma',
|
||||
'.webm',
|
||||
'.alac',
|
||||
'.ape',
|
||||
'.wv',
|
||||
'.dsf',
|
||||
'.dff',
|
||||
];
|
||||
for (const ext of expected) {
|
||||
expect(AUDIO_EXTENSIONS).toContain(ext);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('validateFileExtension', () => {
|
||||
it('validates audio files against AUDIO_EXTENSIONS', () => {
|
||||
expect(validateFileExtension('song.flac', AUDIO_EXTENSIONS)).toBe(true);
|
||||
expect(validateFileExtension('song.mp3', AUDIO_EXTENSIONS)).toBe(true);
|
||||
expect(validateFileExtension('song.opus', AUDIO_EXTENSIONS)).toBe(true);
|
||||
expect(validateFileExtension('song.exe', AUDIO_EXTENSIONS)).toBe(false);
|
||||
expect(validateFileExtension('song.pdf', AUDIO_EXTENSIONS)).toBe(false);
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue