diff --git a/apps/web/src/App.test.tsx b/apps/web/src/App.test.tsx index cf3fef0..8e95d85 100644 --- a/apps/web/src/App.test.tsx +++ b/apps/web/src/App.test.tsx @@ -316,10 +316,10 @@ describe('my wave', () => { }); describe('suggest tracks', () => { - it('warns that FLAC and WAV are the formats to send', async () => { + it('warns that lossless formats are the ones to send', async () => { const admin = makeUser('admin', 'admin'); await renderApp([admin], '/uploads/new', { signedInAs: admin }); - expect(await screen.findByText(/Нужны FLAC или WAV/)).toBeInTheDocument(); + expect(await screen.findByText(/Нужны FLAC, WAV или AIFF/)).toBeInTheDocument(); expect(screen.getByText(/MP3 — только в крайнем случае/)).toBeInTheDocument(); }); }); diff --git a/apps/web/src/features/uploads/files.test.ts b/apps/web/src/features/uploads/files.test.ts index 4a2e828..9da1d67 100644 --- a/apps/web/src/features/uploads/files.test.ts +++ b/apps/web/src/features/uploads/files.test.ts @@ -3,10 +3,13 @@ import { describe, expect, it } from 'vitest'; import { needsFormatAttention } from './files'; describe('needsFormatAttention', () => { - it('marks everything except flac and wav', () => { + it('marks everything except lossless formats', () => { expect(needsFormatAttention('flac', 'a.mp3')).toBe(false); expect(needsFormatAttention('WAV', 'track.wav')).toBe(false); expect(needsFormatAttention(null, 'Кино/01.wav')).toBe(false); + expect(needsFormatAttention('aiff', 'a.aif')).toBe(false); + expect(needsFormatAttention(null, 'track.AIFF')).toBe(false); + expect(needsFormatAttention(null, 'track.wv')).toBe(false); expect(needsFormatAttention('mp3', 'a.flac')).toBe(true); expect(needsFormatAttention(null, 'folder/song.MP3')).toBe(true); expect(needsFormatAttention(null, 'song.m4a')).toBe(true); diff --git a/apps/web/src/features/uploads/files.ts b/apps/web/src/features/uploads/files.ts index 7e89ceb..ae6af72 100644 --- a/apps/web/src/features/uploads/files.ts +++ b/apps/web/src/features/uploads/files.ts @@ -9,7 +9,8 @@ export interface PickedFile { export const AUDIO_EXTENSIONS = ['flac', 'mp3', 'm4a', 'ogg', 'opus', 'wav', 'aiff', 'aif', 'wv']; /** То, что просим присылать. MP3 и прочие — крайний случай, их помечает очередь. */ -const PREFERRED_AUDIO = new Set(['flac', 'wav']); +// Lossless — как в quality.go на сервере. +const PREFERRED_AUDIO = new Set(['flac', 'wav', 'aiff', 'aif', 'wv']); export function audioExt(name: string): string { const base = name.split(/[/\\]/).pop() ?? name; @@ -18,7 +19,7 @@ export function audioExt(name: string): string { return base.slice(dot + 1).toLowerCase(); } -/** Не FLAC и не WAV: в очереди на добавление такой файл нужно выделить. */ +/** Не lossless (FLAC, WAV, AIFF, WavPack): в очереди на добавление такой файл нужно выделить. */ export function needsFormatAttention(format: string | null | undefined, name: string): boolean { const ext = (format || audioExt(name)).toLowerCase(); return ext !== '' && !PREFERRED_AUDIO.has(ext); diff --git a/docs/uploads.md b/docs/uploads.md index e0f48e2..8d39511 100644 --- a/docs/uploads.md +++ b/docs/uploads.md @@ -84,7 +84,7 @@ до 4 параллельных загрузок, прогресс по каждому файлу. - Мобильный клиент загрузку не поддерживает (первая версия). - Staging — локальный диск сервера `/srv/pipu/uploads//` (не NFS). -- Разрешённые форматы: `flac mp3 m4a ogg opus wav aiff wv`. Просим присылать **FLAC или WAV**; MP3 и остальные — крайний случай: форма предупреждает об этом, а очередь на добавление помечает такой файл «обратить внимание». Проверяется не расширение, а содержимое (`ffprobe`): +- Разрешённые форматы: `flac mp3 m4a ogg opus wav aiff wv`. Просим присылать lossless — **FLAC, WAV или AIFF** (WavPack тоже считается lossless); MP3 и остальные lossy — крайний случай: форма предупреждает об этом, а очередь на добавление помечает такой файл «обратить внимание». Проверяется не расширение, а содержимое (`ffprobe`): должен быть ровно один аудиопоток, длительность 5 с – 3 ч. Иначе `invalid` с кодом причины. - Допускается отдельная картинка обложки (`cover.jpg|png`) в той же пачке — привязывается к файлам той же папки. diff --git a/packages/i18n/locales/en/admin.json b/packages/i18n/locales/en/admin.json index 174447f..c66aaa5 100644 --- a/packages/i18n/locales/en/admin.json +++ b/packages/i18n/locales/en/admin.json @@ -200,9 +200,9 @@ "suggest_title": "Suggest tracks", "suggest_subtitle": "Files go to the upload queue; an administrator reviews them and places them into a storage", "drop_title": "Drop music files or folders here", - "drop_hint": "Use FLAC or WAV. MP3 only as a last resort: the quality is worse, and the queue marks that file “needs attention”.", + "drop_hint": "Use FLAC, WAV or AIFF. MP3 only as a last resort: the quality is worse, and the queue marks that file “needs attention”.", "drop_folders": "Folder structure helps guess the artist and album.", - "format_attention": "Not FLAC or WAV. Send MP3 only when there is no lossless file.", + "format_attention": "Not lossless (FLAC, WAV, AIFF). Send MP3 only when there is no lossless file.", "pick_files": "Choose files", "pick_folder": "Choose folder", "files": "Files to send", diff --git a/packages/i18n/locales/ru/admin.json b/packages/i18n/locales/ru/admin.json index 4779400..f8e4a86 100644 --- a/packages/i18n/locales/ru/admin.json +++ b/packages/i18n/locales/ru/admin.json @@ -200,9 +200,9 @@ "suggest_title": "Предложить треки", "suggest_subtitle": "Файлы попадут в очередь на добавление; администратор проверит и разложит их в хранилище", "drop_title": "Перетащите сюда файлы или папки с музыкой", - "drop_hint": "Нужны FLAC или WAV. MP3 — только в крайнем случае: качество хуже, и в очереди такой файл помечается «обратить внимание».", + "drop_hint": "Нужны FLAC, WAV или AIFF. MP3 — только в крайнем случае: качество хуже, и в очереди такой файл помечается «обратить внимание».", "drop_folders": "Структура папок поможет угадать исполнителя и альбом.", - "format_attention": "Не FLAC и не WAV. MP3 присылайте, только если lossless нет.", + "format_attention": "Не lossless (FLAC, WAV, AIFF). MP3 присылайте, только если lossless нет.", "pick_files": "Выбрать файлы", "pick_folder": "Выбрать папку", "files": "Файлы для отправки",