Récemment j'ai été amené à faire un petit service de streaming et de VoD, je me suis donc aventuré dans ce petit monde. Je vais essayer via ce blog post de montrer quelques petites technologies et techniques permettant de monter simplement un petit service de ce style. Il s'agit d'une introduction, à vous par lasuite d'aller plus loin :).
Le but :
. Faire un streaming continu type WebTV mais avec des contenus connu à l'avance (playlist)
. Faire de la VoD
. Niveau technos : pour le "live" : un flux rtmp, un HLS. Pour la VoD : player HTML5(mp4, webm), flux rtmp.
Pré-requis :
- Aucun, enfin si un système GNU/Linux.
Premier temps :
- Il vous faut nginx-rtmp-module : https://github.com/arut/nginx-rtmp-module/
- Et ffmpeg, bien que certaines distributions proposent des paquets ffmpeg (ou avconv sous Debian) je vous conseille tout de même l'installation via les sources afin d'être up-to-date et d'avoir toutes les options disponibles : https://www.ffmpeg.org/
Maintenant préparons nos vidéos :
- On prend en entrée des vidéos .mp4
- On veut y rajouter un petit logo : logo.png en haut à droite
Déjà nous voulons mettre nos vidéos au format webm ... voici donc la commande :
ffmpeg -i video.mp4 -vf "movie=logo.png [logo]; [in][logo] overlay=main_w-overlay_w-10:10 [out]" -c:v libvpx -crf 10 -b:v 1M -c:a libvorbis fazo-vibes.webm
Explications :
- -i : spécifie le fichier en entrée (mais ça peut être un flux, on le verra plus tard);
- -vf : permet de filtrer les frames vidéos (dans notre cas pour y ajouter notre logo), -vf est utilisé pour des cas simples à savoir un input et un output;
- - overlay : permet d'insérer une vidéo, ou une image, sur notre vidéo et définit sa position (je vous laisse lire la bonne doc ffmpeg sur le sujet : https://ffmpeg.org/ffmpeg-filters.html#overlay-1);
- -c:v : codec video, en l'occurence libvpx pour du webm : http://www.webmproject.org/code/;
- -c:a : codec audio;
- Ensuite le video output (ou le flux si on le désire).
Ensuite on veut aussi s'assurer que notre fichier mp4 est bien conforme afin de pouvoir être lu par un player HTML5 au besoin donc, et on veut ajouter notre petit logo aussi :) :
ffmpeg -i video.mp4 -vf "movie=logo.png [logo]; [in][logo] overlay=main_w-overlay_w-10:10 [out]" -c:v libvpx -crf 10 -b:v 1M -c:a libvorbis fazo-vibes.webm
Flux RTMP :
Nous allons maintenant nous occuper de nos flux RTMP. Faisons d'abord la "VoD" (vous comprendrez pourquoi je commence par là ;)). Donc regardons notre fichier de configuration nginx.conf :
Si elle n'exite pas déjà créons une section rtmp :
rtmp {
server {
listen 1935;
ping 30s;
notify_method get;
}
}
Ajoutons-y de quoi faire notre VoD :
rtmp {
server {
listen 1935;
ping 30s;
notify_method get;
application mavod {
play /repertoire/des/videos/mp4;
}
}}
Je vous conseille d'ailleurs de mettre ce répertoire vidéo accessible à votre serveur http cela permettra de les utiliser pour le player HTML5 un peu plus tard.
Maintenant imaginons que vous voulez lire la vidéo mesdernieresvacances.mp4 qui se trouve dans /repertoire/des/videos/mp4 ... vous n'aurez qu'à consulter le flux : rtmp://ip/mavod/mesdernieresvacances.mp4
;)
Passons maintenant au "live-stream" :
D'abord configurons nginx ... tout comme pour la VoD il nous faut rajouter une "application" :
application mawebtv {
live on;
}
Attention il s'agit d'une configuration de PoC : je vous conseille par la suite pour éviter que n'importe qui ne stream via votre serveur de vous intéresser aux directives on_play et on_publish !
Imaginons maintenant que je désire faire tourner en boucle video1.mp4, video2.mp4 et video3.mp4 sur ce feed. Faisons un petit script bash :
while :
do
ffmpeg -f flv -i rtmp://127.0.0.1/mavod/video1.mp4 -c:v libx264 -b:v 5M -pix_fmt yuv420p -c:a:0 libfdk_aac -b:a:0 480k -f flv rtmp://127.0.0.1/mawebtv/live
ffmpeg -f flv -i rtmp://127.0.0.1/mavod/video2.mp4 -c:v libx264 -b:v 5M -pix_fmt yuv420p -c:a:0 libfdk_aac -b:a:0 480k -f flv rtmp://127.0.0.1/mawebtv/live
ffmpeg -f flv -i rtmp://127.0.0.1/mavod/video3.mp4 -c:v libx264 -b:v 5M -pix_fmt yuv420p -c:a:0 libfdk_aac -b:a:0 480k -f flv rtmp://127.0.0.1/mawebtv/live
done
Voilà ;) ... vous avez remarqué, j'ai changé certains codecs, dans ce cas ce n'était pas réellement nécessaire mais vous verrez que pour HLS ces changements le sont ! (par exemple de codec AAC pour le son, car HLS n'est pas compatible avec mp3 !).
Flux HLS :
Préparation de nginx :
HLS est un stream HTTP il faut donc préparer notre serveur HTTP, donc dans nginx.conf :
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias /tmp;
}
}
Et ensuite dans la section rtmp :
application hls {
live on;
hls on;
hls_path /tmp/hls;
hls_nested on;
}
Maintenant pour streamer, la même technique que pour le live rtmp mais en output : rtmp://127.0.0.1/hls/live
Vous pouvez ensuite accéder au flux via : http://ip/hls/hls/live/index.m3u8 !!!
Lecteur web :
Full HTML5, c'est assez simple : pour chaque vidéo :
<video id="our-video" width="600" height="400" controls>
<source src="repvidmp4/video.mp4" type="video/mp4">
<source src="repvidwebm/video.webm" type="video/webm">
Votre navigateur ne gère pas l'élément <code>video</code>.
</video>
Attention pour que cela marche sous Firefox pensez à renseigner les MIME type dans un .htaccess ;)
Pour lire des flux RTMP je vous conseille de jeter un oeil à video.js : http://www.videojs.com/
Aller plus loin :
Voilà vous avez la base, mais certaines choses montrés ici sont "sales" et il y a de nombreuses choses à faire avec ffmpeg, ffserver, ffplay et nginx (fonction push et pull par exemple :)). Vous pouvez aussi jeter un oeil à GStreamer et à ffserver !
En gros je vous laisse vous amuser un peu ;)
Have Fun !