Ubalab > Projetos / MidiaLivre > LiveGaivota

LiveGaivota

Estação de trabalho responsável pela programação automática da Rádio Cultural Comunitária Gaivota FM.

Descrição do sistema

Hardware atual

  • Acer Aspire
  • AMD Athlon™ 64 X2 Dual-Core Processor TK-53
  • 2G RAM
  • HD 120G
  • Pendrive de 32 formatado como vfat

Sistema operacional

  • Debian Wheezy (7.9) (10/09/2015)

Software relevante

  • MPD para gerenciamento de biblioteca de músicas
  • MPC - cliente CLI para MPD
  • Darkice - cliente para envio de stream icecast

Configuração inicial

Sistema de som

  • Servidor MPD gerenciando música e playlists na pasta padrão (/var/lib/mpd/music e /var/lib/mpd/playlists)
  • Primeiro protótipo: link simbólico na pasta music apontando para uma pasta no pendrive. Esta pasta está subdividida nas pastas dia, espaco-local, fds e fds-I.

todo

  • Inserir blocos de apoio (definir periodicidade e estrutura)
  • Entrar em pontos aleatórios da lista após carregá-la pelo script.
  • Quebrar os blocos de apoio 10 em horários alternados.
  • Resolver Voz do Brasil:
    • Playback simultâneo em dois programas diferentes, configurando o Alsa com plugin Dmix;
    • Script para usar o mplayer em modo daemon entre as 19h e as 20h.
  • Liberar espaço, ou pôr pendrive/disco USB para inserir mais músicas na seleção automática (e ainda disponibilizar a pasta para outras máquinas na rede)
  • Definir autorizações de usuários para o MPD e configurar os clientes de acordo.
  • Configurar Interface Behringer UCA para realizar o stream a partir da saída da mesa direto na LiveGaivota (e liberar o netbook para ser só servidor web/impressão).

Log

10/09/2015

1. aptitude upgrade

2. organização da biblioteca. temos uma pasta “som”, dentro da qual existem as pastas “prefixo” e “apoios”. a de prefixos tem cinco arquivos que precisam entrar aleatoriamente a cada meia hora. a de apoios entra em blocos. temos também um link simbólico para a pasta “mascara” que fica no pendrive, com uma primeira seleção de músicas.

3. criando uma pasta para os scripts:

 # mkdir ~/scripts

4. editando o script para inserir prefixo. cheguei na solução abaixo, inserida em /usr/local/bin/prefixo. eu listo todos os arquivos da pasta som/prefixo/, seleciono um deles de maneira aleatória e depois uso o mpc insert para colocá-lo após a música que está tocando no momento.

(lembrar para depois: corrigir o script de prefixo para refletir as mudanças na organização das pastas)

 #!/bin/sh
 # escolhendo uma entrada aleatoria (ref abaixo)
 # http://stackoverflow.com/questions/2346730/picking-a-random-line-from-stdout
 mpc ls som/prefixo | shuf | head -n 1 | mpc insert

5. enquanto estudava um pouco do cron, percebi que o horário do computador estava errado. instalei o ntp.

 # aptitude install ntp

6. então fiz um arquivo de cron para carregar o script a cada meia hora, sempre aos 25 e 55 minutos de cada hora:

 25 * * * * /usr/local/bin/prefixo  > /dev/null
 55 * * * * /usr/local/bin/prefixo  > /dev/null

7. usando um cliente gráfico (qmpdclient), conectei-me ao servidor e fiz uma primeira playlist pegando toda a seleção preparada para o horário das 14h às 19h, em ordem direta. por enquanto vamos trabalhar com ela inteira, e no futuro vamos fazer blocos de conteúdo.

8. para os apoios, vamos precisar reorganizar a pasta. uma primeira hipótese é fazer subpastas com o número de vezes que o spot entra. como teste, criei as pastas 05 e 10.

9. Passei o restante do tempo configurando um cliente openvpn na estação, para poder continuar trabalhando nela em casa.

17/09/2015

1. Trabalhando no script para inserir a playlist. Eu tinha usado o comando “mpc load”, mas ele insere a playlist selecionada ao fim da playlist atual. Isso levaria a problemas: se a lista corrente fosse muito extensa, a recém adicionada não seria tocada nunca. A solução que encontrei foi usar dois comandos (neste caso carregando a lista “14-19”)

 # excluir da lista todas as músicas exceto a que está tocando agora
 mpc crop 
 # carregar a playlist desejada
 mpc load 14-19

2. Copiei o script para /usr/local/bin, fiz um script de cron para fazer a operação todo dia às 14h e carreguei-o no crontab

 rsync -avz lista-14-19 /usr/local/bin   
 echo "0 14 * * * /usr/local/bin/lista-14-19  > /dev/null" > lista-14-19.cron
 crontab lista-14-19.cron

Atenção: percebi que usando o comando “crontab nomedoarquivo”, meu crontab atual é substituído. Não consegui encontrar maneira de evitar isso, então acho que o melhor é manter um arquivo de cron geral para todos os scripts, e depois carregá-los de uma vez só.

 cat lista-14-19.cron prefixo.cron >> cron.scripts
 crontab cron.scripts   

3. Hora de manipular melhor as playlists. Para os primeiros testes, eu fiz uma playlist usando o cliente gráfico do mpd: navegando pelos diretórios nos horários entre 14h e 19h, arrastando todos para a lista principal e por fim salvando a playlist. Mas ao analisar o formato dos arquivos M3U gerados (em /var/lib/mpd/playlists), vi que eram simples listas de arquivos com o caminho completo. Então uma maneira bastante simples de fazer a mesma coisa seria usando o find e o sort. Gerei uma lista de todos os MP3 dentro da pasta 07-12, assim:

 find /var/lib/mpd/music/mascara/dia/07-12/ -type f -iname "*mp3"| sort > /var/lib/mpd/playlists/07-12.m3u
 

Mas antes de criar as outras playlists, resolvi reorganizar a biblioteca. Em vez de um link simbólico em /var/lib/mpd/music apontando para o pendrive, resolvi reservar uma partição do HD exclusivamente para armazenar os arquivos. Vou manter uma cópia no USB como backup, mas será só isso.

4. Começando a encontrar o formato para o apoio cultural. De início, criei uma playlist com vinheta de apoio, três spots e uma vinheta da Gaivota encerrando o bloco. Quero carregá-lo em seguida à música que estiver tocando. Para isso preciso listar as entradas da playlist e carregá-las com o mpc insert. Testando aqui.

5. Mudei de rumo para os blocos de apoio. Agora está me parecendo melhor usar pastas para separar os spots que entram 5 ou 10 vezes por dia, e criar um script que permita, em algumas ocasiões, fazer o seguinte:

  1. Inserir a abertura do bloco de apoios;
  2. Inserir uma vinheta da Gaivota;
  3. Carregar todos os arquivos em determinada pasta;
  4. Inserir uma vinheta de encerramento do bloco de apoios.

Pensei em distribuir da seguinte forma os apoios:

  • 5 vezes ao dia: 2 das 6h às 12h; 2 das 12h às 19h; 1 das 20 à meia-noite;
  • 10 vezes ao dia: 4 das 6h às 12h; 4 das 12h às 19h; 2 das 20 à neia-noite.

Da meia-noite às seis da manhã, nenhum apoio cultural será veiculado (salvo exceções, claro). Para evitar sobreposição, acho que todos os spots de 10x devem estar também na pasta de 5x, e o script será disparado cinco vezes adicionais (em vez de dez vezes além daquelas cinco). Talvez até criar um link simbólico na pasta 05 apontando para o conteúdo da 10 (mas será que funciona com subdiretórios? ou preciso periodicamente atualizar os links simbólicos?)

18/09/2015

Fiz algumas alterações nos scripts que carregam as playlists. Agora eles fazem o seguinte:

  1. Excluem todas as músicas menos a que está tocando no momento
  2. Carregam a playlist
  3. Reordenam a playlist aleatoriamente
  4. Verificam se o mpd está tocando

Usando como exemplo o script da lista 00-06:

#!/bin/sh
# excluindo todos os arquivos exceto o que estah tocando agora
mpc crop
# carregando a playlist 00-06
mpc load 00-06
mpc shuffle
mpc play

20/09/2015

Começando a testar uma primeira solução para os blocos de apoio. Fiz um script para carregar cinco vezes ao dia um bloco de apoios:

 #!/bin/sh
 # Inserindo vinheta aleatoria
 mpc ls som/vinhetas/gaivota | shuf | head -n 1 | mpc insert
 # selecionando todos os arquivos da pasta
 for arquivo in /var/lib/mpd/music/som/apoios/05/*
 do
 	mpc insert 'som/apoios/05/'${arquivo##*/}
 done
 #inserindo abre apoios
 mpc insert som/apoios/apoios-vox-renato.mp3

Ainda não sei se gostei. Melhor uma versão usando diretamente o mpc para listar (óbvio!):

 #!/bin/sh
 # Inserindo vinheta aleatoria
 mpc ls som/vinhetas/gaivota | shuf | head -n 1 | mpc insert
 # selecionando todos os arquivos da pasta
 for apoio in $( mpc ls som/apoios/05/ )
 do
 	mpc insert $apoio
 done
 #inserindo abre apoios
 mpc insert som/apoios/apoios-vox-renato.mp3

22/09/2015

Simplificando mais ainda, descobri que dá pra mandar mais de uma entrada para o mpc insert pelo pipe. Então é só usar o mpc ls:

#!/bin/sh
# Inserindo vinheta aleatoria
	mpc ls som/vinhetas | shuf | head -n 1 | mpc insert
# listando e inserindo arquivos na pasta apoios/05
	mpc ls som/apoios/05 | mpc insert
#inserindo abre apoios
        mpc insert som/apoios/apoios-vox-renato.mp3

E inseri cinco chamadas desse script no crontab, nos horários 8h10, 11h10, 14h10, 16h10, 20h10.

# apoios 5
10 8 * * 1-5 /usr/local/bin/apoio5 > /dev/null
10 11 * * * 1-5 /usr/local/bin/apoio5 > /dev/null
10 14 * * * 1-5 /usr/local/bin/apoio5 > /dev/null
10 16 * * * 1-5 /usr/local/bin/apoio5 > /dev/null
10 20 * * * 1-5 /usr/local/bin/apoio5 > /dev/null

25/09/2015

Agora pensando no bloco de 10 veiculações diárias. Depois de refletir um pouco, acho que a melhor maneira é assumir que qualquer spot que toque dez vezes ao dia precisa também tocar cinco vezes (!). Então o script do bloco apoio5 precisa também chamar qualquer coisa que estiver na pasta apoio10. E depois chamar no cron em mais cinco horários alternados com os que já estavam. Assim:

apoio fica assim:

#!/bin/sh
#inserindo abre apoios
      mpc insert som/apoios/apoios-vox-renato.mp3
# Inserindo vinheta aleatoria
mpc ls som/vinhetas | shuf | head -n 1 | mpc insert
# listando e inserindo arquivos na pasta apoios/05
mpc ls som/apoios/05 | mpc insert
# listando e inserindo arquivos na pasta apoios/10
mpc ls som/apoios/10 | mpc insert
#inserindo abre apoios
      mpc insert som/apoios/apoios-vox-renato.mp3

apoio10 fica assim:

#!/bin/sh
#inserindo abre apoios
      mpc insert som/apoios/apoios-vox-renato.mp3
# Inserindo vinheta aleatoria
mpc ls som/vinhetas | shuf | head -n 1 | mpc insert
# listando e inserindo arquivos na pasta apoios/10
mpc ls som/apoios/10 | mpc insert
#inserindo abre apoios
      mpc insert som/apoios/apoios-vox-renato.mp3

e adicionei as seguintes linhas ao crontab:

# apoios 10
10 9 * * 1-5 /usr/local/bin/apoio10 > /dev/null
10 10 * * * 1-5 /usr/local/bin/apoio10 > /dev/null
10 15 * * * 1-5 /usr/local/bin/apoio10 > /dev/null
10 17 * * * 1-5 /usr/local/bin/apoio10 > /dev/null
10 21 * * * 1-5 /usr/local/bin/apoio10 > /dev/null

Para facilitar a administração dos apoios, precisei criar uma maneira de os usuários de windows em outros computadores dentro da rede acessarem a pasta. Para isso, instalei o samba e compartilhei a pasta /media/som/apoios. Fui no computador do estúdio que infelizmente ainda roda windows, e criei um atalho no desktop para esta pasta compartilhada.

Alguma coisa estava evitando o carregamento dos blocos de apoio. Meu maior suspeito são os dias da semana. Testei substituir, em uma linha do cron, o 1-5 por um *, e aparentemente rodou. Vou precisar estudar mais a sintaxe do cron para definir somente dias de semana.

A fazer:

  • estudar as permissões de usuários e aprender a configurar o mpc com permissões
  • estudar sintaxe do crontab
  • mudar o carregamento de playlist salva para listagem viva dos diretórios
  • voz do brasil

01/10/2015

O sistema está em testes na programação ao vivo da rádio desde o fim de semana passado. Estou aos poucos refinando os scripts, os blocos e arrumando as rotinas de cron. Deixei de documentar todas as alterações aqui, porque seria muita informação de pouca relevância. Mas estou mantendo tudo no gitlab.

Ontem eu estava conversando com o Brum no estúdio da rádio e fazendo alguns ajustes no formato dos blocos de apoio, quando o sistema simplesmente parou. Não consegui acessar por SSH e fui direto ao laptop. Ele parecia rodar normalmente, mas o MPC estava parado e a rede não pingava. Reiniciei a máquina, funcionou por algum tempo e depois parou novamente. Brum puxou uma das programações antigas, e deixamos rodar. Deixei para resolver hoje na Hackinta.

Hoje pela manhã limpei o laptop, liguei-o na bancada do escritório, resolvi desabilitar o cliente openvpn (que era o último registro no logs/messages, horas antes de travar). Rodou por duas horas e meia, sem problemas. Instalei novamente no estúdio e saí. Poucos minutos depois, em casa, percebi que alguém havia mudado a programação. Verifiquei remotamente que o sistema estava rodando e voltei ao estúdio.

Quando cheguei, novamente havia parado de tocar música. E não estava mais pingando para fora. Mudei de perspectiva e decidi reiniciar o switch que distribui a internet dentro do estúdio. Bingo, poucos segundos depois o MPD voltou a funcionar.

Duas conclusões, por enquanto:

  1. Temos um switch com algum tipo de problema.
  2. O MPD estava travando quando a internet não funcionava, o que não pode acontecer. Lembrei que havia habilitado o icecast como uma das saídas do mpd. Seria ele que estava fazendo o MPD parar de tocar as músicas? Tentei isolar o problema: primeiro desabilitei a saída icecast (no meu caso aqui foi simplesmente mandar $ mpc disable 3). Então arranquei o cabo de força do switch e esperei 10s. O áudio continuou ok. Para verificar a hipótese, habilitei novamente o icecast. Depois de me assegurar que o MPD continuava firme, desliguei o switch outra vez. Em cerca de cinco segundos, o áudio parou. Um pouco depois, inseri de novo o cabo, e a transmissão voltou de onde havia parado. Donde concluí que era mesmo a saída icecast que fazia tudo parar. Então decidi desabilitá-la até resolver a situação do switch ou ter tempo de pesquisar uma saída que evite esse bloqueio.

03/03/2016

Mudei a estação para dentro do escritório da Gaivota. Tarefas que preciso resolver agora:

  • Voz do Brasil (que travou na dificuldade de tocar dois programas simultâneos usando ALSA)
  • Migrar o stream para o Live

Pelo que pesquisei, o uso simultaneo do ALSA é possível com o plugin dmix. Encontrei um tutorial dele. Os testes com o aplay deram certo.

Procurando um pouco mais, encontrei uma menção ao dmix na documentação do próprio mpd. Segui as modificações sugeridas (mudar o mpd.conf e o /etc/asound.conf), mas por enquanto não deu (o log do MPD deu “option 'options' on line 209 was not recognized”. Será só questão de plural? Não…

10/03/16

Organizando as demandas aqui na wiki e procurando soluções para usar o dmix no MPD. Será que preciso compilar uma versão que o suporte?

17/03/16

Vim algumas vezes durante esta semana. Modifiquei algumas coisas nos scripts (quebrei ao meio os blocos de apoio 10x, e eles alternam a cada hora no horário útil). E finalmente migrei o stream para esta estação. Eu estava usando a sintaxe errada para a configuração da placa de som. O correto é “hw:1,0” em vez de “hw1,0”.

Tentando resolver a transmissão da Voz do Brasil. Costumamos usar o stream da Rádio Nacional de Brasília, disponível nesta página:

http://radios.ebc.com.br/sites/_radios/player_streamer/index.html?emissora=radio-nacional-fm-brasilia

O código-fonte da página aponta dois streams: um rtmp e um http. O http baixa por alguns segundos e para. O rtmp não abre nem no mpd nem no mplayer. Parece ter um começo de solução aqui:

http://stackoverflow.com/questions/1024632/rtmp-is-there-such-a-linux-command-line-tool

http://unix.stackexchange.com/questions/16806/play-rtmp-stream-from-command-line

Que aponta para baixar o stream (em FLV!) e convertê-lo para mp3. Se isso rolar, talvez dê para fazer em tempo real ou ao menos com um delay de uns 5 segundos. Será?

A última sugestão no Stack Overflow indica que o ffmpeg pode ser usado para baixar e converter ao mesmo tempo. Tentei aqui, mas não deu. Mensagem de erro:

HandShake: client signature does not match!
Closing connection: NetStream.Play.StreamNotFound
rtmp://ebcremuxlivefs.fplive.net/ebcremuxlive-ebcnacionalfm/stream1: Operation not permitted

Nenhum resultado com rtmdump nem com o flvstreamer. Vou explorar as opções http.

Este arquivo:

http://ebcremuxlive-live.hls.adaptive.level3.net/manifests/ebcremuxlive-ebcnacionalfm/live.m3u8

Contém isso:

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=64000
http://ebcremuxlive-live.hls.adaptive.level3.net/hls-live/ebcremuxlive-ebcnacionalfm/_definst_/live/stream1.m3u8

Já este arquivo listado lá dentro tem uma série de coisas que começam assim e vão adiante:

#EXTM3U
#EXT-X-MEDIA-SEQUENCE:36402
#EXT-X-ALLOW-CACHE:NO
#EXT-X-VERSION:2
#EXT-X-TARGETDURATION:8
#EXTINF:8,
../../../../hls-live/streams/ebcremuxlive-ebcnacionalfm/events/_definst_/live/stream1Num36402.ts
#EXTINF:8,
../../../../hls-live/streams/ebcremuxlive-ebcnacionalfm/events/_definst_/live/stream1Num36403.ts
#EXTINF:8,
../../../../hls-live/streams/ebcremuxlive-ebcnacionalfm/events/_definst_/live/stream1Num36404.ts

E assim por diante.

24/03/2016

Pensando em maneiras para facilitar a inserção de arquivos de música para quem não tem familiaridade com o linux e linha de comando. Decidi pegar um pequeno disco externo (de 30G), replicar a estrutura de pastas da “máscara” e então modificar os scripts para, antes do shuffle, carregar os arquivos da pasta correspondente também.

mount /dev/sdb1 /media/biblioteca
mkdir /media/biblioteca/mascara-ext
mkdir /media/biblioteca/mascara-ext/dia/
mkdir /media/biblioteca/mascara-ext/dia/00-07
...

(e assim por diante)

31/03/2016

Começando a estudar possibilidades do Telegram para o fluxo de trabalho da rádio. Vou documentar na página GaivotaGram.

01/04/2016

Referências para o futuro próximo:

Referências