serveur_multimedia_artnet
Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédenteDernière révisionLes deux révisions suivantes | ||
serveur_multimedia_artnet [2018/04/26 17:00] – serge | serveur_multimedia_artnet [2020/10/04 12:16] – ↷ Liens modifiés en raison d'un déplacement. serge | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | ======Serveur | + | ====== Serveur |
- | Projet en cours … | + | ===== Matériel ===== |
+ | * 4 x Raspberry Pi 3 : | ||
+ | * 4 x Disque dur WD [[https:// | ||
+ | * 4 x [[https:// | ||
+ | * 4 x [[https:// | ||
+ | * 1 x Borne d' | ||
+ | * 2 x Câbles ethernet Cat 5 | ||
+ | * 1 x Node OnPC | ||
+ | * 2 x Adaptateurs USB-C / Ethernet | ||
+ | * 1 x Ordinateur tournant sous Windows | ||
- | La première présentation se déroulera lors de la fête des 0 et des 1 le samedi 9 mai 2015 à Orléans. | + | ===== Switch WIFI ===== |
+ | [[https:// | ||
- | ===== Présentation | + | [[https:// |
+ | |||
+ | [[http:// | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | Mettre à jour le firmware | ||
+ | |||
+ | ==== Connecter l' | ||
+ | Sur MAC | ||
+ | Dans Préférences système > Réseaux, choisissez le port ethernet puis dérouler la liste Configurer IPV4 > Manuellement | ||
+ | Ensuite dans remplir les champs suivants : | ||
+ | Adresse IP : 192.168.0.210 | ||
+ | Sous-réseau : 255.255.255.0 | ||
+ | Cliquer sur Appliquer | ||
+ | Allumer la borne d' | ||
+ | Brancher avec un câble RJ45 l' | ||
+ | |||
+ | Dans un navigateur entrer l' | ||
+ | 192.168.0.100 | ||
+ | Entrer les valeurs suivantes dans les champs correspondants : | ||
+ | Admin : admin | ||
+ | Password : password | ||
+ | La fenêtre de configuration s' | ||
+ | |||
+ | Dans Setup > Wireless Setup | ||
+ | |||
+ | Changer le SSID et le mot de passe pour le 2,4 gHz. | ||
+ | Changer le canal de diffusion choisir le 1 car le 12 et le 13 peuvent poser des problèmes. | ||
+ | |||
+ | Dans les options de sécurité choisir : | ||
+ | WPA2-PSK [AES] | ||
+ | Cliquer sur Apply pour sauvegarder la configuration. | ||
+ | |||
+ | Dans Advaced Setup > IP Settings, cocher la case : | ||
+ | Use fixed IP Address (not recommended): | ||
+ | Vous pouvez changer l' | ||
+ | IP address : 192.168.1.200 | ||
+ | Netmask : 255.255.255.0 | ||
+ | Gateway IP address : 192.168.1.1 | ||
+ | Primary DNS : 192.168.1.1 | ||
+ | Cliquer sur Apply | ||
+ | |||
+ | ===== Installer un disque dur ===== | ||
+ | Pour pouvoir utiliser des fichiers vidéos conséquents, | ||
+ | sudo apt-get update | ||
+ | sudo apt-get install exfat-fuse | ||
+ | |||
+ | Une fois le disque branché sur un port USB de la Raspberry, taper : | ||
+ | sudo fdisk -l | ||
+ | Vous verrez ainsi que le disque de 250 Go a bien été détecté. Vous devez avoir un résultat semblable : | ||
+ | Disk /dev/sda: 232.9 GiB, 250025607168 bytes, 488331264 sectors | ||
+ | |||
+ | Préparer la partition | ||
+ | sudo cfdisk /dev/sda | ||
+ | Il faut d' | ||
+ | |||
+ | === Créer une nouvelle partition === | ||
+ | Allez sur [ New ] et validez. Comme nous n'en créons qu'une seule elle prendra la totalité de l' | ||
+ | Votre partition st créée et elle s' | ||
+ | 7 HPFS/ | ||
+ | Pour finaliser, aller sur [ Write ] et validez et confirmez avec ''' | ||
+ | Le message suivant s' | ||
+ | The partition table has been altered. | ||
+ | L' | ||
+ | Pour quitter l' | ||
+ | |||
+ | Vous pouvez vérifier le résultat avec : | ||
+ | sudo fdisk -l | ||
+ | === Formater la partition === | ||
+ | Une fois la pétition crée, il faut la formater avec : | ||
+ | sudo mkfs.exfat -n RaspiHDD /dev/sda1 | ||
+ | |||
+ | === Monter le disque dur === | ||
+ | Créer le répertoire dans lequel le disque sera monté par exemple pour qu'il soit facilement accessible, le nom du répertoire sera par exemple PIHDD : | ||
+ | sudo mkdir / | ||
+ | Monter le disque au point voulu : | ||
+ | sudo mount /dev/sda1 / | ||
+ | Vérifier que l' | ||
+ | ls / | ||
+ | |||
+ | === Monter les disque automatiquement au démarrage === | ||
+ | Repérer en premier lieu l' | ||
+ | sudo blkid | ||
+ | Par exemple ''' | ||
+ | |||
+ | Il faut ensuite modifier le fichier fstab | ||
+ | sudo nano / | ||
+ | Ajouter à la fin du fichier la ligne suivante : | ||
+ | UUID=5C24-1453 / | ||
+ | Ctrl + O validez et Ctrl + X pour finaliser l' | ||
+ | |||
+ | === Sources === | ||
+ | * [[https:// | ||
+ | * [[http:// | ||
+ | * [[https:// | ||
+ | |||
+ | ===== Installer OLA ===== | ||
+ | [[https:// | ||
+ | |||
+ | Installer les dépendances : | ||
+ | sudo apt-get install autoconf uuid-dev pkg-config libncurses5-dev libtool libcppunit-dev libmicrohttpd-dev automake g++ protobuf-compiler libprotobuf-lite10 python-protobuf libprotobuf-dev libprotoc-dev zlib1g-dev bison flex make libftdi-dev libftdi1 libusb-1.0-0-dev liblo-dev libavahi-client-dev python-numpy | ||
+ | |||
+ | |||
+ | Avec Git | ||
+ | sudo apt-get install git | ||
+ | git clone https:// | ||
+ | cd ola | ||
+ | |||
+ | Pour installer les fichiers manquants : | ||
+ | autoreconf -i | ||
+ | |||
+ | Pour configurer l' | ||
+ | ./configure --help | ||
+ | Vous donnera la liste des éléments possible à inclure. Ici nous allons faire simple, nous n' | ||
+ | ./configure --disable-all-plugins --enable-artnet --enable-http | ||
+ | Compiler en utilisant les quatre coeurs du processeur (durée 25 minutes): | ||
+ | make -j4 | ||
+ | make check | ||
+ | sudo make install | ||
+ | Pour pouvoir utiliser les nouvelles libraires installées : | ||
+ | sudo ldconfig | ||
+ | |||
+ | Pour lancer le serveur lad | ||
+ | olad -l 3 | ||
+ | |||
+ | Vous pouvez à présent vérifier que vous pouvez accéder au serveur en tapant dans votre navigateur préféré : | ||
+ | raspberrypi.local: | ||
+ | Une page s' | ||
+ | Universe Id : 0 | ||
+ | Universe Name : Raspberry0 | ||
+ | Et cocher la case | ||
+ | ArtNet [192.168.1.x] | ||
+ | Puis valider la création en cliquant sur le bouton | ||
+ | |||
+ | Pour vérifier qu'il reçoit bien des informations, | ||
+ | Dans cette page vous pouvez voir toutes les valeurs reçues par le serveur OLA. | ||
+ | |||
+ | === Configurer OLA === | ||
+ | [[https:// | ||
+ | |||
+ | ===== Installer OMXPlayer ===== | ||
+ | Si git n'est pas installé : | ||
+ | sudo apt-get install git | ||
+ | Ensuite : | ||
+ | git clone https:// | ||
+ | Une fois le téléchargement fini | ||
+ | cd omxplayer | ||
+ | Installer les dépendances : | ||
+ | sudo apt-get update && sudo apt-get install | ||
+ | Le script prépare les fichiers nécessaire à l' | ||
+ | ./ | ||
+ | Compiler avec | ||
+ | make ffmpeg | ||
+ | make -j4 | ||
+ | Puis installer avec : | ||
+ | sudo make install | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | ===== Programmation C++ ===== | ||
+ | [[https:// | ||
+ | g++ -o multi multi.cpp $(pkg-config --cflags --libs libola) | ||
+ | |||
+ | <code c++> | ||
+ | /////////////////////////////////////////////////////////////////////////////////////////////////// | ||
+ | // | ||
+ | // g++ -o multi multi.cpp $(pkg-config --cflags --libs libola) | ||
+ | // | ||
+ | /////////////////////////////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | using namespace std; | ||
+ | |||
+ | // Variabes globales | ||
+ | static const string chemin = "/ | ||
+ | vector< | ||
+ | int fichirEnLecture = -1; | ||
+ | |||
+ | void RegisterComplete(const ola:: | ||
+ | if (!result.Success()) { | ||
+ | OLA_WARN << " | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void arreterVideo(int index) { | ||
+ | cout << " | ||
+ | cout << " | ||
+ | system(" | ||
+ | } | ||
+ | |||
+ | void demarrerVideo(int index) { | ||
+ | cout << " | ||
+ | cout << "Video : " << listeFichiers[index] << endl << endl; | ||
+ | int pid = fork(); | ||
+ | if(pid == 0) { | ||
+ | string fichierVideo = chemin + listeFichiers[index]; | ||
+ | execlp(" | ||
+ | _exit(0); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Appeler lors de la réception d'une trame DMX | ||
+ | void NewDmx(const ola:: | ||
+ | const ola:: | ||
+ | if ((fichirEnLecture >= 0) && (data.Get(fichirEnLecture) < 128)) { | ||
+ | arreterVideo(fichirEnLecture); | ||
+ | fichirEnLecture = -1; | ||
+ | } | ||
+ | for (int i = 0; i < listeFichiers.size(); | ||
+ | if (data.Get(i) > 127) { | ||
+ | if (fichirEnLecture != i) { | ||
+ | arreterVideo(fichirEnLecture); | ||
+ | fichirEnLecture = i; | ||
+ | demarrerVideo(fichirEnLecture); | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void listerRepertoire(string chemin, vector< | ||
+ | DIR* repertoire = opendir(chemin.c_str()); | ||
+ | struct dirent* fichierLu; | ||
+ | if (repertoire != NULL) { | ||
+ | while ((fichierLu = readdir(repertoire)) != NULL) { | ||
+ | if (fichierLu-> | ||
+ | tableau.push_back(fichierLu-> | ||
+ | } | ||
+ | } | ||
+ | sort (tableau.begin(), | ||
+ | } | ||
+ | closedir(repertoire); | ||
+ | } | ||
+ | |||
+ | unsigned int univers() { | ||
+ | unsigned int univers; | ||
+ | ifstream fichier("/ | ||
+ | string ligne; | ||
+ | size_t position; | ||
+ | while(getline(fichier, | ||
+ | position = ligne.find(" | ||
+ | if (position == 0) { | ||
+ | ligne = ligne.substr(10); | ||
+ | univers = stoi(ligne); | ||
+ | cout << univers << endl; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | fichier.close(); | ||
+ | return univers; | ||
+ | } | ||
+ | |||
+ | int main() { | ||
+ | // Lister les fichiers vidéos présents | ||
+ | listerRepertoire("/ | ||
+ | for (int i = 0; i < listeFichiers.size(); | ||
+ | cout << listeFichiers[i] << endl; | ||
+ | } | ||
+ | |||
+ | ola:: | ||
+ | ola:: | ||
+ | if (!wrapper.Setup()) | ||
+ | exit(1); | ||
+ | ola:: | ||
+ | // Set the callback and register our interest in this universe | ||
+ | client-> | ||
+ | client-> | ||
+ | | ||
+ | | ||
+ | wrapper.GetSelectServer()-> | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ===== Configuration supplémentaires ===== | ||
+ | [[https:// | ||
+ | |||
+ | [[https:// | ||
+ | === Écran noir au démarrage === | ||
+ | *modifier le fichier cmdline.txt | ||
+ | sudo nano / | ||
+ | et ajouter sur la même ligne à la fin | ||
+ | consoleblank=20 | ||
+ | *source | ||
+ | [[https:// | ||
+ | |||
+ | === Accéder à la borne === | ||
+ | Il faut éditer le fichier wpa_supplicant.conf avec la commande : | ||
+ | sudo nano / | ||
+ | Ensuite ajouter : | ||
+ | ctrl_interface=DIR=/ | ||
+ | network={ | ||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | === Adresse IP fixe === | ||
+ | Afin d' | ||
+ | sudo nano / | ||
+ | Puis insérer le lignes suivantes à la fin du fichier : | ||
+ | auto wlan0 | ||
+ | |||
+ | iface lo inet loopback | ||
+ | |||
+ | iface eth0 inet dhcp | ||
+ | |||
+ | allow-hotplug wlan0 | ||
+ | iface wlan0 inet static | ||
+ | address 192.168.1.101 | ||
+ | netmask 255.255.255.0 | ||
+ | gateway 192.168.1.200 | ||
+ | wpa-conf / | ||
+ | iface default inet dhcp | ||
+ | |||
+ | ===== GrandMA2 ===== | ||
+ | === Configuration ArtNet === | ||
+ | {{media_03: | ||
+ | === Configuration sACN === | ||
+ | Mettre le node dans le même sous-réseau : | ||
+ | [Setup] > [Network Configuration] > [DMX Node] | ||
+ | Pour modifier l'IP du code faire un clic secondaire sur le champ IP Ethernet 1 (Eth0) et entrer | ||
+ | 192.168.1.202 | ||
+ | Configurer la sortie sACN | ||
+ | [Setup] > [Network Protocols] > [sACN] | ||
+ | Remplir les champs avec les valeurs indiquées ci-dessous : | ||
+ | |||
+ | {{:: | ||
+ | |||
+ | Ne pas oublier d' | ||
+ | [Ouput sACN Active] | ||
+ | |||
+ | ===== Version sACN ===== | ||
+ | Avec l' | ||
+ | |||
+ | Les fichiers sont triés et lus dans l' | ||
+ | |||
+ | Le circuite 512 éteint la Raspberry PI. Il est nécessaire de le faire pour ne pas détériorer la Pi. | ||
+ | |||
+ | <code c++> | ||
+ | /////////////////////////////////////////////////////////////////////////////////////////////////// | ||
+ | // | ||
+ | // g++ -Wall -o UDP UDP.cpp | ||
+ | // Documentation sACN : http:// | ||
+ | // http:// | ||
+ | // | ||
+ | /////////////////////////////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | using namespace std; | ||
+ | |||
+ | // Variabes globales | ||
+ | static const string chemin = "/ | ||
+ | static const int port = 5568; // Port par défaut du protocole sACN | ||
+ | vector< | ||
+ | unsigned int fichirEnLecture = -1; | ||
+ | |||
+ | string intToHexString (int n) { | ||
+ | ostringstream oss; | ||
+ | oss << hex << n; | ||
+ | return oss.str(); | ||
+ | } | ||
+ | |||
+ | string intToString (int n) { | ||
+ | ostringstream oss; | ||
+ | oss << n; | ||
+ | return oss.str(); | ||
+ | } | ||
+ | |||
+ | void arreterVideo(int index) { | ||
+ | cout << " | ||
+ | cout << " | ||
+ | system(" | ||
+ | } | ||
+ | |||
+ | void demarrerVideo(int index) { | ||
+ | cout << " | ||
+ | cout << "Video : " << listeFichiers[index] << endl << endl; | ||
+ | int pid = fork(); | ||
+ | if(pid == 0) { | ||
+ | string fichierVideo = chemin + listeFichiers[index]; | ||
+ | execlp(" | ||
+ | _exit(0); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void arreterRaspberry() { | ||
+ | system(" | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | void listerRepertoire(string chemin, vector< | ||
+ | DIR* repertoire = opendir(chemin.c_str()); | ||
+ | struct dirent* fichierLu; | ||
+ | if (repertoire != NULL) { | ||
+ | while ((fichierLu = readdir(repertoire)) != NULL) { | ||
+ | if (fichierLu-> | ||
+ | tableau.push_back(fichierLu-> | ||
+ | } | ||
+ | } | ||
+ | sort (tableau.begin(), | ||
+ | } | ||
+ | closedir(repertoire); | ||
+ | } | ||
+ | |||
+ | int main(int argc, char *argv[]) { | ||
+ | |||
+ | // Variables ; | ||
+ | int yes = 1; | ||
+ | |||
+ | // Création du socket | ||
+ | int sckt = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); | ||
+ | if (sckt < 0) { | ||
+ | perror(" | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | // Ouverture du socket | ||
+ | sockaddr_in adresse; | ||
+ | adresse.sin_family = AF_INET; // L' | ||
+ | adresse.sin_port = htons(port); | ||
+ | adresse.sin_addr.s_addr = INADDR_ANY; // Permet d' | ||
+ | // V2rifie si le socket n'est pas déjà ouvert | ||
+ | int res = setsockopt(sckt, | ||
+ | if(res == -1) { | ||
+ | perror(" | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | res = bind(sckt, (struct sockaddr*) & | ||
+ | if (res < 0 ) { | ||
+ | perror(" | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | // Lister les fichiers vidéos présents | ||
+ | listerRepertoire(chemin, | ||
+ | for (unsigned int i = 0; i < listeFichiers.size(); | ||
+ | cout << listeFichiers[i] << endl; | ||
+ | } | ||
+ | |||
+ | // Boucle principale | ||
+ | while(1) { | ||
+ | char packet_data[638]; | ||
+ | struct sockaddr_in cliaddr; | ||
+ | socklen_t taille = sizeof(cliaddr); | ||
+ | |||
+ | int received_bytes = recvfrom(sckt, | ||
+ | if ( received_bytes > 0 ) { | ||
+ | // Traitement des données reçues | ||
+ | |||
+ | for (unsigned int i = 0; i < listeFichiers.size(); | ||
+ | if (packet_data[i + 126] > 127) { // 126 Début de la trame DMX | ||
+ | if (fichirEnLecture != i) { | ||
+ | arreterVideo(fichirEnLecture); | ||
+ | fichirEnLecture = i; | ||
+ | demarrerVideo(fichirEnLecture); | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | // Le canal 512 éteint la Raspberry Pi | ||
+ | if (packet_data[637] > 127) { | ||
+ | arreterRaspberry(); | ||
+ | } | ||
+ | /* | ||
+ | // | ||
+ | | ||
+ | for (int i = 126; i < 638; i++) { // Les vameurs DMX commencent à partir de l' | ||
+ | | ||
+ | } | ||
+ | cout << blip << endl << endl; | ||
+ | */ | ||
+ | } | ||
+ | } | ||
+ | close(sckt); | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Améliorations | ||
+ | Il serait bien de réécrire le programme et d' | ||
- | Le but de ce projet est de faire oeuvre patrimoniale en proposant de pouvoir consulter des oeuvres créer sur Minitel. C'est une installation qui regroupera six minitels pouvant être consultés en local et tous de manières indépendantes. | ||
- | ===== Matériel ===== | ||
- | * 1 x Raspberry 2 avec Raspbian installée | + | {{tag>c++ sylvain |
- | * 1 x Hub USB D-Link 7 voies DUB-H7 | + | |
- | * 6 x câbles FTDI | + | |
- | * 6 x connecteurs DIN 5 mâle Neutrix | + | |
- | * 6 x Minitel Alcatel 1 ou 1B | + | |
- | * | + | |
- | {{tag> | + |
serveur_multimedia_artnet.txt · Dernière modification : 2020/12/01 18:43 de serge