Acenando para o serviço de música TIDAL com Python. Funciona em (pelo menos) Windows, macOS e GNU/Linux.
TIDAL é uma plataforma de streaming de música centrada nos fãs e voltada para os artistas, que oferece mais de 100 milhões de músicas com qualidade de som HiFi para a comunidade musical global. © 2024 TIDAL Music AS
Este projeto é inspirado em qobuz-dl
e, particularmente, é uma continuação do Tidal-Media-Downloader
. Este projeto destina-se apenas ao uso privado: não se destina à distribuição de conteúdo protegido por direitos autorais .
Este software utiliza bibliotecas do projeto FFmpeg sob LGPLv2.1. FFmpeg é uma marca registrada de Fabrice Bellard, criador do projeto FFmpeg.
requests
, os proxies do sistema são respeitados (HTTP, HTTPs, Socks); ou pode ser especificado por uma variável de ambiente típicarequests
, o cache de solicitação Cache-Control
muito simples ocorre via CacheControl
É necessária uma assinatura atual e válida do TIDAL para executar tidal-wave
. Anteriormente, o TIDAL segmentava as qualidades de áudio disponíveis nos planos HiFi e HiFi Plus: agora,
Todos os planos TIDAL atuais apresentam formatos de qualidade de som Max, como full lossless, HiRes FLAC e Dolby Atmos (até 24 bits, 192 kHz).
Mais informações sobre qualidade de som no site do TIDAL aqui.
ffmpeg
.chocolatey
é uma opçãobackoff
cachecontrol
dataclass-wizard
ffmpeg-python
mutagen
m3u8
platformdirs
pycryptodome
requests[socks]
typer
pip
Instalar do PyPi Instale este projeto com pip
: seja com um ambiente virtual (preferencial) ou da forma que desejar:
# GNU/Linux or macOS or Android (e.g. Termux)
$ python3 -m pip install tidal-wave
# Windows
PS > python.exe - m pip install tidal - wave
pip
Instalar a partir do repositório Alternativamente, você pode clonar este repositório; cd
nele; e instale a partir daí:
$ git clone --depth=1 https://github.com/ebb-earl-co/tidal-wave.git
$ cd tidal-wave
$ python3 -m venv .venv
$ source .venv/bin/activate
$ (.venv) pip install .
Os artefatos de lançamento deste projeto são criados com PyInstaller. Ele agrupa Python 3.12.6, FFmpeg 7.0 e o programa tidal-wave
em um binário, licenciado sob os termos do FFmpeg: com a GNU Lesser General Public License (LGPL) versão 2.1. A instalação é tão simples quanto baixar o binário correto para sua plataforma, dando-lhe permissões de execução e executá-lo. Certifique-se de que a soma de verificação SHA256 do arquivo que você baixou corresponde ao arquivo .sha256
correspondente na página de lançamentos!
$ wget https://github.com/ebb-earl-co/tidal-wave/releases/latest/download/tidal-wave_ubuntu_24.04_amd64
$ wget https://github.com/ebb-earl-co/tidal-wave/releases/latest/download/tidal-wave_ubuntu_24.04_amd64.sha256
$ sha256sum --check tidal-wave_ubuntu_24.04_amd64.sha256
# ONLY CONTINUE IF THE OUTPUT IS THE FOLLOWING: 'tidal-wave_ubuntu_24.04_amd64.sha256: OK'
# Otherwise, delete the downloaded binary and try to download it again
$ chmod +x ./tidal-wave_ubuntu_24.04_amd64
$ ./tidal-wave_ubuntu_24.04_amd64 --help
# For just the lifetime of this PowerShell process, don't block the download from GitHub
PS > Set-ExecutionPolicy - ExecutionPolicy Bypass - Scope Process
PS > Invoke-WebRequest " https://github.com/ebb-earl-co/tidal-wave/releases/latest/download/tidal-wave_windows.exe " - OutFile " tidal-wave_windows.exe "
PS > Invoke-WebRequest " https://github.com/ebb-earl-co/tidal-wave/releases/latest/download/tidal-wave_windows.exe.sha256 " - OutFile " tidal-wave_windows.exe.sha256 "
# Get the checksum value from the tidal-wave_windows.exe.sha256 file and compare it to the just-downloaded EXE
# (Get-FileHash .tidal-wave_windows.exe -Algorithm SHA256).Hash -eq (Get-Content .tidal-wave_windows.exe.sha256)
PS > ( Get-FileHash . tidal-wave_windows.exe - Algorithm SHA256).Hash -eq " e02f69eb850a98e6e1df2bc033fd12566cf27305421a36ec5372fd432ccc8e70 " # This checksum is from version 2024.4.3
# ONLY CONTINUE IF THE OUTPUT OF THE PREVIOUS COMMAND IS 'True'
PS > & . tidal-wave_windows.exe -- help
Extraia a imagem do repositório de contêineres do GitHub:
$ docker pull ghcr.io/ebb-earl-co/tidal-wave:latest
# Or, the main branch of this repository, which will be ahead of `latest`:
$ docker pull ghcr.io/ebb-earl-co/tidal-wave:trunk
Se o local da instalação do Python estiver disponível no caminho, execute tidal-wave --help
para ver as opções disponíveis. Caso contrário (inclusive se você seguiu as etapas de clonagem do repositório acima), execute python3 -m tidal_wave --help
no diretório raiz do repositório, tidal-wave
. Em ambos os casos, você deverá ver algo como o seguinte:
Usage: python -m tidal_wave [OPTIONS] TIDAL_URL [OUTPUT_DIRECTORY]
╭─ Arguments ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * tidal_url TEXT The Tidal album or artist or mix or playlist or track or video to download [default: None] [required] │
│ output_directory [OUTPUT_DIRECTORY] The parent directory under which directory(ies) of files will be written [default: ~ /Music] │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --audio-format [Atmos | HiRes | Lossless | High | Low] [default: Lossless] │
│ --loglevel [DEBUG | INFO | WARNING | ERROR | CRITICAL] [default: INFO] │
│ --include-eps-singles No-op unless passing TIDAL artist. Whether to include artist ' s EPs and singles with albums │
│ --no-extra-files Whether to not even attempt to retrieve artist bio, artist image, album credits, album review, or playlist m3u8 │
│ --no-flatten Whether to treat playlists or mixes as a list of tracks/videos and, as such, retrieve them independently │
| --transparent Whether to dump JSON responses from TIDAL API; maximum verbosity |
│ --install-completion Install completion for the current shell. │
│ --show-completion Show completion for the current shell, to copy it or customize the installation. │
│ --help Show this message and exit. │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
A invocação desta ferramenta armazenará credenciais em um diretório específico no diretório "home" do usuário: para sistemas do tipo Unix, será /home/${USER}/.config/tidal-wave
: para Windows, varia: em Em qualquer situação do sistema operacional, o diretório exato é determinado pela função user_config_path()
do pacote platformdirs
.
Da mesma forma, por padrão, toda mídia recuperada é colocada em subdiretórios do diretório de música padrão do usuário: para sistemas do tipo Unix, provavelmente é /home/${USER}/Music
; para Windows é provavelmente C:Users
. Este diretório é determinado por platformdirs.user_music_path()
.
output_directory
, então toda a mídia será gravada em subdiretórios desse diretório.Fonte: TIDAL
Baixo | Alto | Sem perdas | Contrata FLAC | Dolby Atmos | Vídeo (H.264 + AAC) | |
---|---|---|---|---|---|---|
Android | ✔️ | ✔️ | ✔️ | ✔️ | ❌ | ✔️ |
TV de fogo? | ✔️ | ✔️ | ✔️ | ❌ | ✔️ | ✔️ |
macOS | ✔️ | ✔️ | ✔️ | ✔️ | ❌ | ✔️ |
Windows | ✔️ | ✔️ | ✔️ | ✔️ | ❌ | ✔️ |
? Este é o cliente padrão do tidal-wave
, um Amazon Fire TV falsificado. É aquele invocado em todas as situações, a menos que --audio-format hires
seja passado como um sinalizador de linha de comando:
$ tidal-wave https://listen.tidal.com/album/000000
$ # no --audio-format flag passed will instruct tidal-wave to use the Fire TV client, as it implies --audio-format lossless
$ tidal-wave https://listen.tidal.com/album/000000 --audio-format high
$ # specifying low, high, lossless, or atmos will instruct tidal-wave to use the Fire TV client
$ tidal-wave https://listen.tidal.com/album/000000 --audio-format hires
$ # the above forces tidal-wave to ask for an access token gleaned from an Android, macOS, or Windows device, as laid out in the above table
Certamente é útil para depuração e, talvez, para usar múltiplas versões de um software, saber qual binário/pacote invocado é qual versão. A partir da versão 2024.7.1 do tidal-wave
, isso é possível adicionando o sinalizador --version
a qualquer comando. Este é um comando ansioso , na linguagem typer
, o que significa que qualquer outro sinalizador ou argumento passado para tidal-wave
será ignorado e a versão será simplesmente retornada. Por exemplo
$ tidal-wave --version
tidal-wave 2024.7.1
tidal-wave
sem outros argumentos para: recuperar o álbum/artista/mix/playlist/faixa em qualidade Lossless para um subdiretório do diretório de música do usuário e registro em nível de INFO no caso de áudio; recupere o vídeo em 1080p, qualidade H.264+AAC para um subdiretório do diretório de música do usuário com registro em nível INFO no caso de um URL de vídeo. (.venv) $ tidal-wave https://tidal.com/browse/track/226092704
--no-extra-files
: (.venv) $ tidal-wave https://tidal.com/browse/track/226092704 --no-extra-files
(.venv) $ tidal-wave https://tidal.com/browse/track/... --audio-format atmos --loglevel debug
Tenha em mente que um token de acesso de um dispositivo Android (preferencial), Windows ou macOS precisará ser extraído e passado para esta ferramenta para acessar as faixas HiRes FLAC
$ tidal-wave https://tidal.com/browse/album/... --audio-format hires --loglevel warning
--audio-format
não funciona ao recuperar vídeos. PS > C:UsersUser > & tidal-wave_windows.exe https: // tidal.com / browse / playlist / ...
--audio-format
não funciona ao recuperar vídeos. $ ./tidal-wave_ubuntu_24.04_amd64 https://tidal.com/browse/mix/...
(.venv) $ python3 -m tidal_wave https://listen.tidal.com/artist/... --audio-format high --loglevel debug
(.venv) $ tidal-wave https://listen.tidal.com/artist/... --audio-format hires --include-eps-singles
--transparent
. No diretório onde tidal-wave
é chamado, --transparent
gravará as respostas da API TIDAL em arquivos .json (.venv) $ tidal-wave https://listen.tidal.com/track/... --audio-format low --loglevel debug --transparent
Por padrão, quando transmitido um URL de playlist ou mix, tidal-wave
recuperará todas as faixas e/ou vídeos especificados por esse URL e os gravará em um subdiretório de Playlists
ou Mixes
, que por si só é um subdiretório do output_directory
especificado . Por exemplo, ~/Music/Mixes/My Daily Discovery [016dccd302e9ac6132d8334cfbc022]
. Neste diretório, uma vez recuperadas todas as faixas e/ou vídeos, eles são renomeados com base na ordem em que aparecem na lista de reprodução. Por exemplo
(.venv) $ tidal-wave https://listen.tidal.com/playlist/1b418bb8-90a7-4f87-901d-707993838346
$ ls ~ /Music/Playlists/New Arrivals [1b418bb8-90a7-4f87-901d-707993838346]/
' 001 - Dance Alone [CD].flac '
' 002 - Kissing Strangers [CD].flac '
' 003 - Sunday Service [CD].flac '
Se este não for o comportamento desejado, passe o sinalizador --no-flatten
. Este sinalizador instrui tidal-wave
a deixar as faixas e/ou vídeos no diretório onde eles teriam sido gravados se tivessem sido passados para tidal-wave
de forma independente. Por exemplo
(.venv) $ tidal-wave https://listen.tidal.com/playlist/1b418bb8-90a7-4f87-901d-707993838346 --no-flatten
$ ls ~ /Music/
' Sia/Dance Alone [343225498] [2024]/01 - Dance Alone [CD].flac '
' USHER/COMING HOME [339249017] [2024]/05 - Kissing Strangers [CD].flac '
' Latto/Sunday Service [344275657] [2024]/01 - Sunday Service [CD].flac '
As opções de linha de comando são as mesmas para a invocação do Python, mas para salvar a configuração e os dados de áudio, os volumes precisam ser passados. Se forem montagens vinculadas a diretórios, elas deverão ser criadas antes de executar docker run
para evitar problemas de permissão ! Por exemplo,
$ mkdir -p ./Music/ ./config/tidal-wave/
$ docker run
--rm -it
--name tidal-wave
--volume ./Music:/home/debian/Music
--volume ./config/tidal-wave:/home/debian/.config/tidal-wave
ghcr.io/ebb-earl-co/tidal-wave:latest
https://tidal.com/browse/track/...
Usar o Docker pode ser uma ideia atraente caso você queira recuperar todos os vídeos, álbuns, EPs e singles na mais alta qualidade possível para um determinado artista. A seguinte invocação do Docker fará isso por você:
$ mkdir -p ./Music/ ./config/tidal-wave/
$ docker run
--name tidal-wave
--rm -it
--volume ./Music:/home/debian/Music
--volume ./config/tidal-wave:/home/debian/.config/tidal-wave
ghcr.io/ebb-earl-co/tidal-wave:latest
https://listen.tidal.com/artist/...
--audio-format hires
--include-eps-singles
Talvez você não queira um tipo executável de invocação do Docker, mas sim um contêiner de longa duração no qual é possível docker exec
para solicitar mídia quando quiser. Este é um dos recursos solicitados nas discussões do GitHub, em particular para usuários do Unraid. Para fazer isso, use o seguinte comando Docker ligeiramente modificado:
$ mkdir -p ./Music/ ./config/tidal-wave/
$ docker run
--name tidal-wave
-dit # is short for: --detach --interactive --tty
--volume ./Music:/home/debian/Music
--volume ./config/tidal-wave:/home/debian/.config/tidal-wave
--entrypoint " /bin/bash "
ghcr.io/ebb-earl-co/tidal-wave:latest
$ docker exec -it tidal-wave tidal-wave https://tidal.com/browse/album/...
$ docker exec -it tidal-wave tidal-wave https://tidal.com/browse/mix/...
$ docker exec -it tidal-wave tidal-wave https://tidal.com/browse/playlist/...
$ docker exec -it tidal-wave tidal-wave https://tidal.com/browse/track/...
Nota: o primeiro tidal-wave
é qualquer --name
que você der ao contêiner, então pode ser o que seu coração desejar, mas o segundo tidal-wave
está invocando o programa Python dentro do contêiner e precisa exatamente tidal-wave
.
A maneira mais fácil de começar a trabalhar no desenvolvimento é bifurcar este projeto no GitHub ou clonar o repositório em sua máquina local e fazer a solicitação pull no GitHub posteriormente. Em qualquer caso, primeiro será necessário obter alguma informação do GitHub, então, aproximadamente, o processo é:
$ git clone --depth=1 https://github.com/ebb-earl-co/tidal-wave/git
* Obviously replace the URL with your forked version if you've followed that strategy
(some-virtual-env) $ python3 -m pip install -r requirements.txt
* optional packages to follow the coding style and build process; `pyinstaller`, `black`: `(some-virtual-env) $ python3 -m pip install black pyinstaller`
* optionally, Docker to build the OCI container artifacts
from tidal_wave import album , artist , dash , hls , login , main , media , mix , models , oauth , playlist , requesting , track , utils , video
from tidal_wave . main import logging , user_music_path , Path