Ce projet, ralis lors du module proejt d'ESIR 2 a pour but de raliser un scheduling temporel de containers docker fonctionnant sur un cluster de RaspberryPi dans le but de raliser l'encodage de vidos.
Ce rpertoire contient :
Pour rsumer, ce projet est compos d'un cluster de raspberry pi qui font tourner une instance de glusterfs afin d'avoir un espace de fichier partag. Un des raspberrys (node1) fait tourner une interface web dans lequel l'utilisateur peut envoyer un fichier a encoder. Ce docker lance un processus (split/encode/merge) o les containers sont grs par DockerSwarm. Enfin, the-graph sert la visualisation des tats des containers.
Il suffit de flasher une image raspbian puis d'xcuter le script prepareRpi.sh qui mettera en place le hostname et dmarrera les containers ncessaires (glusterfs, dockerswarm, etc).
Sur le node 1, il suffit de faire tourner le docker fileuploader avec la commande suivante : docker run -it -p 3000:3000 --volume-driver=glusterfs --volume uploads:/uploads --name fileuploader fileuploader
Ce qui donnera pour interface :
Les fichers seront uploads dans le dossier uploads du glusterfs.
Le serveur est dvelopp avec nodejs (le code source se trouve dans /FileUploader). Lors de l'envoie d'un fichier, 2 fichiers sont ajouts sur le serveur. Un fichier de la forme toEncode_$DATE$ qui est le fichier upload et un .json contenant :
{
"toEncode":"toEncode_1464009095314",
"original_name":"$ORIGINALNAME$",
"wanted_name":"$WANTEDNAME$",
"bitrate":"$BITRATE$"
}
Pour comprendre comment ont t install l'ensemble des packages ncessaires pour cette partie, veuillez vous rfrer au Dockerfile correspondant chaque partie (Split, Encode, Merge).
Ce script permet de couper notre vido d'origine en un nombre de parties donn en paramtre de notre script.
Les deux paramtres de ce script sont :
Fonctionnement :
Dans un premier temps on rcupre les informations qui nous intresse dans le .json de notre vido (la valeur de toEndode pour obtenir le nom du fichier d'origine split qui sera donc rentr en paramtre de notre script et la valeur de wanted_name pour connatre le nom qu'aura chacun de nos splits, si cette valeur est absente on prend alors l'original_name par dfaut).
inputFile="$directory"$(grep -Po '(?<="toEncode":")[^"]*' "$directory""$1.json")
outputFile="$directory"$(grep -Po '(?<="wanted_name":")[^"]*' "$directory""$1.json")
outputFileName=$(echo $outputFile | cut -f1 -d '.')
Ensuite, on rcupre des informations sur la vido tel que sa dure mais galement toutes ses key_frames que l'on stocke dans un fichier texte ("$inputFile"_key_frame.txt). Pour effectuer cela, on a utilis la commande avprobe (installe sur les raspberry et provenant du package libav-tools).
avprobe -show_format_entry duration -v quiet "$inputFile"
avprobe -v quiet -show_packets -of json "$inputFile" | awk '$0 ~ /"pts_time" : "([0-9]|\.)*"/ {toPrint=$3} $0 ~ /"flags" : "K"/ {print toPrint} '
| grep -oE \([0-9]\|\\\.\)* > "$inputFile"_key_frame.txt
Une fois toutes ces informations obtenues, on peut alors procder au dcoupage de notre vido. Pour cela cette fois, nous avons utilis la commande avconv. Enfin si l'utilisateur entre en second paramtre un nombre souhait de split suprieur au nombre total de key_frames de notre vido, alors cette dernire sera dcoup en cette deuxime valeur (#key_frames).
avconv -y -i "$inputFile" -ss $startTime -t "$splitTime" -codec copy "$outputFileName"_part_"$fileCurrentNumber".mp4
Retour :
Ce script permet d'encoder nos splits de vido obtenus grce au script prcdent (scriptSplit).
Les deux paramtres de ce script sont :
Fonctionnement :
Nous rcuprons la valeur du bitrate sur le fichier json pass en paramtre. Si cette information n'est pas disponible, on donne comme valeur de bitrate celle de la vido d'origine obtenue via la commande avprobe. Avec cette valeur nous pouvons ensuite lanc notre commande d'encodage via cette fois la commande gst-launch-1.0 (package gstreamer1.0) o le bitrate est justement plac en otion de cette commande. Pour l'encodage, on se sert de omxh264enc qui est l'encodeur hardware prsent dans nos raspberrys.
gst-launch-1.0 -v filesrc location="$outputFileName"_part_"$2" ! decodebin ! videoconvert ! \
videoscale ! omxh264enc control-rate=1 \
target-bitrate="$bitRate" ! h264parse ! mp4mux ! \
filesink location="$outputFileName"_part_"$2"_encoded.mp4
Retour :
Ce script permet de faire fusionner nos splits de vido obtenus grce au script scriptSplit et aprs l'encodage de ces derniers (scriptEncode).
L'unique paramtre de ce script est :
Fonctionnement :
On rcupre premirement dans ce fichier JSON le nom qu'aura notre vido finale (wanted_name ou si absent original_name).
outputFile=$(grep -Po '(?<="wanted_name":")[^"]*' "$1.json")
Ensuite, nous procdons au merge via la commande ffmpeg (ici nous n'avons pas russi rutiliser avconv pour le merge, cela ne fonctionnait pas...). On met en paramtre de cette commande le fichier .part obtenu aprs le split de notre vido.
ffmpeg -y -f concat -i $1.part -c copy "$outputFile"
Retour :
Cette partie du projet sert raliser le scheduling temporel des containers.
Pour lancer un container sur le swarm : docker -H tcp://$IPADD:2375 run -d -P --name NAME IMAGE
Il est possible de faire en sorte qu'un container attende qu'un autre soit finit avec -e waitfor:container==NAME
. Ainsi par exemple docker -H tcp://$IPADD:2375 run -d -P -e waitfor:container==h1 --name h2 armhf/hello-world
va crer un container h2 qui attendra que le container h1 soit arrt.
Le code source est disponible dans le module du dossier /swarm, principalement dans le dossier swarm/cluster/state/. Lors de l'appel la mthode run, swarm vrifie si toutes les dpendances sont termines, sinon le container est rajout une liste de containers bloqus. chaque fois qu'un container termine, les dpendances sont vrifies. Si on peut lancer un container bloqu car toutes les dpendances sont rsolues, on le fait.
Get dependencies using Bower and Browserify (via npm and grunt):
bower install
npm install
grunt build
La librairie open-source the-graph est bas sur noflograph. Dans notre projet cette librairie nous permet d'afficher les images docker qui sont installs sur les diffrents Raspberry Pi. Il y a 3 types d'images affichs : 1 image split -> Cette image reli sur ses sorties aux diffrentes images encode. n images encode -> Ces images sont relis l'image split sur leur entre et l'image merge sur leur sorties. 1 image merge -> Cette image est reli sur son entre aux diffrentes images encode.
The-graph fonctionne grce des objets JSON. En effet il faut produire les fichiers JSON qui permettent de dcrire tous les noeuds et toutes les connections entre les diffrents noeuds. Il faut au pralable avoir dfini ces noeuds en tant que "components" pour que cela fonctionne.
Pour ce faire, 2 fichiers ont t modifis pour correspondre notre projet :
read-status.js -> Les fonctions ncessaires au bon fonctionnement de notre graph sont dfinis ici. Une fonction permet de rcuprer le json envoy par la requte GET au swarm. Une fonction permettant de gnrer la librairie de components et une fonction permettant d'afficher les nodes ainsi que les connections entre les nodes.
index.html -> Permet d'appeler les fonctions dfinis dans read-status afin de charger le graphe.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <[email protected]>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0\. You just DO WHAT THE FUCK YOU WANT TO.