Essa é uma revisão anterior do documento!
Ubalab > Projetos > 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:
- Inserir a abertura do bloco de apoios;
- Inserir uma vinheta da Gaivota;
- Carregar todos os arquivos em determinada pasta;
- 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:
- Excluem todas as músicas menos a que está tocando no momento
- Carregam a playlist
- Reordenam a playlist aleatoriamente
- 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:
- Temos um switch com algum tipo de problema.
- 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:
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
Tem simplesmente dentro dele 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.