Como fazer seu próprio receptor de rádio on-line no Linux
As rádios on-line não são nenhuma novidade, porém são recursos muito interessantes (sobretudo àqueles que sempre estão querendo conhecer novos estilos musicais e culturas diferentes). Para os padrões de conectividade atuais, é perfeitamente possível ouvir uma rádio on-line com uma conexão de Internet comum. Este post ensinará você a construir seu próprio player de rádio on-line no Linux!
Pré-requisitos
Para reproduzir o projeto proposto, os seguintes pré-requisitos são necessarios:
- Possuir algum dispositivo com acesso à Internet, saída de som e com alguma distribuição Linux instalada (ou até mesmo uma máquina virtual Linux). Este projeto foi testado com sucesso em distribuições derivadas da Debian.
- Conhecimentos básicos de Python
- Conhecimentos básicos de Linux
- Conhecimentos básicos de algum editor de texto em modo terminal do Linux (exemplo: VI e Nano)
Estratégia do projeto
Este projeto é, na verdade, um controlador de um player consagrado do Linux. O player em questão chama-se mplayer. Trata-se de um player muito leve e versátil para o Linux. Ou seja, o projeto se comunica com o player e este (rodando em “background”) obedece aos comandos desejados. Para isto ser possível, o mplayer opera em modo slave.
Os comandos são trafegados utilizando um recurso chamado named pipes. Isto permite que processos distintos no Linux se comuniquem / enviem mensagens uns aos outros, ficando a cargo do sistema operacional (neste caso, o kernel do Linux) gerenciar a transferências destas mensagens. No caso específico deste projeto, as mensagens trafegadas entre o receptor e o mplayer são os comandos que o mplayer aceita em modo slave, e são escritas e lidas em arquivos FIFO salvos no diretório /tmp.
[stextbox id=”info” caption=”Dica:” color=”000000″ bcolor=”FBFF77″ bgcolor=”FBFF77″ bgcolorto=”FBFF77″]Sempre que for fazer este tipo de comunicação entre processos, o arquivo FIFO é mapeado em RAM, independente de onde você criá-lo (ou seja, ele não pertence de verdade ao filesystem / não é um arquivo de fato). Essa característica é default do Linux, e oferece desta forma muito mais velocidade de escrita e leitura.
Além disso, em se tratando de Linux embarcado, isto é essencial para evitar múltiplas escritas em memória Flash (o que é “mortal” para este tipo de sistema, uma vez que pode levar à falha completa da Flash em pouco tempo devido ao limite de escritas que toda memória Flash possui).[/stextbox]
Para uma referência completa dos comandos do mplayer em modo slave, clique aqui.
Preparando o terreno
Antes de fazer o projeto propriamente dito, são necessárias algumas etapas prévias:
– Instalação do mplayer
Para instalar o mplayer, basta utilizar o comando abaixo:
sudo apt-get install mplayer2
– Escolha das rádios
Uma das formas do mplayer tocar uma rádio on-line é através do link de sua playlist (arquivo .pls). Portanto, ao escolher suas rádios a serem ouvidas, procure pela playlist em formato .pls. Abaixo há alguns exemplos:
- http://yp.shoutcast.com/sbin/tunein-station.pls?id=1057392
- http://panel3.serverhostingcenter.com:2199/tunein/radiobackstage1.pls
- http://yp.shoutcast.com/sbin/tunein-station.pls?id=1425714
Dica: um ótimo lugar para buscar rádios on-line é o Shoutcast.
Testando o mplayer junto com suas estações de rádio online
Antes de partir para o projeto em si, é prudente verificar se o mplayer toca corretamente sua rádio on-line. Este teste é necessário pois pode ser que a rádio esteja temporariamente fora do ar (melhor saber isso antes de quebrar a cabeça com um problema que não está “do seu lado”, concorda?).
A forma de fazer isso, considerando um exemplo de rádio on-line, pode ser vista abaixo:
mplayer -playlist http://panel3.serverhostingcenter.com:2199/tunein/radiobackstage1.pls
Feito isso, o mplayer inicializará e tocará a rádio on-line. Para sair do mplayer, basta pressionar a tecla ‘q’ (ou interromper a aplicação pressionado Ctrl + C).
Talk is cheap. Show me the code!
Chegou a hora do código! O projeto foi desenvolvido em Python. O código-fonte do projeto do receptor de rádio online pode ser visto abaixo.
Se preferir, acesse o código-fonte no meu GitHub clicando aqui.
import os
import sys
import subprocess
import shlex
#Variaveis globais
CaminhoArquivoControle="/tmp/ControleRadio"
ComandoMPlayer = "mplayer -input file=/tmp/ControleRadio -slave -playlist "
#Variaveis das playlists
Playlists=[] #Array que contem todas as playlists
NumeroPlaylists = 0 #quantidade de playlists
NomesRadios=[] #Nomes das radios / playlists
PlaylistEscolhida=0 #Indice da playlist escolhida
NomeRadio1="Radio ShoutCast"
NomeRadio2="Radio Backstage (www.radiobackstage.com)"
#Funcao: inicia lista de playlists
#Parametros: nenhum
#Retorno: nenhum
def IniciaListaPlaylists():
global Playlists
global NomesRadios
global NumeroPlaylists
#playlist 1
Playlists.append("http://yp.shoutcast.com/sbin/tunein-station.pls?id=1057392")
NomesRadios.append("Radio Shoutcast")
#playlist 2
Playlists.append("http://panel3.serverhostingcenter.com:2199/tunein/radiobackstage1.pls")
NomesRadios.append("Radio Backstage")
#playlist 3
Playlists.append("http://yp.shoutcast.com/sbin/tunein-station.pls?id=1425714")
NomesRadios.append("Techno")
NumeroPlaylists=3
return
#Funcao: Toca a plsylist escolhida
#Parametros: nenhum
#Retorno: nenhum
def TocaPlaylist(PEscolhida):
global Playlists
global ComandoMPlayer
os.system("pkill -f mplayer")
ComandoPlaylist = ComandoMPlayer + Playlists[PEscolhida]
#inicia processo e direciona o stdout para /dev/null
FNULL = open(os.devnull,'w')
args = shlex.split(ComandoPlaylist)
InterfaceMPlayer = subprocess.Popen(args, shell=False, stdin=subprocess.PIPE, stdout=FNULL, stderr=subprocess.STDOUT)
#ajusta volume em 50%
os.system('echo "volume 50" >'+CaminhoArquivoControle)
return
#Funcao: cria arquivo de controle do player (MPlayer)
#Parametros: nenhum
#Retorno: nenhum
def CriaArquivoControle():
#se arquivo ja existe, nada e feito.
if (os.path.exists(CaminhoArquivoControle)):
return
try:
os.mkfifo(CaminhoArquivoControle)
except:
print "Falha ao criar arquivo de controle. Por favor, verifique o caminho de criacao do mesmo."
exit(1)
#Funcao: escreve na tela o menu de opcoes
#Parametros: nenhum
#Retorno: opcao escolhida
def MostraMenuDeOpcoes():
global NomesRadios
global PlaylitsEscolhida
print "-----------------------"
print " Menu de opcoes "
print "-----------------------"
print "Estacao: "+NomesRadios[PlaylistEscolhida]
print " "
print "<p> Play/pause"
print "<s> Sair"
print "<+> Sobe volume"
print "<-> Desce volume"
print "<d> Proxima estacao"
print "<a> Estacao anterior"
print " "
opcao = raw_input("Opcao> ")
return opcao
#------------------
#Programa principal
#------------------
#Inicializa lista de playlists
IniciaListaPlaylists()
#Cria arquivo de controle e inicia processo MPlayer
CriaArquivoControle()
#Toca playlist 1
TocaPlaylist(PlaylistEscolhida)
while True:
try:
os.system("clear")
Tecla = MostraMenuDeOpcoes()
if (Tecla == "p"):
print "[ACAO] Play/Pause"
os.system('echo "pause" > '+CaminhoArquivoControle)
if (Tecla == "s"):
print "[ACAO] Sair"
os.system('echo "quit 0" > '+CaminhoArquivoControle)
os.system("pkill -f mplayer")
exit(1)
if (Tecla == "+"):
print "[ACAO] Sobe volume"
os.system('echo "volume +10" > '+CaminhoArquivoControle)
if (Tecla == "-"):
print "[ACAO] Desce volume"
os.system('echo "volume -10" > '+CaminhoArquivoControle)
if (Tecla == "d"):
print "[ACAO] Proxima estacao"
PlaylistEscolhida = PlaylistEscolhida + 1
if (PlaylistEscolhida == NumeroPlaylists):
PlaylistEscolhida = 0
TocaPlaylist(PlaylistEscolhida)
if (Tecla == "a"):
print "[ACAO] Estacao anterior"
PlaylistEscolhida = PlaylistEscolhida - 1
if (PlaylistEscolhida < 0):
PlaylistEscolhida = NumeroPlaylists-1
TocaPlaylist(PlaylistEscolhida)
except (KeyboardInterrupt):
print "Aplicacao sendo encerrada."
exit(1)
Para executar o projeto, basta salvar seu script com qualquer nome e executá-lo com o seguinte comando:
python NOMEDOSEUSCRIPT.py
Resultado
Veja abaixo as fotos e vídeo do resultado do projeto:
Fotos:
[slideshow_deploy id=’337′]
Vídeo:
Trabalhos futuros /próximos passos
Este projeto é algo experimental. O objetivo deste é, além de fazer com que você desenvolvedor crie algo divertido (afinal, quem não gosta de ouvir música, não é mesmo?), a familiarização com comunicação entre processos no Linux.
Se for seu desejo melhorar este projeto, segue abaixo alguns pontos aos quais sugiro melhorias:
- Substituição do pkill -f (comando que mata processos com nomes familiares ao qual lhe é passado como parâmetro) por um kill no PID do processo exato do mplayer. Isto garante que outros processos com nomes semelhantes a mplayer não sejam interrompidos por acidente.
- Substituição da escrita em FIFO através de os.system() por escritas não-blocantes diretamente no arquivo FIFO.
- Acrescentar uma interface gráfica
Agradecimentos
Segue aqui um agradecimento especial ao Cleiton Bueno e Felipe Lavratti por toda a ajuda e paciência em me ajudar neste projeto. Muito obrigado mesmo!
Gostou do artigo? Tem dúvidas? Tem críticas? Comente abaixo!