You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
337 lines
11 KiB
337 lines
11 KiB
% |
|
% new 24 juillet 2014 - Mixart Myrys |
|
% |
|
\chapter{streaming} |
|
\label{chap:streaming} |
|
\index{streaming} |
|
|
|
Avertissement : pour le moment\footnote{En juillet 2014}, nous |
|
n'allons nous pencher que sur la diffusion de flux audios, avec |
|
des encodages libres comme \textsl{ogg} ou \textsl{speex}. |
|
Tout simplement parce que le monde de la vidéo est un gigantesque |
|
foutoir de codecs, de containers, de brevets logiciels et |
|
d'incompatiblités diverses et variées. |
|
|
|
Une notion importante à bien comprendre, c'est l'organisation |
|
du flux des sons immatériels au travers des intertubes. |
|
|
|
\textbf{insert picture here !}\index{XXX} |
|
|
|
%------------------------------------------------------------- |
|
\section{icecast2} |
|
\index{icecast2} |
|
\label{icecast2} |
|
|
|
Icecast est, semble-t-il, \textbf{le} serveur de streaming de référence. |
|
Il se configure facilement avec des fichiers en XML\index{XML}. |
|
Première approche d'une ergonomie différente, vous êtes avertis. |
|
|
|
\begin{quote} |
|
Icecast, the project, is a collection of programs and libraries for |
|
streaming audio over the Internet. This includes: |
|
Icecast, the program that streams audio data to listeners, |
|
libshout, a library for communicating with Icecast servers and |
|
Ices2\index{ices}, a program that sends audio data to Icecast servers |
|
|
|
\end{quote} |
|
|
|
Pour alimenter Icecast en son, il faut utiliser un |
|
\textsl{source-client} approprié. Le modèle recommandé |
|
est \textbf{ices2} qui est détaillé un peu plus loin, |
|
à la page \pageref{ices2}. |
|
|
|
Il peut envoyer depuis une entrée audio (alsa, jack, pulseaudio...) |
|
ou une playlistde fichiers \texttt{.ogg}\index{ogg}. |
|
|
|
|
|
|
|
\textsl{more to come...} |
|
|
|
%------------------------------------------------------------- |
|
\section{liquidsoap} |
|
\index{liquidsoap} |
|
|
|
Mais nous allonc commencer par un outil puissant, bien que |
|
délicat à comprendre au premier abord~: |
|
\texttt{https://www.liquidsoap.info/} |
|
|
|
\begin{quote} |
|
Liquidsoap is an extensible and flexible audio stream generator, |
|
mainly used for streaming to a shoutcast/icecast server. |
|
It is also possible to output in a file, to speakers or as |
|
raw PCM stream. |
|
|
|
liquidsoap can |
|
perform any audio processing, mixing streams together, |
|
applying filters, generating sound procedurally, |
|
there is no limit but your imagination. |
|
Input files can be accessed through the network, using samba, |
|
ftp or speech synthesis. |
|
The system features lots of programming operators, including user |
|
requests, time-based selection, sum... |
|
\end{quote} |
|
|
|
Un étonnant langage de script pour gérer tous ces octets musicaux |
|
en les promenant un peu dans tous les sens, la possibilité |
|
de commander Savonet avec un simple telnet\index{telnet}. |
|
Vite, un exemple d'utilisation, vous créez un fichier texte avec |
|
cez quelques lignes dedans et vous le sauvez sous le nom |
|
\texttt{savon.liq} : |
|
|
|
\begin{verbatim} |
|
set("log.file.path","/tmp/savon.log") |
|
set("log.stdout",true) |
|
|
|
output.icecast (%vorbis, |
|
host = "10.20.0.23", |
|
port = 1984, |
|
password = "hopla!", |
|
mount = "savon.ogg", |
|
single("loveme.ogg")) |
|
\end{verbatim} |
|
|
|
Avec ce petit programme, nous pouvons envoyer en boucle un fichier |
|
Ogg vers notre serveur. |
|
Les deux premières lignes permettent de voir et d'enregistrer les |
|
diverses actions. |
|
Et la grosse instruction \texttt{output.icecast} |
|
envoie la musique dans votre serveur |
|
Icecast2 en passant les paramètres nécessaires. |
|
|
|
\subsection{10.20.0.23} |
|
|
|
Maintenant, voyons un exemple plus complet et plus réaliste, |
|
largement inspiré d'un tutoriel de la documentation officielle, |
|
et qui deviendra un de ces jours la base de la nouvelle% |
|
\footnote{L'ancienne ayant été fermée pour des raisons |
|
incompréhensibles.} radio de Myrys~: |
|
|
|
\begin{verbatim} |
|
set("log.file.path", "/tmp/savon.log") |
|
set("log.stdout", false) |
|
|
|
default = single("loveme.ogg") |
|
openbsd = playlist(mode="random", "files/openbsd.pls") |
|
others = playlist(mode="random", "files/others.pls") |
|
jingles = playlist( "files/jingles.pls") |
|
|
|
radio = fallback([ switch([({ 5h-11h }, openbsd), |
|
({ 11h-5h }, others)]), |
|
default]) |
|
radio = random(weights=[1,12],[ jingles, radio ]) |
|
|
|
output.icecast( %vorbis, |
|
host = "localhost", |
|
port = 1984, |
|
password = "hopla!", |
|
mount = "savon.ogg", |
|
radio) |
|
\end{verbatim} |
|
|
|
Ah bah oui, ça commence à être robuste, mais en fait c'est |
|
presque simple à comprendre, et un peu plus compliqué à mettre |
|
en œuvre. |
|
|
|
On se retrouve vite face à un problème classique : |
|
les différences de niveau sonore entre les divers morceaux. |
|
Et comme on veut avancer sur d'autres choses, on rache un |
|
petit bout de Bash avec de la poudre verte dedans : |
|
|
|
\begin{verbatim} |
|
#!/bin/bash/ |
|
echo "que faire ?" |
|
\end{verbatim} |
|
|
|
Cette poudre verte pourrait bien être \texttt{vorbisgain(1)}\dots |
|
|
|
\subsection{rotation des playlists} |
|
|
|
\begin{verbatim} |
|
pl2014 = playlist("2014") |
|
pl2013 = playlist("2013") |
|
... |
|
jingles = playlist("jingles") |
|
s = rotate([pl2014, pl2013, ..., jingles]) |
|
output.icecast(..., s) |
|
\end{verbatim} |
|
|
|
\subsection{Take over the playlist} |
|
|
|
XXX\index{XXX} |
|
|
|
Il est également possible, avec liquidsoap, d'interrompre la |
|
diffusion d'une playlist à partir d'une autre source |
|
(fichier ou entrée audio), eventuellement externe. |
|
|
|
\lstinputlisting{code/takeover.liq} |
|
|
|
\subsection{trucs divers} |
|
|
|
Que signifie ce message : \textbf{That source is fallible.} ? |
|
Par exemple, que le fichier que vous aviez soigneusement |
|
désigné comme \texttt{default} n'existe plus sur le disque. |
|
|
|
|
|
Comment envoyer vers plusieurs icecasts ? Bah c'est très facile : |
|
il suffit de mettre plusieurs "blocs" \texttt{output.icecast} à |
|
la suite les uns des autres ;) |
|
|
|
|
|
%==================================================================== |
|
\section{Source clients} |
|
\label{sourceclients} |
|
|
|
Il existe une foultitude de clients source pour abreuver icecast2. |
|
|
|
|
|
%------------------------------------------------------------- |
|
\subsection{ices2} \index{ices2} \label{ices2} |
|
|
|
Premier mystère : comment faire le rapprochement entre |
|
la déclaration du périphérique d'entrée |
|
(\texttt{<param name="device">hw:1,0</param>}) et |
|
l'équivalent dans le monde Alsa ? |
|
|
|
La commande \texttt{arecord -L} va nous donner quelques |
|
informations sur les « points d'entrée » utilisables. |
|
Liste dont nous extrayons (par la pure pensée logique) |
|
ce fameux nom de device~: \texttt{ plughw:CARD=Snowball,DEV=0} |
|
XXX\index{XXX} que nous pouvons mettre dans le XML. |
|
|
|
|
|
\textbf{Attention} si votre source est monophonique, comme |
|
le microphone USB \textsc{Snowball} utilisé dans cet exemple, |
|
il NE faut PAS mettre \textsl{downmix} à 1\dots |
|
|
|
Et si vous souhaitez dupliquer une entrée à un seul canal |
|
(genre un micro usb) por obtenir une sortie stéréo, ça ne |
|
semble pas possible fin 2020\index{2020}. Il serait temps |
|
de songer à écrire un patch\index{patch}. |
|
|
|
%------------------------------------------------------------- |
|
|
|
\subsection{Ezstream} |
|
|
|
\begin{quote} |
|
Ezstream is an audio and video streaming client which feeds any |
|
icecast server with audio data and metadata from a standard input |
|
without reencoding. It thus requires very little CPU resources. Some |
|
playlists can be looped and composed with MP3, Ogg Vorbis or Ogg |
|
Theora media files. |
|
\end{quote} |
|
|
|
%------------------------------------------------------------- |
|
|
|
\subsection{darkice} |
|
\index{darkice} |
|
|
|
\begin{quote} |
|
DarkIce as a live audio streamer. It records audio from an audio |
|
interface (e.g. sound card), encodes it and sends it to a streaming server. |
|
\end{quote} |
|
%------------------------------------------------------------- |
|
\subsection{VLC} |
|
\index{vlc} |
|
|
|
VLC est le « cône de chantier » du multimédia. |
|
|
|
%------------------------------------------------------------- |
|
\subsection{butt} |
|
\index{butt} |
|
|
|
Du clickaconvi qui plante en X remote ;( mais sinon une |
|
interface graphique simple et facile d'emploi. |
|
|
|
%------------------------------------------------------------- |
|
|
|
\subsection{idjc} |
|
\index{idjc} |
|
|
|
\begin{quote} |
|
Internet DJ Console is an Internet radio application for making a |
|
live radio show or podcast. Features include two main media players |
|
with a crossfader, a jingle player, microphone signal processing |
|
(compressor and noise gate) |
|
\end{quote} |
|
|
|
%------------------------------------------------------------- |
|
\subsection{Android} \index{Android} |
|
|
|
Cool Mic \texttt{https://coolmic.net/} ? |
|
|
|
Mais il faut avoir quelques connaissances en \textsc{modernophone} |
|
pour arriver à tenter de comprendre pouquoi ça ne fonctionne pas, |
|
alors que tout semble correct. |
|
|
|
|
|
%==================================================================== |
|
\section{Gadgets} |
|
|
|
On peut aussi imaginer des \textsl{client sources} plus ésotériques. |
|
L'exemple classique étant l'utilisation de la synthèse vocale pour |
|
faire une horloge parlante. Mais comme tout vieux linuxien, j'attache |
|
un intérêt tout particulier à une valeur symbolique~: |
|
l'uptime de ma machine. |
|
En ces temps troublés\footnote{Début janvier 2021, le collectif |
|
d'artistes Mixart-Myrys, dont je fais partie depuis dix ans, |
|
est en train de se faire salement éjecter de son hangartistique. |
|
À cette occasion, j'ai remonté \textit{à la rache} un Icecast, |
|
et je l'ai voulu un peu surprent, d'où l'uptime parlé.}, |
|
l'uptime, c'est important. |
|
|
|
|
|
\lstinputlisting{code/say-uptime.sh} |
|
|
|
L'option \texttt{-p} de la commande \texttt{uptime} permet d'obtenir |
|
une sortie de cette forme : \textsf{up 1 day, 1 hour, 37 minutes} |
|
qu'une micromagie \texttt{sed} change en une forme plus correcte |
|
syntaxiquement, bien qu'anglo-saxonne. |
|
|
|
La ligne suivante sert uniquement d'affichage de contrôle, et peut |
|
être supprimée sans vergogne. |
|
|
|
\label{say-uptime} |
|
Les trois lignes suivantes vont effectivement généré le son qui sera |
|
envoyé vers la radio\index{radio} de l'Internet. |
|
|
|
Premier élémént du pipeline, \texttt{espeak-ng} reçoit le texte |
|
par son \textsl{stdin} et génère le flux de |
|
parole sur son \textsl{stdout}, à partir des options |
|
\texttt{-g 9 -s 150 -a 133}, réglant la voix synthétique. |
|
Ensuite, il faut que les échantillons sonores soient au format |
|
physique attendu par le diffuseur, |
|
d'où la conversion en 2$x$16 bits. Et pour finir, il est |
|
encodé/encapsulé dans du OggVorbis\index{ogg} que le |
|
\textsl{yuser} final ne pourra peut-être pas écouter sur |
|
son \textsf{iPhone}. |
|
|
|
Quand à la dernière ligne \texttt{~/bin/sender} c'est un programme, |
|
basé sur \texttt{libshout}, qui va gérer l'authentification et |
|
le transfert des données vers un point d'entrée du serveur icecast. |
|
|
|
Voilà, c'est tout pour le moment. |
|
|
|
%==================================================================== |
|
|
|
|
|
\section{libshout}\index{libshout}\label{libshout} |
|
|
|
Libshout c'est quoi ? Ah, chers amis de la radio en ligne, |
|
c'est une porte |
|
ouverte facilitant l'accès en direction du monde sonore extérieur, |
|
comme le précise clairement sa documentation~: |
|
|
|
\begin{quote} |
|
Libshout is a library for communicating with and sending data to an |
|
icecast server. It handles the socket connection, the timing of the |
|
data, and prevents bad data from getting to the icecast server. |
|
\end{quote} |
|
|
|
\lstinputlisting[language=c]{code/microcast.c} |
|
|
|
|
|
|
|
%==================================================================== |
|
|
|
%------------------------------------------------------------- |
|
|
|
|