coda/README.md
Rodrigo Verdiani e1a262fec0 feat: scaffold Coda transcoder with docs, dev tooling and web base
Add the initial foundation for Coda, a Go/Docker service that converts
FLAC albums to MP3 320 kbps CBR, triggered by Lidarr webhooks or manually
from the web UI.

- docs: requirements and architecture (SQLite persistence, media volume,
  work window, manual FLAC search, env + web config)
- config: .env loader with env precedence
- web: embed/dev asset split, chi server, index template (DaisyUI + htmx)
- build: Makefile (setup/css/run/build/test/lint), Dockerfile (Tailwind
  standalone CLI + DaisyUI, no Node), .env.example, ignore rules
- docs: AGENTS.md and README for the project
2026-07-06 20:06:25 -03:00

5.1 KiB

Coda

Transcoder para Lidarr, escrito em Go e distribuído via Docker. Converte álbuns de FLAC para MP3 320 kbps CBR, acionado automaticamente por webhooks do Lidarr ou manualmente pela interface web.

Em ambos os fluxos, o Coda converte os arquivos, valida o resultado, remove os FLACs originais e solicita ao Lidarr um rescan da biblioteca.

Funcionalidades

  • Conversão FLAC → MP3 320 kbps CBR (libmp3lame), preservando metadados e capa.
  • Acionamento por webhook do Lidarr ou manual pela interface web.
  • Fila interna com worker pool e conversão paralela configurável.
  • Validação pós-conversão (ffprobe, tamanho, existência) antes de apagar qualquer FLAC.
  • Janela de trabalho opcional (desabilitada por padrão) para restringir o processamento a um intervalo de horário.
  • Interface web: dashboard, tarefas, logs, navegação/scan de FLACs e configurações.
  • Persistência em SQLite (jobs, logs e configurações).
  • Modo dry run para simular sem converter nem apagar.

Stack

Camada Escolha
Linguagem Go 1.25.x
HTTP Router chi (go-chi/chi/v5)
Banco SQLite (modernc.org/sqlite, sem CGO)
UI html/template + htmx + Tailwind CSS v4 + DaisyUI
Logging log/slog (stdlib) + handler SQLite
Áudio ffmpeg + ffprobe (libmp3lame)
Distribuição Docker (Alpine Linux)

Início Rápido (local, sem Docker)

Pré-requisitos: Go 1.25+ e ffmpeg com libmp3lame.

No Fedora, o ffmpeg completo vem do RPM Fusion:

sudo dnf install -y https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm
sudo dnf install -y ffmpeg

Setup e execução:

make setup                    # baixa Tailwind + DaisyUI + htmx, deps Go, cria .env
mkdir -p data testdata/music  # pastas locais (ajuste MUSIC_PATH no .env)
make run                      # dev com hot-reload (http://localhost:8080)

O SQLite não precisa ser instalado (modernc.org/sqlite é Go puro).

Comandos (Makefile)

make setup        # baixa ferramentas + deps + cria .env
make css          # gera web/static/app.css
make css-watch    # regenera o CSS ao salvar (dev)
make run          # dev (build tag dev, assets do disco, hot-reload)
make run-prod     # produção (assets embutidos via //go:embed)
make build        # binário de produção em bin/server
make test         # go test ./...
make lint         # go vet ./...
make clean        # remove bin/ e app.css

Docker

docker build -t coda .
docker run -d \
  -p 8080:8080 \
  -v /caminho/para/musica:/music \
  -v coda-data:/data \
  -e LIDARR_URL=http://lidarr:8686 \
  -e LIDARR_API_KEY=... \
  coda

Volumes:

  • /music — arquivos de música (mesmo path usado pelo Lidarr).
  • /data — volume persistente do SQLite (coda.db).

Configuração

Definida por variáveis de ambiente (defaults) e sobrescrita pela interface web (persistida no SQLite; a web vence). Em dev, o .env é carregado no startup.

Variável Default Descrição
PORT 8080 Porta do servidor HTTP
WORKERS 4 Workers simultâneos
FFMPEG_BIN /usr/bin/ffmpeg Caminho do ffmpeg
FFPROBE_BIN /usr/bin/ffprobe Caminho do ffprobe
LOG_LEVEL INFO Nível de log
DRY_RUN false Não converte nem apaga (só registra)
LIDARR_URL URL base do Lidarr
LIDARR_API_KEY API key do Lidarr
WEBHOOK_SECRET Segredo para validar webhooks
MUSIC_PATH /music Diretório com os arquivos de música
DB_PATH /data/coda.db Caminho do arquivo SQLite
TIMEZONE UTC Timezone da janela de trabalho
WORK_WINDOW_ENABLED false Habilita a janela de trabalho
WORK_WINDOW_START 08:00 Início da janela (HH:MM)
WORK_WINDOW_END 18:00 Fim da janela (HH:MM)

Estrutura do Projeto

cmd/server/        # entrypoint
internal/          # config, scheduler, webhook, queue, worker,
                   # transcoder, validator, lidarr, logger, web,
                   # models, store, scanner
web/               # styles/ (fonte CSS), static/ (gerado), templates/
data/              # volume local do SQLite

Documentação