Transformer une Raspberry Pi 2 ou 3 en système de diffusion de la voix sur un Wifi privé (création du point d'accès)

Motivations

Lors de FormaTerre2016 le programme de la formation incluait une visite géologique de Lyon. Avec plus de 50 partcipants il était nécessaire de mettre en place un dispositif de diffusion de la voix de l'accompagnateur de l'excursion dans l'environnement proche des arrêts. Comme depuis plusieurs mois l'équipe ACCES travaille sur l'utilisation des nano-ordinateurs RaspBerry Pi et que durant cette formation une expérimentation de BYOD (Bring Your Own Device) était prévue, l'idée a germé d'utiliser une raspberry Pi comme dispositif de multicast de proximité vers les smartphones des participants. Avant d'aborder le problème de la diffusion de la voix il est nécessaire de transformer la Raspberry Pi en point d'accès mobile qui se déplacera dans la poche de l'accompagnateur pendant toute l'excursion.

La maturation du projet fut difficile mais aboutit au résultat qui est présenté ici. Une Raspberry Pi a été configurée avec des logiciels libres, comme précisé ci-dessous, elle a fonctionné sans interruption pendant plus de 4 heures et diffusé sur le réseau wifi qu'elle avait créé et maintenu la voix de Pierre Thomas Professeur de Géologie à l'ENS de Lyon qui assurait la direction de l'excursion. Le réseau Wifi se déplaçait avec le porteur de la Raspberry; les participants écoutaient les présentations sur leur smartphone via l'application "vlc". Le son a été enregistré et un extrait concernant les colonnes de la basilique d'Ainay, l'Aber Ildu, l'obélisque de la concorde et les carrières d'Assouan est proposé ici.


Sommaire

  1. Mise en place du hotspot

    1. Téléchargements des paquets
    2. Configuration des outils
    3. Démarrage du réseau
  2. Configuration pour que le point d'accès fonctionne au démarrage

  3. Configuration de la translation d'adresse pour se connecter à internet via une autre interface

  4. Mise en place du webcast en réseau privé

    1. Encodage de la voix de l'orateur
    2. Diffusion de la voix de l'orateur
    3. Réception du flux audio avec un smartphone
    4. Avantages et limites du dispositif
  5. Remettre le dispositif en "configuration standard"

  6. Se Connecter avec screen de puis une tablette

Téléchargements


1. Mise en place du hotspot

1.1 Examen du matériel disponible

La création d'un hotspot Wifi n'est pas une opération fondamentalement compliquée mais elle est délicate et requiert un peu de méthode. Avant de commencer le premier point est de vérifier que tous les logiicels nécessaires sont effectivement installés sur la raspberryPi. On a besoin de iproute2, iw, udhcpd, hostapd, dkms, dnsmasq, bc, build-essential, dkms, on utilise la commande dpkg -l et s'il en manque les installer avec apt install :

sudo apt install dnsmasq bc build-essential dkms

sudo dpkg -l iproute2 iw udhcpd hostapd bc build-essential dkms
Souhait=inconnU/Installé/suppRimé/Purgé/H=à garder
| État=Non/Installé/fichier-Config/dépaqUeté/échec-conFig/H=semi-installé/W=attend-traitement-déclenchements
|/ Err?=(aucune)/besoin Réinstallation (État,Err: majuscule=mauvais)
||/ Nom            Version                             Architecture Description
+++-==============-===================================-============-=========================================================
ii  bc              1.07.1-2+b2   armhf        GNU bc arbitrary precision calculator language
ii  build-essential 12.9          armhf        Informational list of build-essential packages
ii  dkms            2.8.4-3       all          Dynamic Kernel Module Support Framework
ii  hostapd         2:2.9.0-21    armhf        access point and authentication server for Wi-Fi and Ethernet
ii  iproute2        5.10.0-4      armhf        networking and traffic control tools
ii  iw              5.9-3         armhf        tool for configuring Linux wireless devices
ii  udhcpd          1:1.30.1-6+b2 armhf        Provides the busybox DHCP server implementation

Pour observer la configuration ip token fournit le nom des interfaces du réseau ;

ip token
token :: dev enx############
token :: dev wlx############
token :: dev wlan1

Or la raspberryPi que nous utilisons dispose de deux interfaces wifi en plus de l'interface filaire et de l'interface Wifi de base. Lorsque l'interface réseau n'est pas présente alors que l'on sait que le dispositif physique existe, on teste s'il est vu sur le bus concerné, ici USB.

lsusb
Bus 001 Device 004: ID 0bda:8179 Realtek Semiconductor Corp. RTL8188EUS 802.11n Wireless Network Adapter
Bus 001 Device 005: ID 0bda:b812 Realtek Semiconductor Corp. RTL88x2bu [AC1200 Techkey]
Bus 001 Device 006: ID 0424:7800 Microchip Technology, Inc. (formerly SMSC) 
Bus 001 Device 003: ID 0424:2514 Microchip Technology, Inc. (formerly SMSC) USB 2.0 Hub
Bus 001 Device 002: ID 0424:2514 Microchip Technology, Inc. (formerly SMSC) USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Le dispositif connecté sur le bus 001:005 AC1200 Techkey ne dispose pas de son driver rtl88x2BU il faut l'installer. La méthode pour installer le driver puis le point d'accès est détaillée sur le github de cilynx. Le dispositif connecté sur le bus 001:004 TL-WN725Nne dispose pas de son driver RTL8188EUS il faut l'installer depuis par exemple le github de aircrack-ng. Malheureusement cette procédure ne fonctionne pas sur toutes les raspberries testées, un problème apparait lorsque la version du noyau n'est pas la version indiquées par le système d'exploitation pour les linux-headers disponibles. cette anomalie vient de ce que : * le noyau linux installé dans la raspberry coontient des binaires en format x86_64 qui est celui de l'hôte qui a servi a créer l'image * la version du noyau installé n'est pas celle proposée par les paquets debian

La solution trouvée est de télécharger et recompiler le noyau de la raspi dans les sources, la compilation des modules se fait alors sans problème.

sudo su
cd /usr/src
git clone -b rpi-#.#.y --single-branch https://github.com/raspberrypi/linux.git
cd linux
make
cd 
mkdir -p Logiciels/Network
cd !$
#
git clone https://github.com/cilynx/rtl88x2bu
cd ~/Logiciels/Network/rtl88x2bu
sed -i 's/I386_PC = y/I386_PC = n/' Makefile
sed -i 's/ARM_RPI = n/ARM_RPI = y/' Makefile
VER=$(sed -n 's/\PACKAGE_VERSION="\(.*\)"/\1/p' dkms.conf)
sudo rsync -rvhP ./ /usr/src/rtl88x2bu-${VER}
sudo dkms add -m rtl88x2bu -v ${VER}
sudo dkms build -m rtl88x2bu -v ${VER}
sudo dkms install -m rtl88x2bu -v ${VER}
sudo modprobe 88x2bu
#
git clone https://github.com/aircrack-ng/rtl8188eus.git
cd ~/Logiciels/Network/rtl8188eus
sed -i 's/I386_PC = y/I386_PC = n/' Makefile
sed -i 's/ARM_RPI = n/ARM_RPI = y/' Makefile
VER=$(sed -n 's/\PACKAGE_VERSION="\(.*\)"/\1/p' dkms.conf)
sudo rsync -rvhP ./ /usr/src/rtl8188eus-${VER}
sudo dkms add -m rtl8188eus -v ${VER}
sudo dkms build -m rtl8188eus -v ${VER}
sudo dkms install -m rtl8188eus -v ${VER}
sudo modprobe 8188eu

Avec un adaptateur dont le driver existe dans les paquets debian on a l'interface wlan0 d'origine et la nouvelle interface fournie par l'adaptateur wifi:

ip token
token :: dev enxb827########
token :: dev wlxd037########
token :: dev wlan1
token :: dev wlx1cbf########

iw dev la configuration des interfaces wifi et leur désignation qui sera utilisée plus tard.

sudo iw dev
phy#1
        Interface wlx1cbfcec7e37a
                ifindex 5
                wdev 0x100000001
                addr ##:##:##:##:##:##
                type managed
                txpower 12.00 dBm
phy#0
        Interface wlan1
                ifindex 4
                wdev 0x1
                addr ##:##:##:##:##:##
                type managed
                channel 34 (5170 MHz), width: 20 MHz, center1: 5170 MHz
ens-ife@raspife3P:~$ 

1.1 Téléchargements des paquets

Deux paquets supplémentaires à l'installation de base sont nécessaires. Une fois installés il peuvent rester en place cette manipulation est donc à effectuer une fois seulement.

sudo apt-get install udhcpd hostapd

Ces outils sont légers et ont été choisis parce que la fonction attendue ne devrait pas être trop lourde, s'il s'avère que les outils proposés ne tiennent pas la charge ou ne satisfont pas la demande l'un des sites en référence propose une autre solution plus lourde. Si votre application le requiert vous pourrez utiliser les logiciels proposés ci-dessous.

If you want something a little more 'heavyweight', you can use the isc-dhcp-server and bind9 packages for DHCP and DNS respectively, but for our purposes, dnsmasq works just fine.

Pour que ce protocole fonctionne il est nécessaire que la carte WIFI ne soit pas activée en mode "managed" et qu'elle dispose de la capacité AP (Access point); pour le savoir utiliser la commandes suivante :

  • On utilise les identifiants obtenus ci-dessus, la valeur du paramètre -A indique le nombre de lignes affichées, il a été ajusté ici à postériori au nombre d'interfaces et de chiffrements effectivement disponibles, (mette une valeur suffisante pour ne pas rater une interface)
sudo iw phy phy0 info| grep "Supported interface modes" -A 6
    Supported interface modes:
         * IBSS
         * managed
         * AP
         * P2P-client
         * P2P-GO
         * P2P-device

sudo iw phy phy0 info| grep "Supported Ciphers" -A 5
        Supported Ciphers:
                * WEP40 (00-0f-ac:1)
                * WEP104 (00-0f-ac:5)
                * TKIP (00-0f-ac:2)
                * CCMP-128 (00-0f-ac:4)
                * CMAC (00-0f-ac:6)

sudo iw phy phy1 info| grep "Supported interface modes" -A 5
        Supported interface modes:
                 * IBSS
                 * managed
                 * AP
                 * P2P-client
                 * P2P-GO

sudo iw phy phy1 info| grep "Supported Ciphers" -A 4
        Supported Ciphers:
                * WEP40 (00-0f-ac:1)
                * WEP104 (00-0f-ac:5)
                * TKIP (00-0f-ac:2)
                * CCMP-128 (00-0f-ac:4)

La carte AC1200 Techkey propose la possibilité de créer un point d'accès, tout comme la carte interne de la raspi P3P

La seconde carte TP-Link TL-WN823N ne propose pas la possibilité de créer un point d'accès, contrairement à la carte préinstallée sur la Raspberry Pi 3.

1.2 Configuration des outils

Comme d'habitude dans l'univers linux de nombreux choix sont possibles pour faire fonctionner les outils installés afin de répondre à un maximum d'usages que pourrait demander un usager; il est nécessaire de choisir des paramètres dans les fichiers de configuration. Comme d'habitude dans cette série de blogs une configuration qui a été testée est proposée mais elle n'est pas la seule possible et satisfait le besoin que nous avions, si le votre diffère lisez la doc des deux outils et faites les modifications qui vous conviennent.

Configuration d'udhcpd

/etc/udhcpd.conf

Le fichier udhcpd.conf est le fichier de configuration de udhcpd et il se trouve dans le répertoire des fichiers de configuration /etc . Afin de pouvoir revenir à postériori à la situation initiale faire une copie du fichier de configuration :

sudo cp /etc/udhcpd.conf /etc/udhcpd-std.conf
sudo jed /etc/udhcpd.conf

Le contenu du fichier de configuration testé est le suivant :

start 192.168.11.2 
end 192.168.11.254

interface  wlx1cbfcec7e37a

remaining yes

opt dns 192.168.11.1 192.168.10.1 9.9.9.9
opt subnet 255.255.255.0
opt router 192.168.11.1 

opt lease 864000 

Il est possible de fournir dans ce fichier des ip statiques sous la forme :

# Static leases map
#static_lease 00:60:08:11:CE:4E 192.168.0.54         
#static_lease 00:60:08:11:CE:3E 192.168.0.44

Le nom du device (de la carte WIFI) a été obtenu avec la commande ip address. Bien vérifier que la carte que vous souhaitez utiliser n'est pas en mode "managed" c'est à dire déjà connectée à un réseau WIFI

ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enxb827eb1a17bc: <BROADCAST,MULTICAST,DYNAMIC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether b8:27:eb:1a:17:bc brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.73/24 brd 192.168.10.255 scope global enxb827eb1a17bc
       valid_lft forever preferred_lft forever
    inet6 fe80::ba27:ebff:fe1a:17bc/64 scope link 
       valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    link/ether b8:27:eb:4f:42:e9 brd ff:ff:ff:ff:ff:ff
4: wlx1cbfcec7e37a: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 1c:bf:ce:c7:e3:7a brd ff:ff:ff:ff:ff:ff

/etc/default/udhcpd

Le fichier de configuration /etc/default/udhcpd permet de choisir le type de fonctionnement de l'outil udhcpd. Nous allons activer la fonction DHCP de la raspberry Pi.

sudo jed /etc/default/udhcpd

Le contenu testé est copié ci-dessous.

 # Comment the following line to enable
 # DHCPD_ENABLED="no"

 # Options to pass to busybox' udhcpd.
 #
 # -S    Log to syslog
 # -f    run in foreground

Nous avons vu plus haut que nous avons prévu de conserver des traces des connexions leases s'il n'existe pas encore il est nécessaire de créer le fichier qui contiendra ces traces.

sudo touch /var/lib/misc/udhcpd.leases

Il est maintenant temps d'attribuer l'IP fixe qui a été choisie dans le fichier de configuration plus haut, on ajoute l'IP avec la commande ip

sudo ip addr add 192.168.11.1/24 dev wlx1cbfcec7e37a

Le serveur d'adresses udhcpd est configuré mais il n'est pas encore actif, il sera lancé plus tard quand le point d'accès sera terminé.

Configuration d'hostapd

hostapd.conf

Le fichier hostapd.conf sert à configurer l'outil qui transforme la carte WIFI en un point d'accès, lors de l'installation du paquet un exemple a été ajouté dans /usr/share/doc/hostapd/examples on recopie cet exemple dans le dossier /etc/hostapd.

sudo cp /usr/share/doc/hostapd/examples/hostapd.conf /etc/hostapd/hostapd.conf
sudo jed /etc/hostapd/hostapd.conf

Les modifications de la configuration testées sont proposées ci-dessous. Le fichier de configuration est long et complexe, les choix proposés ci-dessous sont minimalistes mais suffisants, ils profitent de la configuration par défaut pas nécessairement parfaitement adaptée à la carte connectée, pour de meilleures performances il est souhaitable d'affiner ces choix.

##### hostapd configuration file ##############################################                                                         #      
interface=wlan0                                                                                                                         
driver=nl80211                                                                                                                          
logger_syslog=-1
logger_syslog_level=0
logger_stdout=-1
logger_stdout_level=0
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
ssid=test
hw_mode=g
channel=6
beacon_int=100
dtim_period=2
max_num_sta=255
rts_threshold=-1
fragm_threshold=-1
macaddr_acl=0
auth_algs=3
ignore_broadcast_ssid=0
wmm_enabled=1
# Low priority / AC_BK = background
wmm_ac_bk_cwmin=4
wmm_ac_bk_cwmax=10
wmm_ac_bk_aifs=7
wmm_ac_bk_txop_limit=0
wmm_ac_bk_acm=0
# Note: for IEEE 802.11b mode: cWmin=5 cWmax=10
#
# Normal priority / AC_BE = best effort
wmm_ac_be_aifs=3
wmm_ac_be_cwmin=4
wmm_ac_be_cwmax=10
wmm_ac_be_txop_limit=0
wmm_ac_be_acm=0
# Note: for IEEE 802.11b mode: cWmin=5 cWmax=7
#
# High priority / AC_VI = video
wmm_ac_vi_aifs=2
wmm_ac_vi_cwmin=3
wmm_ac_vi_cwmax=4
wmm_ac_vi_txop_limit=94
wmm_ac_vi_acm=0
# Note: for IEEE 802.11b mode: cWmin=4 cWmax=5 txop_limit=188
#
# Highest priority / AC_VO = voice
wmm_ac_vo_aifs=2
wmm_ac_vo_cwmin=2
wmm_ac_vo_cwmax=3
wmm_ac_vo_txop_limit=47
wmm_ac_vo_acm=0
# Note: for IEEE 802.11b mode: cWmin=3 cWmax=4 burst=102
ieee80211n=1
eapol_key_index_workaround=0
own_ip_addr=127.0.0.1
wpa=2
wpa_passphrase=LilooTest
wpa_psk_radius=0
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP

# ...

/etc/default/hostapd

le fichier /etc/default/hostapd permet de choisir le fonctionnement par défaut du point d'accès via le fichier de configuration ci-dessus.

sudo  jed  /etc/default/hostapd

Le contenu du fichier testé est recopié ci-dessous.

 # Defaults for hostapd initscript
 #
 # See /usr/share/doc/hostapd/README.Debian for information about alternative
 # methods of managing hostapd.
 #
 # Uncomment and set DAEMON_CONF to the absolute path of a hostapd configuration
 # file and hostapd will be started during system boot. An example configuration
 # file can be found at /usr/share/doc/hostapd/examples/hostapd.conf.gz
 #
 DAEMON_CONF="/etc/hostapd/hostapd.conf"

 # Additional daemon options to be appended to hostapd command:-
 #  -d   show more debug messages (-dd for even more)
 #  -K   include key data in debug messages
 #  -t   include timestamps in some debug messages
 #
 # Note that -B (daemon mode) and -P (pidfile) options are automatically
 # configured by the init.d script and must not be added to DAEMON_OPTS.
 #
 #DAEMON_OPTS=""

Le point d'accès est maintenant totalement configuré il reste à le démarrer.

1.3 Démarrage du réseau

Vérifier que les interfaces ne sont pas bloquées avec rfkill :

sudo  rfkill list
0: phy0: Wireless LAN
        Soft blocked: yes
        Hard blocked: no
1: phy1: Wireless LAN
        Soft blocked: yes
        Hard blocked: no

Ici l'interface phy1 (wlx1cbfcec7e37a) est bloquée, il faut la débloquer avec la commande sudo rfkill unblock 1.

La façon la plus robuste de faire démarrer le réseau est de lancer un service qui porte chacun des outils avec les commandes suivantes :

sudo systemctl start udhcpd
sudo systemctl start hostapd 

Il peut-être nécessaired'arrêter udhcpd avant de le relancer sudo sudo restart udhcpd, le service hostapd peut-être masqué, dans ce cas utiliser la commande sudo systemctl unmask hostapd.service

Il suffit maintenant d'allumer un autre ordinateur, ce dernier devrait trouver le WIFI FormaTerre2016 et obtenir une adresse sur ce réseau avec le mot de passe proposé dans le fichier de configuration.

2 Configuration pour que le point d'accès fonctionne au démarrage

Le travail qui vient d'être effectué a laissé des fichiers de configuration opérationnels qui existeront encore au démarrage mais l'attribution de l'IP fixe ainsi que les deux services ont été faits "à la main" sans fichier de configuration. Pour que le point d'accès soit configuré au démarrage de la Raspberry il faut ajouter un fichier de configuration et veiller à ce que les services soient activés au démarrage.

Depuis Jessie debian est passé de lanceurs systemV à des lanceurs systemD cela a donné lieu à une grosse querelle entre les développeurs, il reste encore quelques soubressauts de ce combat et le nouvel outil est moins abouti que le précédent mais évolue vite.... Les tutoriels suivant le nouveau mode d'emploi sont rares et ce qui est présenté ici n'est pas garanti mais... fonctionne!

Le réseau est configuré à l'intérieur du répertoire /etc/systemd/network pout toute nouvelle interface réseau il est nécessaire d'ajouter un fichier, de nombreux paramètres sont possibles, voici une proposition qui fonctionne mais qui n'est peut-être pas idéale.

cd /etc/systemd/network
sudo jed /etc/systemd/network/60-wirelessAP.network

Le nom qui a été choisi est arbitraire, le contenu du fichier a été copié ci-dessous.

[Match]
Name=wlp2s0

[Network]
Address=192.168.11.1/24
Gateway=192.168.11.1
#DNS=192.168.11.1

Pour vérifierque la carte sera bien configurée au démarrage lancer la commande sudo systemctl restart systemd-networkd et vérifier avec ip address showque le numéro IP de l'interface a été conservé (ou renouvelé à l'identique).

Il existe donc maintenant un réseau wifi privé accessible à proximité de la raspberry Pi. Tous les smartphones peuvent se connecter à ce réseau et être à l'écoute de ce qui y est diffusé.

3 Configuration de la translation d'adresse pour se connecter à internet via une autre interface

Il est nécessaire de configurer le noyau pour que la translation d'adresse soit assurée, pour cela archiver le fichier /etc/sysctl.conf puis l'éditer pour activer la translation d'adresse en décommantant la ligne net.ipv4.ip_forward=1 ; archiver ensuite le fichier en cas de réutilisation.

sudo cp /etc/sysctl.conf /etc/sysctl.conf.std
sudo jed /etc/sysctl.conf
sudo cp /etc/sysctl.conf /etc/sysctl.conf.nat

Pour que la translation soit effective au démarrage conserver /etc/sysctl.conf.nat, pour redémarrer en conditions classiques recopier /etc/sysctl.conf.std.

Configurer ensuite les iptables afin que la translation soit effective

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i eth0 -o wlp2s0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i  wlp2s0 -o eth0 -j ACCEPT

Démarrer la translation:

sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"

Pour une réutilisation ultérieure on peut sauvegarder l'état des iptables permettant le reroutage avec la commande :

sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"

La configuration est sauvegardée dans le fichier /etc/iptables.ipv4.nat

4. Mise en place du webcast en réseau privé

Une fois le réseau mis en place il reste deux fonctions à mettre en place : * la captation et l'encodage de la voix du guide / orateur * la diffusion de la voix sur le réseau local qui vient d'être créé.

Le logiciel ffmpeg sera installé et utilisé pour réaliser ces deux fonctions, une version existe dans le dépôt debian par défaut mais certains programmes non libres en sont expurgés, pour en disposer il est nécessaire d'utiliser le dépôt alternatif de Marillat en ajoutant la ligne ci-jointe deb http://www.deb-multimedia.org/ stretch main non-free au fichier de dépôts /etc/apt/sources.list ou /etc/apt/sources.list.d/non-free.

4.1. Encodage de la voix de l'orateur

Le site ffmpeg, les tutoriaux et autres forums de la ffmpegosphère sont la meilleure source de renseignements et de conseils possibles. Nous présentons ici la procédure qui a fonctionné pour nous mais il n'est pas à exclure que pour des raisons de version logicielle ou de configuration elle ne fonctionne pas parfaitement dans votre univers dans ce cas reportez vous à la documentation https://ffmpeg.org/ffmpeg.html ou à l l'un des nombreux forums en ligne.

La Raspberry Pi ne dispose pas de prise jack d'entrée micro c'est pourquoi nous utilisons un convertisseur analogique digital qui se connecte sur l'un des ports USB de la Raspberry et propose un double connecteur mini-jack audioin/audio out.

Connecteur mini-jack audio  USB

On connecte alors le micro au dispositif (y compris le récepteur d'un micro HF si on le souhaite) et on vérifie que la ressource est présente :

vidal[~] 3littlehills.€ : arecord -l
**** Liste des Périphériques Matériels CAPTURE ****
carte 1: Set [C-Media USB Headphone Set], périphérique 0: USB Audio [USB Audio]
  Sous-périphériques: 1/1
  Sous-périphérique #0: subdevice #0

Dans ce cas on trouvera le micro via le périphérique alsa (arecord) sur la ressource 1 au niveau de la sous-ressource 0 et l'instruction ffmpeg prendra la forme :

ffmpeg -f alsa -ac 1 -i hw:1,0  -b:a 64k -vn

dont l'explication des paramètres est la suivante : * -f alsa utilisation du format alsa par défaut * -ac 1 enregistrement mono ou duplication d'un canal sur les deux pistes stéréo si le format de sortie le permet; l est possible d'enregistrer en stéréo deux sources on choisit alors -ac 2 * -i hw:1,0 la source d'entrée se trouve sur le périphérique 1 et le sous périphérique 0 (cf ci-dessus); * -b:a 64k l'enregistrement est effectué ici à 64 kbit/s pour éviter de surcharger la bande passante de diffusion et parce que cela fournit une qualité suffisante pour la voix; il est possible d'augmenter ce débit pour avoir une meilleure qualité aux déppens de la bande passante. * -vn précise que le flux encodé ne contient pas de vidéo.

La commande ci-dessus est incomplète et on doit impérativement préciser un flux de sortie. Ce flux peut être envoyé dans un fichier il suffit alors de préciser son nom et éventuellement d'autres paramètres d'encodage que le débit, le codec, la fréquence d'échantillonnage etc... Ffmpeg est toutefois un logiciel complexe pour lequel des valeurs par défaut robustes ont été fixées pour en faciliter l'utilisation et il suffit souvent d'ajouter une extension valide pour que ffmpeg choisisse pour vous des paramètres qui fonctionnent. Attention, le fait qu'ils fonctionnent ne certifie absolument pas qu'ils sont optimaux (ce serait même le contraire...car pour qu'ils fonctionnent en toutes circonstances ils sont très peu optimisés). Attention aussi aux extensions qui impliquent des contraintes, fabriquer un fichier .wav impliquera nécessairement un débit de 1500kbit/s, quel que soit la valeur que vous avez choisie à la main.

Dans notre cas nous avons besoin de créer un flux continu qui pourra être capturé et diffusé par le serveur, cela est réalisé en utilisant le format ffm et en indiquant l'adresse du serveur qui diffusera le flux en direct. La commande complète est donc :

ffmpeg -f alsa -ac 1 -i hw:1,0  -b:a 64k -vn -f ffm http://localhost:8090/feed1.ffm

Les options utilisées permettent : * de préciser le format utilisé -f ffm * de renvoyer le flux localement sur la Raspberry en choisissant le port 8090 et un flux nommé feed1.ffm

Pour respecter la logique nous venons de présenter comment encoder un flux et le proposer à un serveur mais d'un point de vue opérationnel il est impératif que le serveur soit opérationnel avant de lancer l'encodeur, ne tentez pas d'exécuter cette commande elle échouerait à coup sûr en vous gratifiant d'une avalanche de messages d'erreur. Le chapitre suivant présente la construction et la mise en route du serveur.

4.2. Diffusion de la voix de l'orateur

Dans le chapitre précédent nous avons vu comment créer un flux audio local sur la Raspberry avec ffmpeg, nous allons utiliser ffserver (contenu dans le paquet ffmpeg) pour créer le serveur qui capturera le flux et le diffusera sur le réseau wifi de la même machine.

L'outil ffserver utilise un fichier de configuration qui regroupe tous les paramètres nécessaires à la capture du flux entrant et à la diffusion d'un flux audio sur le réseau. Ce fichier peut s'avérer très complexe et nous ne décrirons pas ici toutes les possibilités offertes mais nous présenterons la solution simple qui a été mise en oeuvre pour l'excursion géologique de FormaTerre 2016 pilotée par Pierre Thomas.

Nous avons déjà vu que nous devons capturer un flux audio au format ffm disponible sur le port 8090, nous nous proposons de diffuser un flux mp3 avec le même débit et sur le même port afin de simplifier la configuration au maximum. Le fichier de configuration raspiffserv.conf est recopié ci-dessous (les commentaires du fichier d'origine ont été conservés commentés afin de documenter les choix effectués :

# Port on which the server is listening. You must select a different
# port from your standard HTTP web server if it is running on the same
# computer.
HTTPPort 8090

# Number of simultaneous HTTP connections that can be handled. It has
# to be defined *before* the MaxClients parameter, since it defines the
# MaxClients maximum limit.
MaxHTTPConnections 100

# Number of simultaneous requests that can be handled. Since FFServer
# is very fast, it is more likely that you will want to leave this high
# and use MaxBandwidth, below.
MaxClients 80

# This the maximum amount of kbit/sec that you are prepared to
# consume when streaming to clients.
MaxBandwidth 1000

# Access log file (uses standard Apache log file format)
# '-' is the standard output.
CustomLog -

##################################################################
# Definition of the live feeds. Each live feed contains one video
# and/or audio sequence coming from an ffmpeg encoder or another
# ffserver. This sequence may be encoded simultaneously with several
# codecs at several resolutions.

<Feed feed1.ffm>
# You must use 'ffmpeg' to send a live feed to ffserver. In this
# example, you can type:
#
# ffmpeg http://localhost:8090/feed1.ffm

# ffserver can also do time shifting. It means that it can stream any
# previously recorded live stream. The request should contain:
# "http://xxxx?date=[YYYY-MM-DDT][[HH:]MM:]SS[.m...]".You must specify
# a path where the feed is stored on disk. You also specify the
# maximum size of the feed, where zero means unlimited. Default:
# File=/tmp/feed_name.ffm FileMaxSize=5M
File /home/vidal/Streaming/feed1.ffm
FileMaxSize 200000K

# Only allow connections from localhost to the feed.
ACL allow 127.0.0.1
</Feed>

##################################################################
# Now you can define each stream which will be generated from the
# original audio and video stream. Each format has a filename (here
# 'test1.mpg'). FFServer will send this stream when answering a
# request containing this filename.

# MP3 audio

<Stream FT2016.mp3>
Feed feed1.ffm
Format mp2
AudioCodec libmp3lame
AudioBitRate 64
AudioChannels 1
AudioSampleRate 44100
NoVideo
</Stream>

##################################################################
# Special streams

# Server status

<Stream stat.html>
Format status

# Only allow local people to get the status
ACL allow localhost
ACL allow 192.168.11.0 192.168.11.255

#FaviconURL http://pond1.gladstonefamily.net:8080/favicon.ico
</Stream>

Outre le choix du port et du nom du flux il est crucial d'utiliser les adresses réseau définies pour le serveur DHCP dans la première partie de cet article 192.168.11.0/24.

Une fois le fichier correctement rempli l'instruction de lancement du serveur est des plus simples :

ffserver -f raspiffserv.conf 
ffserver version 3.2 Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 6.2.0 (Debian 6.2.0-9) 20161019
  configuration: --cc='ccache cc' --disable-decoder=amrnb --disable-decoder=libopenjpeg --disable-decoder=libschroedinger --disable-mips32r2 --disable-mips32r6 --disable-mips64r6 --disable-mipsdsp --disable-mipsdspr2 --disable-mipsfpu --disable-msa --disable-libopencv --disable-podpages --disable-stripping --enable-avfilter --enable-avresample --enable-gcrypt --enable-gnutls --enable-gpl --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libebur128 --enable-libfdk-aac --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libilbc --enable-libkvazaar --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librubberband --enable-libschroedinger --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libx265 --enable-libxvid --enable-libzvbi --enable-nonfree --enable-opengl --enable-openssl --enable-postproc --enable-pthreads --enable-shared --enable-version3 --incdir=/usr/include/arm-linux-gnueabihf --libdir=/usr/lib/arm-linux-gnueabihf --prefix=/usr --toolchain=hardened --enable-frei0r --enable-chromaprint --enable-libx264 --enable-libiec61883 --enable-libdc1394 --disable-altivec --shlibdir=/usr/lib/arm-linux-gnueabihf
  libavutil      55. 34.100 / 55. 34.100
  libavcodec     57. 64.100 / 57. 64.100
  libavformat    57. 56.100 / 57. 56.100
  libavdevice    57.  1.100 / 57.  1.100
  libavfilter     6. 65.100 /  6. 65.100
  libavresample   3.  1.  0 /  3.  1.  0
  libswscale      4.  2.100 /  4.  2.100
  libswresample   2.  3.100 /  2.  3.100
  libpostproc    54.  1.100 / 54.  1.100
Thu Nov 17 15:50:58 2016 FFserver started.
Thu Nov 17 15:51:32 2016 [ffm @ 0x563e9480]Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.
Thu Nov 17 15:51:32 2016 127.0.0.1 - - [GET] "/feed1.ffm HTTP/1.1" 200 20559
Thu Nov 17 15:51:52 2016 127.0.0.1 - - [POST] "/feed1.ffm HTTP/1.1" 200 184320

La trace ci-dessus montre un fonctionnement nominal avec connection d'un flux feed1.ffm entrant [GET] "/feed1.ffm HTTP/1.1" 200 20559 et déconnexion de ce flux après quelques dizaines de secondes [POST] "/feed1.ffm HTTP/1.1" 200 184320.

Pendant que le serveur est opérationnel et qu'il a pu capturer un flux entrant, le flux sortant FT2016.mp3 est disponible sur la Raspberry Pi à l'adresse 192.168.11.1 sur le port 8090, il ne reste plus qu'à le capturer et le restituer sur l'un des portables des membres de l'auditoire.

4.3. Réception du flux audio avec un smartphone

Il existe de nombreuses applications permettant de recevoir un flux audio sur un smartphone, mais comme cette présentation est en général proposée pas des services commerciaux la configuration de ces applications se fait souvent via le nom de la marque ou du service en ligne proposé. Il est nécessaire dans notre cas d'utiliser un outil neutre et ouvert qui accepte de lire un flux à partir de son adresse et pas de sa marque. L'application vlc fait parfaitement l'affaire et a démontré sa fiabilité lors de notre expérimentation.

Installer sur le smartphone l'application vlc, cette application est compatible avec la plupart des smartphones quelle que soit leur marque et leur taille toutefois nous avons observé que certains modèles ne parvenaient pas à récupérer le flux mp3 sans qu'il soit possible de trouver une explication. * Dans l'application vlc choisir Ouvrir MRL * dans le bloc prévu à cet effet taper l'adresse du flux sortant http://192.168.11.1:8090/ FT2016.mp3 * après quelques instants le flux est diffusé par le smartphone.

Ce dispositif a été expérimenté avec succès pendant la totalité de l'excursion soit environ 4 heures sans discontinuité ni interruption. La Raspberry était alimentée avec une batterie longue durée et le son capté ppar un micro HF. L'orateur portait seulement l'émetteur du micro HF, une autre personne portait le récepteur et la Raspberry, l'orateur et le porteur du récepteur ont été séparés ce qui a interrompu la diffusion mais dès qu'ils se sont rapprochés la diffussion a repris sans aucune intervention manuelle.

Extrait de l'excursion

Les colonnes de la basilique d'Ainay de Lyon, l'Aber Ildu et les Carrières d'Assouan... Pierre Thomas 2016.

4.4. Avantages et limites du dispositif

Du côté des avantages du dispositif on trouve un coût extrêmement faible, une robustesse et une fiablité tout à fait exceptionelles, l'encombrement et l'autonomie très confortables. Le dispositif permet en plus de la diffusion en direct de recueillir un enregistrement du son qui pourra être réutilisé aisément en différé. Même si la mise en oeuvre n'est pas complètement triviale, elle ne présente aucune difficulté particulière et ne requiert pas de connaissances avancées sur le son ou l'informatique.

Côté limites il existe une latence incompressible entre la parole de l'orateur et le son diffusé par les smartphones, le délai est court mais gênant si l'auditeur peut entendre la voix de l'orateur. Cet inconvénient disparait si les auditeurs peunt se répartir sur un espace à une certaine distance de l'orateur. Il a été constaté pendant l'excursion l'apparition de perturbation sonores dont il n'a pas été possible de déterminer si elles étaient le fait du wifi ou de la communication radio entre émetteur et récepteur du micro (ce qui est plus probable) il n'en reste pas moins que le dispositif est sensible à l'environnement et que si aucun problème n'apparaira en milieu ouvert le risque est important en milieu urbain.

5. Remettre le dispositif en "configuration standard"

Arrêt des services

La commande suivante permet de lister les services systemD qui sont actifs et l'état dans lequel ils se trouvent.

systemctl list-units -t service --all | grep net

sudo systemctl stop hostapd sudo systemctl stop udhcpd sudo jed /etc/default/udhcpd remettre dans la configuration initiale sudo jed /etc/default/hostapd remettre dans la configuration initiale sudo systemctl disable hostapd sudo systemctl disable udhcpd enlever sudo ip a del 192.168.11.1/24 dev wlp2s0

Suppressio du démarrage au boot s'il a été activé .

sudo systemctl disable  udhcpd 
sudo systemctl disable hostapd 

Suppression des fichier de configuration

Pour conserver la trace de ce qui a été effectué et facilement la remise en route du point d'accès sans perturber le fonctionnement ordinaire de la Raspberry pi, on va conserver tous les fichiers de configuration dans un répertoire il suffira alors de les recopier dans le répertoire souhaité par exemple ~/HotSpot. Les programmes installés peuvent être conservés tant que leur configuration ne leur permet pas de s'exécuter et de perturber le fonctionnement de base de la Raspberry Enlever le fichier du répertoire /etc/systemd/network/et le placer dans le répertoire Hotspotà la racine.

cd
mkdir HotSpot
cd HotSpot
cp /etc/udhcpd.conf .
sudo cp /etc/udhcpd-std.conf /etc/udhcpd.conf
cp /etc/default/udhcpd .
sudo jed /etc/default/udhcpd # uncomment DHCPD_ENABLED="no"
cp /etc/hostapd/hostapd.conf .
sudo cp /usr/share/doc/hostapd/examples/hostapd.conf /etc/hostapd/hostapd.conf
cp /etc/default/hostapd .
sudo jed /etc/default/hostapd # remove daemon conf file address
cp /etc/systemd/network/60-wirelessAP.network .
sudo rm /etc/systemd/network/60-wirelessAP.network
cp /etc/sysctl.conf .
sudo cp /etc/sysctl.conf.std /etc/sysctl.conf
sudo sh -c "echo 0 > /proc/sys/net/ipv4/ip_forward"
sudo iptables --flush

Lancement au boot de wicd

Si le point d'accès a été configuré pour être présent de façon permanente et que l'on souhaite retrouver un fonctionnement ordinaire du WIFI, réactiver wicd :

sudo systemctl enable wicd 

Rebooter la machine.

6 Se Connecter avec screen de puis une tablette

Les outils de connection en ssh depuis les tablettes ne permettent pas d'avoir plusieurs connections ouvertes en même temps la solution est de déployer screen sur la raspberry et interagir avec elle avec les commandes suivantes.

screen -a
cd Streaming
ffserver -f  raspiffserv.conf
C-a d
screen -a
ffmpeg -f alsa -ac 1 -i hw:1,0  -b:a 64k -vn -f ffm http://localhost:8090/feed1.ffm
C-a d
screen -list
There are screens on:
    14096.pts-1.3littlehills    (17/11/2016 13:08:39)   (Detached)
    14084.pts-1.3littlehills    (17/11/2016 13:06:18)   (Detached)
2 Sockets in /var/run/screen/S-vidal.

screen -r 14096.pts-1.3littlehills
C-a k
screen -list
There is a screen on:
    14084.pts-1.3littlehills    (17/11/2016 13:06:17)   (Detached)
1 Socket in /var/run/screen/S-vidal.

Commentaires