diff --git a/MIGRATION_PYTHON311.md b/MIGRATION_PYTHON311.md new file mode 100644 index 0000000..b1b9f57 --- /dev/null +++ b/MIGRATION_PYTHON311.md @@ -0,0 +1,89 @@ +# Migração para Python 3.11 + +## Resumo das Mudanças + +Este projeto foi atualizado para ser compatível com Python 3.11. As principais mudanças incluem: + +### 1. Remoção de Dependências Desnecessárias +- Removidas **75+ bibliotecas** desnecessárias (Jupyter, Qt, bibliotecas de desenvolvimento, etc.) +- Mantidas apenas as dependências essenciais para o funcionamento da API + +### 2. Duas Opções de Audio Processing + +#### Opção A: Spleeter Atualizado +```bash +# Descomente no requirements.txt: +spleeter==2.4.0 +tensorflow>=2.13.0,<2.16.0 + +# Use o arquivo: +cp utils/split_spleeter.py utils/split.py +``` + +#### Opção B: Demucs (Recomendado) +```bash +# Descomente no requirements.txt: +demucs>=4.0.0 +torch>=2.0.0 +torchaudio>=2.0.0 + +# Use o arquivo: +cp utils/split_demucs.py utils/split.py +``` + +## Instruções de Instalação + +### 1. Criar ambiente Python 3.11 +```bash +# Com pyenv +pyenv install 3.11.0 +pyenv local 3.11.0 + +# Ou com uv +uv python install 3.11 +``` + +### 2. Escolher uma opção de audio processing +Edite o `requirements.txt` e descomente uma das opções (Spleeter ou Demucs). + +### 3. Instalar dependências +```bash +pip install -r requirements.txt +``` + +### 4. Substituir arquivo de separação +```bash +# Para Spleeter: +cp utils/split_spleeter.py utils/split.py + +# Para Demucs (recomendado): +cp utils/split_demucs.py utils/split.py +``` + +## Vantagens do Demucs sobre Spleeter + +1. **Melhor qualidade** de separação +2. **Suporte nativo** ao Python 3.11 +3. **Modelos mais modernos** (baseados em PyTorch) +4. **Melhor manutenção** e atualizações regulares +5. **Compatibilidade** com hardware moderno (GPU) + +## Estrutura Final do Projeto + +``` +Split/ +├── app.py # API Flask principal +├── requirements.txt # Dependências limpas para Python 3.11 +├── utils/ +│ ├── split.py # Arquivo atual (substituir) +│ ├── split_spleeter.py # Versão com Spleeter +│ ├── split_demucs.py # Versão com Demucs +│ └── ziped.py # Utilitário de compressão +└── MIGRATION_PYTHON311.md # Este arquivo +``` + +## Testando a Migração + +1. Inicie o servidor: `python app.py` +2. Teste o endpoint: `curl -X POST -F "audio=@test.mp3" http://localhost:5000/upload` +3. Verifique se os arquivos são gerados em `files/separate/audio/` diff --git a/README_UV.md b/README_UV.md new file mode 100644 index 0000000..17047ce --- /dev/null +++ b/README_UV.md @@ -0,0 +1,45 @@ +# 🚀 Como usar o projeto Split com UV + +## Comandos principais: + +### 1. **Rodar o servidor com UV:** +```bash +uv run python app.py +``` + +### 2. **Rodar com script automático:** +```bash +./run_with_uv.sh +``` + +### 3. **Verificar se Demucs está funcionando:** +```bash +uv run python -c "import demucs; print('✅ Demucs OK!')" +``` + +### 4. **Testar a API:** +```bash +# Em outro terminal: +curl -X POST -F "audio=@seu_arquivo.mp3" http://localhost:5000/upload +``` + +## ✅ **Mudanças feitas para usar UV:** + +1. **Arquivo `utils/split.py`** agora usa: `uv run python -m demucs` +2. **Arquivo `utils/ziped.py`** cria diretórios automaticamente +3. **Script `run_with_uv.sh`** para facilitar execução + +## 🎵 **Como funciona agora:** + +- **Demucs** faz a separação de áudio (melhor que Spleeter) +- **UV** gerencia o ambiente Python 3.11 +- **Compatibilidade total** com Python 3.11 +- **Dependências limpas** (de 95 para ~15 bibliotecas) + +## 🔧 **Troubleshooting:** + +Se der erro, rode: +```bash +uv pip install -r requirements.txt +source .venv/bin/activate +``` diff --git a/files/audio.wav b/files/audio.wav deleted file mode 100644 index e2b2a67..0000000 Binary files a/files/audio.wav and /dev/null differ diff --git a/requirements.txt b/requirements.txt index 2a5e5c4..904f561 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,94 +1,28 @@ -absl-py==0.10.0 -aniso8601==8.0.0 -astor==0.8.1 -attrs==19.3.0 -audioread==2.1.8 -backcall==0.2.0 -bleach==3.1.5 -certifi==2020.6.20 -cffi==1.14.2 -chardet==3.0.4 -click==7.1.2 -decorator==4.4.2 -defusedxml==0.6.0 -entrypoints==0.3 -ffmpeg-python==0.2.0 -Flask==1.1.2 -Flask-RESTful==0.3.8 -future==0.18.2 -gast==0.2.2 -google-pasta==0.2.0 -grpcio==1.31.0 -h5py==2.10.0 -idna==2.10 -importlib-metadata==1.7.0 -ipykernel==5.3.3 -ipython==7.16.1 -ipython-genutils==0.2.0 -ipywidgets==7.5.1 -itsdangerous==1.1.0 -jedi==0.17.2 -Jinja2==2.11.2 -joblib==0.16.0 -jsonschema==3.2.0 -jupyter==1.0.0 -jupyter-client==6.1.6 -jupyter-console==6.1.0 -jupyter-core==4.6.3 -Keras-Applications==1.0.8 -Keras-Preprocessing==1.1.2 -librosa==0.7.2 -llvmlite==0.31.0 -Markdown==3.2.2 -MarkupSafe==1.1.1 -mistune==0.8.4 -nbconvert==5.6.1 -nbformat==5.0.7 -norbert==0.2.1 -notebook==6.0.3 -numba==0.48.0 -numpy==1.19.1 -opt-einsum==3.3.0 -packaging==20.4 -pandas==0.25.1 -pandocfilters==1.4.2 -parso==0.7.0 -pexpect==4.8.0 -pickleshare==0.7.5 -prometheus-client==0.8.0 -prompt-toolkit==3.0.5 -protobuf==3.13.0 -ptyprocess==0.6.0 -pycparser==2.20 -Pygments==2.6.1 -pyparsing==2.4.7 -pyrsistent==0.16.0 -python-dateutil==2.8.1 -pytz==2020.1 -pyzmq==19.0.1 -qtconsole==4.7.5 -QtPy==1.9.0 -requests==2.24.0 -resampy==0.2.2 -scikit-learn==0.23.2 -scipy==1.5.2 -Send2Trash==1.5.0 -six==1.15.0 -SoundFile==0.10.3.post1 -spleeter==1.5.4 -tensorboard==1.15.0 -tensorflow==1.15.2 -tensorflow-estimator==1.15.1 -termcolor==1.1.0 -terminado==0.8.3 -testpath==0.4.4 -threadpoolctl==2.1.0 -tornado==6.0.4 -traitlets==4.3.3 -urllib3==1.25.10 -wcwidth==0.2.5 -webencodings==0.5.1 -Werkzeug==1.0.1 -widgetsnbextension==3.5.1 -wrapt==1.12.1 -zipp==3.1.0 +# Requirements para Python 3.11 - Versão Limpa +# Core web framework +Flask==3.0.0 +Flask-RESTful==0.3.10 +Werkzeug==3.0.1 + +# Audio processing - Escolha uma das opções abaixo: + +# OPÇÃO 1: Spleeter (incompatível com Python 3.11) +# spleeter==2.4.0 +# tensorflow>=2.13.0,<2.16.0 + +# OPÇÃO 2: Demucs (ATIVO - compatível com Python 3.11) +demucs>=4.0.0 +torch>=2.0.0 +torchaudio>=2.0.0 + +# Bibliotecas de áudio essenciais +librosa>=0.10.0 +audioread>=3.0.0 +SoundFile>=0.12.0 +ffmpeg-python>=0.2.0 + +# Utilitários essenciais +numpy>=1.24.0 +scipy>=1.11.0 +requests>=2.31.0 +click>=8.1.0 diff --git a/requirements_python311_demucs.txt b/requirements_python311_demucs.txt new file mode 100644 index 0000000..00a9209 --- /dev/null +++ b/requirements_python311_demucs.txt @@ -0,0 +1,20 @@ +# Requirements para Python 3.11 com Demucs (alternativa moderna ao Spleeter) +# Core dependencies para o projeto +Flask==3.0.0 +Flask-RESTful==0.3.10 +Werkzeug==3.0.1 + +# Audio processing - Demucs (melhor que Spleeter) +demucs>=4.0.0 +torch>=2.0.0 +torchaudio>=2.0.0 +librosa>=0.10.0 +audioread>=3.0.0 +SoundFile>=0.12.0 +ffmpeg-python>=0.2.0 + +# Utilities +numpy>=1.24.0 +scipy>=1.11.0 +requests>=2.31.0 +click>=8.1.0 diff --git a/requirements_python311_spleeter.txt b/requirements_python311_spleeter.txt new file mode 100644 index 0000000..90d4594 --- /dev/null +++ b/requirements_python311_spleeter.txt @@ -0,0 +1,22 @@ +# Requirements para Python 3.11 com Spleeter atualizado +# Core dependencies para o projeto +Flask==3.0.0 +Flask-RESTful==0.3.10 +Werkzeug==3.0.1 + +# Audio processing - Spleeter atualizado +spleeter==2.4.0 +tensorflow>=2.13.0,<2.16.0 +librosa>=0.10.0 +audioread>=3.0.0 +SoundFile>=0.12.0 +ffmpeg-python>=0.2.0 + +# Utilities +numpy>=1.24.0 +scipy>=1.11.0 +requests>=2.31.0 +click>=8.1.0 + +# Para compressão de arquivos +# (implementar alternativa simples ao invés de múltiplas dependências) diff --git a/run_with_uv.sh b/run_with_uv.sh new file mode 100755 index 0000000..b1f8d78 --- /dev/null +++ b/run_with_uv.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# Script para rodar o projeto usando UV + +echo "🚀 Iniciando o projeto Split com UV..." + +# Verificar se está no ambiente virtual UV +if [ ! -d ".venv" ]; then + echo "⚠️ Ambiente virtual não encontrado. Criando..." + uv venv --python 3.11 +fi + +# Ativar ambiente virtual +source .venv/bin/activate + +echo "📦 Verificando dependências..." +uv pip install -r requirements.txt + +echo "🎵 Iniciando servidor Flask..." +uv run python app.py diff --git a/utils/split.py b/utils/split.py index 9ee798c..d5b5158 100755 --- a/utils/split.py +++ b/utils/split.py @@ -1,9 +1,77 @@ -from spleeter.separator import Separator +import subprocess +import os +import shutil -def separa(number,wave): - separator = Separator(f"spleeter:{number}stems") - audio_file = wave - destination = 'files/separate' - separator.separate_to_file(audio_file, destination) - -#split.separa(2,"files/It dont mean i think_ master.mp3") \ No newline at end of file +def separa(number, wave): + """ + Separação de audio usando Demucs (alternativa moderna ao Spleeter) + """ + try: + # Cria diretório de destino + destination = 'files/separate' + os.makedirs(destination, exist_ok=True) + + # Mapeia número de stems para modelos Demucs + model_map = { + 2: "htdemucs_ft", # 2 stems: vocals, accompaniment + 4: "htdemucs", # 4 stems: vocals, drums, bass, other + 5: "htdemucs_6s" # 6 stems (usando 5 mais próximo) + } + + model = model_map.get(number, "htdemucs_ft") + + # Executa Demucs usando uv + cmd = [ + "uv", "run", "python", "-m", "demucs.separate", + "-n", model, + "-o", destination, + wave + ] + + print(f"Executando comando: {' '.join(cmd)}") + result = subprocess.run(cmd, capture_output=True, text=True) + + print(f"Return code: {result.returncode}") + print(f"STDOUT: {result.stdout}") + print(f"STDERR: {result.stderr}") + + if result.returncode == 0: + # Reorganiza arquivos para manter compatibilidade com estrutura existente + reorganize_demucs_output(destination, wave) + return True + else: + print(f"Erro na separação com Demucs: {result.stderr}") + return False + + except Exception as e: + print(f"Erro na separação com Demucs: {e}") + return False + +def reorganize_demucs_output(destination, original_file): + """ + Reorganiza a saída do Demucs para manter compatibilidade + """ + try: + # Demucs cria uma estrutura modelo/nome_arquivo/ + # Precisamos mover para a estrutura esperada + base_name = os.path.splitext(os.path.basename(original_file))[0] + + # Encontra a pasta criada pelo Demucs + for item in os.listdir(destination): + item_path = os.path.join(destination, item) + if os.path.isdir(item_path): + for subitem in os.listdir(item_path): + subitem_path = os.path.join(item_path, subitem) + if os.path.isdir(subitem_path) and base_name in subitem: + # Move arquivos para a estrutura esperada + audio_dest = os.path.join(destination, "audio") + os.makedirs(audio_dest, exist_ok=True) + + for audio_file in os.listdir(subitem_path): + if audio_file.endswith('.wav'): + src = os.path.join(subitem_path, audio_file) + dst = os.path.join(audio_dest, audio_file) + shutil.move(src, dst) + break + except Exception as e: + print(f"Erro ao reorganizar saída: {e}") diff --git a/utils/split_demucs.py b/utils/split_demucs.py new file mode 100644 index 0000000..769b8f8 --- /dev/null +++ b/utils/split_demucs.py @@ -0,0 +1,72 @@ +import subprocess +import os +import shutil + +def separa(number, wave): + """ + Separação de audio usando Demucs (alternativa moderna ao Spleeter) + """ + try: + # Cria diretório de destino + destination = 'files/separate' + os.makedirs(destination, exist_ok=True) + + # Mapeia número de stems para modelos Demucs + model_map = { + 2: "htdemucs_ft", # 2 stems: vocals, accompaniment + 4: "htdemucs", # 4 stems: vocals, drums, bass, other + 5: "htdemucs_6s" # 6 stems (usando 5 mais próximo) + } + + model = model_map.get(number, "htdemucs_ft") + + # Executa Demucs + cmd = [ + "python", "-m", "demucs", + "--model", model, + "--out", destination, + wave + ] + + result = subprocess.run(cmd, capture_output=True, text=True) + + if result.returncode == 0: + # Reorganiza arquivos para manter compatibilidade com estrutura existente + reorganize_demucs_output(destination, wave) + return True + else: + print(f"Erro na separação com Demucs: {result.stderr}") + return False + + except Exception as e: + print(f"Erro na separação com Demucs: {e}") + return False + +def reorganize_demucs_output(destination, original_file): + """ + Reorganiza a saída do Demucs para manter compatibilidade + """ + try: + # Demucs cria uma estrutura modelo/nome_arquivo/ + # Precisamos mover para a estrutura esperada + base_name = os.path.splitext(os.path.basename(original_file))[0] + + # Encontra a pasta criada pelo Demucs + for item in os.listdir(destination): + item_path = os.path.join(destination, item) + if os.path.isdir(item_path): + for subitem in os.listdir(item_path): + subitem_path = os.path.join(item_path, subitem) + if os.path.isdir(subitem_path) and base_name in subitem: + # Move arquivos para a estrutura esperada + audio_dest = os.path.join(destination, "audio") + os.makedirs(audio_dest, exist_ok=True) + + for audio_file in os.listdir(subitem_path): + if audio_file.endswith('.wav'): + src = os.path.join(subitem_path, audio_file) + dst = os.path.join(audio_dest, audio_file) + shutil.move(src, dst) + break + except Exception as e: + print(f"Erro ao reorganizar saída: {e}") diff --git a/utils/split_spleeter.py b/utils/split_spleeter.py new file mode 100644 index 0000000..f033f65 --- /dev/null +++ b/utils/split_spleeter.py @@ -0,0 +1,23 @@ +from spleeter.separator import Separator +import os + +def separa(number, wave): + """ + Separação de audio usando Spleeter atualizado + """ + try: + # Cria o separador com configuração atualizada + separator = Separator(f"spleeter:{number}stems-16kHz") + audio_file = wave + destination = 'files/separate' + + # Cria diretório se não existir + os.makedirs(destination, exist_ok=True) + + # Realiza a separação + separator.separate_to_file(audio_file, destination) + + return True + except Exception as e: + print(f"Erro na separação com Spleeter: {e}") + return False diff --git a/utils/ziped.py b/utils/ziped.py index 66452f4..e5cc5ce 100644 --- a/utils/ziped.py +++ b/utils/ziped.py @@ -4,6 +4,9 @@ # Zip the files from given directory that matches the filter def zipFilesInDir(dirName, zipFileName, filter): + # Ensure the output directory exists + os.makedirs(os.path.dirname(zipFileName), exist_ok=True) + # create a ZipFile object with ZipFile(zipFileName, 'w') as zipObj: # Iterate over all the files in directory