232 lines
9.0 KiB
Markdown
232 lines
9.0 KiB
Markdown
# Скачивание музыки — практики и инструменты
|
||
|
||
Документ составлен по итогам сессии загрузки ~165 треков на SD-карту (май 2026).
|
||
|
||
## Источники — рейтинг эффективности
|
||
|
||
### ⭐⭐⭐ hitmotop.com — основной рабочий инструмент
|
||
|
||
**Сайт:** https://rus.hitmotop.com (Россия), https://eu.hitmotop.com (Европа)
|
||
|
||
Прямые ссылки на mp3 без логина, без JS. Работает через curl напрямую.
|
||
|
||
**Как найти ID трека:**
|
||
- Страница артиста: `https://rus.hitmotop.com/artist/{id}` — пагинация `/start/48`, `/start/96` и т.д.
|
||
- Прямая страница трека: `https://rus.hitmotop.com/song/{id}`
|
||
- Поиск: `https://rus.hitmotop.com/search?q={query}` — **внимание**: без JS возвращает пустую страницу. Для поиска song ID используй web_search (`site:rus.hitmotop.com "Артист Трек"`).
|
||
|
||
**Структура download-ссылки:**
|
||
```
|
||
https://rus.hitmotop.com/get/music/{YYYYMMDD}/{Artist}_-_{Track}_{id}.mp3
|
||
```
|
||
|
||
**Bash — скачать по song ID:**
|
||
```bash
|
||
UA="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
|
||
curl -sL "https://rus.hitmotop.com/song/48847061" -H "User-Agent: $UA" -o /tmp/t.html
|
||
url=$(grep -o "get/music/[^\"']*mp3" /tmp/t.html | head -1)
|
||
curl -sL "https://rus.hitmotop.com/$url" -H "User-Agent: $UA" -o "track.mp3"
|
||
```
|
||
|
||
---
|
||
|
||
### ⭐⭐ mp3party.net — хорош для русскоязычного
|
||
|
||
**Сайт:** https://mp3party.net
|
||
|
||
Поиск работает через curl, возвращает прямые CDN-ссылки в HTML.
|
||
|
||
```bash
|
||
UA="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
|
||
url=$(curl -sL "https://mp3party.net/search?q=КняZz+Байкеры" \
|
||
-H "User-Agent: $UA" \
|
||
| grep -o '"https://dl[^"]*\.mp3"' | head -1 | tr -d '"')
|
||
curl -sL "$url" -H "User-Agent: $UA" -o "track.mp3"
|
||
```
|
||
|
||
**Ограничение:** Rate limit при 10+ запросах/мин. Часть треков отсутствует.
|
||
|
||
---
|
||
|
||
### ⭐⭐ classicalmusicarchive.org (через classicals.de) — классика
|
||
|
||
**Сайт:** https://www.classicals.de
|
||
|
||
Роялти-фри записи. Прямые ссылки на CDN.
|
||
|
||
```bash
|
||
curl -sL "https://www.classicals.de/saint-saens-danse-macabre" \
|
||
| grep -o "https://library[^\"']*mp3" | head -1
|
||
```
|
||
|
||
---
|
||
|
||
### ⭐⭐ chosic.com — классика CC-лицензия
|
||
|
||
**Сайт:** https://www.chosic.com
|
||
|
||
Прямые ссылки в `/wp-content/uploads/`. Работает без JS.
|
||
|
||
---
|
||
|
||
### ⚠️ musify.club — СЛОМАН (требует логин, май 2026)
|
||
|
||
**Статус:** `/track/dl/` редиректит на `/login`.
|
||
|
||
**Ловушка:** `curl -L` молча сохраняет HTML-страницу логина (~130-140KB). Файл проходит проверку по размеру, но внутри HTML. В сессии мая 2026 это привело к тому, что **125 из 165 файлов оказались мусором** — обнаружено только после переноса на локальную машину.
|
||
|
||
**Детекция:**
|
||
```bash
|
||
file track.mp3 | grep -q "HTML" && echo "МУСОР — удалить и перекачать"
|
||
```
|
||
|
||
---
|
||
|
||
### ℹ️ Другие сайты
|
||
|
||
| Сайт | curl-совместим | Примечание |
|
||
|------|---------------|------------|
|
||
| sefon.pro | Частично | Хорошая база, русский рок |
|
||
| melody.az | Частично | Небольшая база, транслит URL |
|
||
| drivemusic.club | Нет (JS) | CDN требует JS |
|
||
| spaces.im | Нет | Только стриминг |
|
||
| zaycev.net | Нет | Требует JS |
|
||
|
||
---
|
||
|
||
## Батч-скачивание — рабочий паттерн
|
||
|
||
### Bash-шаблон с проверкой HTML
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
BASE="$HOME/Downloads/music"
|
||
UA="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15"
|
||
LOG="$HOME/dl.log"
|
||
|
||
urlencode() { printf '%s' "$1" | jq -rR @uri; }
|
||
|
||
dl() {
|
||
local dir="$BASE/$1" query="$2" fname="$3"
|
||
mkdir -p "$dir"
|
||
local out="$dir/$fname.mp3"
|
||
|
||
# Пропустить если уже скачан и не мусор
|
||
if [ -f "$out" ]; then
|
||
file "$out" | grep -qv "HTML" && echo "skip: $fname" && return
|
||
rm "$out" # удалить HTML-заглушку
|
||
fi
|
||
|
||
local url
|
||
url=$(curl -sL "https://mp3party.net/search?q=$(urlencode "$query")" \
|
||
-H "User-Agent: $UA" \
|
||
| grep -o '"https://dl[^"]*\.mp3"' | head -1 | tr -d '"')
|
||
|
||
[ -z "$url" ] && echo "✗ not found: $fname" | tee -a "$LOG" && return
|
||
|
||
curl -sL "$url" -H "User-Agent: $UA" -o "$out"
|
||
|
||
# Обязательная проверка на HTML-мусор
|
||
if file "$out" | grep -q "HTML"; then
|
||
rm "$out"
|
||
echo "✗ got HTML: $fname" | tee -a "$LOG"
|
||
return
|
||
fi
|
||
echo "✓ $fname" | tee -a "$LOG"
|
||
}
|
||
```
|
||
|
||
### Проверка после скачивания (обязательно перед переносом)
|
||
|
||
```bash
|
||
# Найти все HTML-заглушки
|
||
find ~/Downloads/music -name "*.mp3" -exec sh -c \
|
||
'file "$1" | grep -q "HTML" && echo "$1"' _ {} \;
|
||
|
||
# Найти слишком маленькие (<100KB)
|
||
find ~/Downloads/music -name "*.mp3" -size -100k -ls
|
||
|
||
# Счёт хороших/плохих
|
||
find ~/Downloads/music -name "*.mp3" | while read f; do
|
||
file "$f" | grep -q "HTML" && echo "BAD: $f" || echo "OK"
|
||
done | sort | uniq -c
|
||
```
|
||
|
||
---
|
||
|
||
## TrueNAS — структура Music
|
||
|
||
**Путь:** `/mnt/RED_2TB/storage/Music/`
|
||
**Доступ:** `ssh truenas_admin@mallexxx.duckdns.org`
|
||
|
||
```
|
||
Music/
|
||
├── !A Not sorted/
|
||
│ └── SD-card-2026-05/ ← новые треки (май 2026, ~160 mp3)
|
||
│ ├── Агата Кристи/
|
||
│ ├── Аквариум/
|
||
│ ├── ... (Artist/Track.mp3)
|
||
│ └── Юрий Визбор/
|
||
├── !Pop, Club, Любэ/
|
||
├── !Retro/
|
||
├── !Rock&Folk/ ← основная рок-коллекция
|
||
├── !Детские/
|
||
├── !Рэп, Шансон/
|
||
└── z Другое, Enigma, Ленинград/
|
||
```
|
||
|
||
### Соглашение по именованию (SD-card-2026-05)
|
||
|
||
- Структура: `Исполнитель/Название трека.mp3`
|
||
- Один исполнитель — одна папка (даже для 1 трека)
|
||
- Папки дублей на латинице (Andervud, OtavaYo) — артефакт, можно слить с кириллическими
|
||
- Класика хранится в папке `Классика/` (Бах, Орф, Пахмутова и др.)
|
||
- Саундтреки — в `Саундтреки/`
|
||
- Исполнитель с одним треком (Елена Камбурова, Тамара Миансарова) — отдельная папка
|
||
|
||
### Загрузка файлов на NAS
|
||
|
||
**Рабочий метод** — python3 скрипт через ssh+scp (май 2026):
|
||
- rsync с `!` в пути назначения ломается (bash history expansion)
|
||
- scp напрямую из bash тоже ломается на кавычках с пробелами
|
||
- **Решение:** python subprocess с отдельными аргументами, ssh mkdir + scp per-file
|
||
|
||
```python
|
||
# Шаблон: /tmp/upload_nas.py
|
||
subprocess.run(["ssh", "-i", KEY, f"user@host", f"mkdir -p '{nas_dir}'"])
|
||
subprocess.run(["scp", "-i", KEY, local_path, f"user@host:{nas_path}"])
|
||
```
|
||
|
||
**WMA на NAS:** 565 файлов (в основном The Prodigy, Дискотека Авария, старые радиозаписи). Конвертация не делалась — отдельная задача при необходимости.
|
||
|
||
### Валидация перед загрузкой
|
||
|
||
```bash
|
||
# Проверить все mp3 через ffmpeg (только ошибки)
|
||
find ~/Downloads/music -name "*.mp3" | while read f; do
|
||
r=$(ffmpeg -v error -i "$f" -f null - 2>&1)
|
||
[ -n "$r" ] && echo "ERR: $f | $(echo "$r" | head -1)"
|
||
done
|
||
|
||
# Частые проблемы:
|
||
# "invalid RIFF header" — файл обёрнут в WAV-контейнер → найти RIFF offset и перекодировать
|
||
# "Failed to find two consecutive MPEG frames" — нулевой или битый файл → перекачать
|
||
# "Header missing" — частичная порча → перекодировать через libmp3lame
|
||
```
|
||
|
||
### HTML-ссылки на треки
|
||
|
||
TrueNAS без дополнительных сервисов HTTP не отдаёт. Варианты:
|
||
- **Navidrome** (docker) — DLNA + веб-плеер + REST API, ссылки вида `http://nas:4533/rest/stream?id=...`
|
||
- **Nginx file server** — простой листинг, ссылки `http://nas/music/Артист/Трек.mp3`
|
||
- **Samba** → монтировать локально → `file://` ссылки
|
||
|
||
---
|
||
|
||
## Связанные документы
|
||
|
||
- [[personal-os-architecture]]
|
||
|
||
---
|
||
*Создано: 2026-05-09 | Сессия: загрузка ~165 треков на SD-карту*
|