Intégration de VLC
Par lud42fr le mercredi, février 21 2007, 22:55 - Tutoriels - Lien permanent
- Comment intégrer VLC dans une application Qt ?
- Comment visualiser une vidéo dans une applicaiton Qt ?
Ce tutoriel va explorer l'intégration de la bibliothèque VLC dans Qt, pour la lecture de fichier.
Version : Qt3, Qt4
Auteur : Ludo (lud42fr)
Status : basé sur la version SVN 0.9.0 de l’API VLC (devrait egalement fonctionner avec une version >= 0.8.6)
Introduction
Qt, dans son souci de framework généraliste, n’implémente pas toujours tout ce dont on peut avoir besoin, surtout lorsque cela n’est pas d’usage courant. Les vidéos font partie de ce qui n’est pas couvert par Qt. Cependant, un grand nombre de librairies et autres backends existent. Nous allons voir comment utiliser l’une d’entre elle: VLC.
Pré-requis
Voici ce dont vous aurez besoin :
- Les librairies VLC >= 0.8.6 (Page de téléchargement)
- La documentation des fonctions internes de VLC
- Il semblerait que VLC soit difficilement compilable sous Visual C++. Comme ce tutoriel suppose de pouvoir lier votre application avec les libraires VLC, les personnes désireuses de développer sous Windows devront utiliser Mingw pour générer leur application.
Pour compiler VLC 0.9.0 (la version actuellement en cours de développement, récupérable depuis le SVN), vous aurez besoin de :
- bibliothèque MAD (MPEG Audio Decoder) : http://www.underbit.com/products/ma... ou mettre une option lors du
configurepour la désactiver, - FFMpeg : http://ffmpeg.mplayerhq.hu/,
- liba52 : http://liba52.sf.net,
- libmpeg2 : http://libmpeg2.sf.net.
Lecteur vidéo
Ce tutoriel détaille la manière d'utiliser l'API VLC au travers d'une application Qt.
L’avantage de cette méthode est que le contrôle de VLC est plus simple et précis et ne nécessite pas d’exécuter/piloter un processus externe (contrairement à l'utilisation de MPlayer).
Nous allons créer un petit exemple simple de lecteur vidéo, ce dernier permettant :
- d’initialiser VLC,
- de charger un flux vidéo,
- de naviguer dans la vidéo (avance/retour),
- de modifier le volume.
Une image valant mieux qu'un long discours, voici une capture d'écran du résultat final :
Le code de ce tutorial (source + .pro)
Compilation
La compilation de l’exemple nécessite bien entendu les includes et les libraires de VLC. Celles ci doivent êtres dans dans les chemins de recherche
Linux/Unix
Voici le fichier pro typique :
TEMPLATE = app DEPENDPATH += . INCLUDEPATH += . SOURCES += tuto_vlc.cpp LIBS+=-lvlc
Explications
Si l'on résume les étapes nécessaires à la lecture d'un vidéo dans une application Qt :
- initialiser un contexte VLC,
- ajouter un flux à la playlist,
- rediriger la fenêtre vidéo de sortie vlc sur un widget Qt de l'application,
- démarrer la lecture du flux.
Certaines fonctions de l'API de VLC seront détaillées. Toutes ces fonctions et bien plus encore sont disponibles dans la documentation de VLC.
Initialisation d'un contexte VLC
Normalement seule l'inclusion de l'entête vlc/libvlc.h est nécessaire pour utiliser toutes les fonctions VLC.
#include <vlc/libvlc.h>
VLC reporte toutes ses erreurs dans une structure particulière libvlc_exception_t. Avant tout appel à une fonction VLC, il nous faudra donc une telle structure :
libvlc_exception_t _vlcexcep; //déclaration de la structure libvlc_exception_init (&_vlcexcep); //initialisation de la structure
Quelques fonctions pratiques à utiliser avec libvlc_exception_t :
if(libvlc_exception_raised(&_vlcexcep)!=0) {....} //teste si une erreur a eu lieu. libvlc_exception_get_message(&_vlcexcep); //retourne le message d'erreur libvlc_exception_clear(&_vlcexcep); //efface la/les erreurs précédentes
Il est maintenant temps de créer un contexte VLC, de type libvlc_instance_t, nécessaire à la plupart des fonctions :
libvlc_instance_t *_vlcinstance; _vlcinstance=libvlc_new(argc,argv,&_vlcexcep);
Il n'est possible de lire qu'un seul flux vidéo à la fois par contexte. Pour lire plusieurs flux en parallèle, il faut donc initialiser plusieurs contextes. Lorsqu'un contexte, n'est plus utile, ne pas oublier de le libérer :
libvlc_destroy (_vlcinstance, &_vlcexcep);
Ajout d'un flux
Le chargement d'un flux vidéo se fait dans un contexte initialisé et dans l'élément playlist de VLC (se réfèrer à la doc quant à la gestion des playlist, ce tutoriel n'en faisant pas d'autres mentions).
libvlc_playlist_clear(_vlcinstance,&_vlcexcep); //on vide la playlist libvlc_playlist_add (_vlcinstance,URL,NULL,&_vlcexcep);//on ajoute le nouveau flux
Note : à ce niveau, le fichier est dans la playlist, il n'est pas en cours de lecture ou n'a pas interrompu la lecture en cours.
Avec URL une chaine de caractère de la forme (principalement) :
| Type | Forme |
|---|---|
| Fichier local | file://chemin |
| Url http | http://ip:port/file |
| Fichier ftp | ftp://ip:port/file |
| DVD | dvd://[device] |
| Flux UDP | udp:[ |
Redirection du flux sur un widget Qt
La redirection de la sortie vidéo sur un widget de l'application est une des étapes les plus importantes pour l'intégration (ce n'est pas la plus compliquée ;-) ).
A noter que VLC, se chargera d'adapter la taille de la vidéo à la taille du widget tout en conservant l'aspect de la video (VLC se chargera aussi de resizer la video si la taille du widget venait a changer en cours de lecture).
N'importe quel widget peut servir pour afficher une video, mais dans la mesure ou il sera complètement recouvert, un simple QWidget suffit.
//Notez l'usage de Widget->winId() pour indiquer on dessiner la video libvlc_video_set_parent(_vlcinstance ,Widget->winId(),&_vlcexcep);
Functions vidéos/audios
Certaines fonctions requièrent un pointeur sur libvlc_input_t .Pour obtenir ce pointeur, un flux doit etre en cours de lecture/pause :
libvlc_input_t *input=libvlc_playlist_get_input (_vlcinstance,&_vlcexcep); //obtenir un pointeur input libvlc_input_free (input); //il est en general de bon ton de libérer input après usage
Contrôle de la vidéo
- Démarrer la lecture :
libvlc_playlist_play (_vlcinstance , -1, 0, NULL, &_vlcexcep); // avec : // -1 pour indiquer de lire l'element suivant de la playlist // 0 le nombre d'option a passer au flux a lire // NULL : les options
- Stopper la lecture :
libvlc_playlist_stop (_vlcinstance, &_vlcexcep);
- Mettre en pause la lecture :
libvlc_playlist_pause (_vlcinstance, &_vlcexcep);
- Connaître l'état :
int etat=libvlc_playlist_isplaying(_vlcinstance, &_vlcexcep); //etat=0 si stop ou pause //etat=1 si lecture en cours
- Lire en boucle :
int loop=1; //mettre a 0 pour stopper la lecture en boucle libvlc_playlist_loop (_vlcinstance, loop,&_vlcexcep);
- Connaître la durée totale du flux (nécessite un pointeur input) :
long long duree=libvlc_input_get_length (input, &_vlcexcep);
- Connaître la position actuelle en ms (nécessite un pointeur input) :
long long position=libvlc_input_get_time (input, &_vlcexcep);
- Se positionner dans le flux (position en ms - nécessite un pointeur input) :
libvlc_input_set_time (input, 42000,&_vlcexcep); //se positionne a 42 sec
- Connaître la position actuelle en pourcentage (nécessite un pointeur input) :
float posEnPourcent=libvlc_input_get_position (input, &_vlcexcep)*100.0;
- Se positionner dans le flux (position en pourcentage du temps total - nécessite un pointeur input) :
libvlc_input_set_position(input, 0.42f,&_vlcexcep); // se positionne a 42% du flux ???
Contrôle du volume
- Obtenir la valeur du volume comprise entre 0 et 100 - 0 étant le minimum :
int volume=libvlc_audio_get_volume (_vlcinstance, &_vlcexcep);
- Positionner le volume (valeur en 0 et 100) :
libvlc_audio_set_volume (_vlcinstance, 42,&_vlcexcep); //volume a 42%

Commentaires
Pour compiler VLC 0.9.0, il faut la lib mad (http://www.underbit.com/products/ma...) ou mettre une option au "configure" pour la désactiver ainsi que FFMpeg et ses headers ainsi que a52 (http://liba52.sf.net) et mpeg2 (http://libmpeg2.sf.net)
++
nikikko : merci, c'est ajouté dans le tutoriel
Je voudrais savoir comment fabriquer libvlc.h, en effet, le seul libvlc que j'ais dans mes sources vlc est un .dll .
Faut'il que je lise le point dll et que j'en fasse le .h correspondant ?
Problème résolu.
comment produire le fichier linbvlc.h
Bonjour,
j'ai eu un petit problème avec l'exemple de ce tuto. Tout compile très bien et j'ai préparé une vidéo à ouvrir.
Maintenant quand le lance le programme, une fenêtre s'affiche (avec les bonnes dimentions de la vidéo) et se ferme tout de suite avec un joli message d'erreur :
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 7 (X_ReparentWindow)
Resource id in failed request: 0x2e00008
Serial number of failed request: 118
Current serial number in output stream: 119
Quelqu'un aurait une idée ?
"X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 7 (X_ReparentWindow)
Resource id in failed request: 0x2e00008
Serial number of failed request: 118
Current serial number in output stream: 119"
C'est souvent du au sleep(ms)
il ne faut pas hesiter a augmenter la valeur de ms
(au niveau de :
// donc je met un sleep (oui avec deux e ;) ) en attendant de trouver mieux
sleep (1);
)
bonjour, j'utilise VLC et QT, grace à vous, merci beaucoup
je voulais simplement vous faire part d'une remarque:
la ligne qui pose problème et entraine à des mettage de sleep
=> libvlc_video_set_parent(_vlcinstance ,(libvlc_drawable_t)(_videoWidget->winId()),&_vlcexcep);
peut être intégrée directement dans le constructeur de la classe du player, ou plus exactement juste après la création de l'instance _vlcinstance
du coup plus besoin de l'appeler dans la fonction playFile(), ni de mettre un sleep (une couche?!) de précaution avant
ah oui et aussi j'ai une pitite question, si quelqu'un sait comment faire pour éviter que l'objet VLC ne reçoivent les événements clavier/souris (ça parasite les shortcuts de mon appli) ... j'ai lu quelques pistes à base de callback sur les forums d'ici je crois, mais rien de clair, et sur la doc officiel pas grand chose non plus ...
Aide bienvenue = )
<citation>si quelqu'un sait comment faire pour éviter que l'objet VLC ne reçoivent les événements clavier/souris</citation>
tu as essayer avec :
ton_widget_ou_vlc_dessine->setEnabled(false); ?
salut minirop
oui c'est testé sans succès...
_videoWidget->setEnabled(false);
et aussi
_videoWidget->releaseKeyboard();
même en bloquant l'accès du clavier aux autres widget en appellant grabKeyboard(); dans le constructeur du main widget, dès lors que ma souris est sur la video, c'est vlc qui reçoit les keystrokes et plus mon appli : \
peut être une option au lancement de vlc pourrait lui dire de ne pas gérer ni clavier ni souris, mais perso j'ai po trouvé ...
précision, quand je dis que j'ai pas trouvé c un peu de google et aussi les commandes suivantes:
vlc --help --advanced|grep keyboard => rien
vlc --help --advanced|grep input =>
--input-repeat <Entier> Répétitions de l’entrée
--input-list <Chaîne> Liste des entrées
--input-slave <Chaîne> Entrée auxiliaire (expérimental)
vlc --help --advanced|grep key => la liste des keybindings
donc à priori je vois pas de façon de lancer une instance de vlc qui ne s'accapare pas le clavier et la souris ... c'est peut être possible, mais comment ?
wopla up
besoin d'aide sur la gestion des événements en entrée (clavier/souris), de l'instance vlc créé avec libvlc.
Si vous avez une piste sur les callback d'évenement de la libvlc, je veux bien la suivre ...
cimer
Quelques modifications pour une bonne compilation sous avec vlc-0.8.6b et suppression du sleep(1) :
dans le tuto_vlc.pro
LIBS+= -lvlc -li420_rgb_mmx -li420_ymga_mmx -li420_yuy2_mmx -li422_yuy2_mmx -lmemcpy3dn -lmemcpymmx -lmemcpymmxext
Pour regler les problemes de sleep() il est plus de supprimer l'attribut QFrame *_videoWidget inutile a mon sens, et passer directement le this->winId() a la foncton libvlc_video_set_parent() en ayant prealablement pris le soin de declarer le constructeur Player::Player(QWidget *parent = 0 ) : public QWidget(parent)
Ceci fonctionne tres bien si on souhaite integrer un flux v4l dans un widget. J'ai laisse le layout par contre sans ajouter quoi que ce soit dedans.
Comment utiliser la DLL VLC sans recompiler VLC dans un projet Visual C++ ?
ou-puis-je trouver le .lib sinon ?
merci
kaned > tu ne peux pas utiliser seulement la DLL. Comme tu l'as dit, il faut aussi le .lib.
A part en demandant à quelqu'un qui a déjà compilé, je ne vois pas comment faire pour le récupérer (à moins que ça traîne sur le net).
merci nicolas.
bon je fais un appel à temoin, pour le .lib win32....
Bonjour;
La compilation du code de ce tutos se passe normalement, cependant à l'exécution le fenêtre s'affiche mais se ferme de suite après avec ce message d'erreur :
main video outpout error :option glx-shm does not exist
main video outpout error :no chroma module for I420 to
Quelqu'un aurait une idée???
Bonjour,
J'ai longtemps developpé sous windows et la je passe sous linux quand je compile j'ai ces messages:
Makefile qdevelop-settings.db tuto_vlc.cpp tuto_vlc.moc tuto_vlc.o tuto_vlc.pro
root@ubuntu:/home/clap/tuto_vlc# make
g++ -m64 -Wl,-rpath,/usr/local/Trolltech/Qt-4.3.0/lib -o tuto_vlc tuto_vlc.o -L/usr/local/Trolltech/Qt-4.3.0/lib -lvlc -lQtGui -L/usr/local/Trolltech/Qt-4.3.0/lib -L/usr/X11R6/lib64 -lpng -lSM -lICE -pthread -pthread -lXi -lXrender -lXrandr -lXfixes -lXcursor -lXinerama -lfreetype -lfontconfig -lXext -lX11 -lQtCore -lz -lm -pthread -lgthread-2.0 -lglib-2.0 -lrt -ldl -lpthread
/usr/bin/ld: ne peut trouver -lvlc
collect2: ld returned 1 exit status
make: *** [tuto_vlc] Erreur 1
@Yaya,
Ton editeur de lien ne trouve pas la bibliotheque vlc, assures toi qu´elle existe bien , elle se nomme libvlc.so.* , une fois que tu la trouvé, le plus simple est de mettre un lien symbolique a partir de /usr/lib. -> "$cd /usr/lib" puis "$ln -s chemin/vers/lib/libvlc.so.* ."
jsuis pas oci kalé que vous mais jvoulais juste rentrer quelque skins pour vlc mais jsais pas du tout comment faire et j ai beau essayer mais sans succé meme e n regardant sur le net et tout vos conseils mais une explication aprofondie est la bien venu quand meme pour pouvoir progresser merci.
Bonjour,
Je cherche à acquérir un flux rtsp, savez-vous quelle est la syntaxe à utiliser dans la fonction playlist_play?
D'autre part j'aimerais aussi enregistrer ce flux dans un fichier et le streamer à nouveau. Peut-on le faire également?
Merci.
Bonjour,
Est ce que quelqu'un sait a quoi correspondent les options qu'on a dans la fonction pour lire la playliste?
Je veux arreter un flux reçu en RTP/RTSP, a un endroit precis de la video en recuperant l'etat d'avancement de la video et de reutiliser ce temps pour redemarer ma video la ou je l'ai arreté.
Salut!!
Mon probleme a certe déjà ete posé mais j'ai pas lu de reponse. Je voudrais recuperer un flux rtsp/rtp chez un server vod à partir de mon application QT. Est ce que quelqu'un pourrait m'aider???
J'ai deja introduit mes buttons "play/pause" et "stop". Il ne manque plus que la logique
merci
Bonjour , je ne trouve aucun fichier .a pour lier au projet . La compilation échoue donc lorsque je ne fais qu'inclure libvlc.h.¨Pouriez-vous donc m'aider.
ps : Je développe sous windows XP SP2 avec Dev-Cpp.
Bonjour à tous,
Tout d'abord bravo pour ce tutoriel qui va m'être très utile, j'ai ensuite une petite question à poser. Voila j'ai un problème avec ma fonction void libvlc_video_set_parent(_vlcinstance ,_videoWidget->winId(),&_vlcexcep); et plus particulierement avec l'argumen 2 : _videoWidget->winld().
Le compilateur (minGW) me donne deux erreur :
- la premiere comme quoi il n'arrive pas à convertir de 'HWND_*' à 'libvlc_drawable_t'
- la deuxiéme comem quoi il a un problème à l'initialisation de cet arrgument (le 2).
Merci d'avance si quelqu'un à une petite idée d'ou ça peut venir...
@moustick:
As-tu bien lu la section Pré-requis? Il faut que tu compiles toi même la lib vlc:
http://www.videolan.org/developers/...
@Sébastien:
Il faut passer par un reinterpret_cast:
reinterpret_cast<unsigned int>(_videoWidget->winId())
et ça devrait passer.
Bonjour,
J'ai un probleme dans l'execution:
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 7 (X_ReparentWindow)
Resource id in failed request: 0x4a00008
Serial number of failed request: 121
Current serial number in output stream: 122
*** Exited with status: 1 ***
J'ai augmenté la valeur de sleep sans resultat
merci
bonjours,
je ne suis pas sous QT, mais je souhaiterai créer un flux a partir d'une carte d'acquisition et l'envoyer par udp.Je pense mettre le code de ce tuto jusqu'a :
libvlc_playlist_clear(_vlcinstance,&_vlcexcep); //on vide la playlist
libvlc_playlist_add (_vlcinstance,URL,NULL,&_vlcexcep);//on ajoute le nouveau flux
URL=v4l:://Video0 pour respecter ça :
Type Forme
Fichier local file://chemin
Url http http://ip:port/file
Fichier ftp ftp://ip:port/file
DVD dvd://[device]
Flux UDP udp:[]@[][:]%%
masi ensuite pour envoyer ce flux ?
que doi je faire ??
quel argument dois je récupérer et quel fonction dois je utilisé ???
la libvlc est très mal documenté je trouve..et les exemple sont rare et quand il y en as, sont très court.....
Merci.
Bonjour,
Je vous explique mon problème : je dois réaliser un lecteur en C++, pour cela je pensais utiliser dans un premier temps le module phonon intégré à Qt, mais il m'était impossible de compiler. Je me suis donc rabattu sur la bibliothèque libvlc mais a la compilation il ne reconnait pas la bibliothèque, je voudrais savoir comment intégrer libvlc a mon programme ( error: vlc/libvlc.h: Aucun fichier ou répertoire de ce type).
Merci d'avance
Bonjour, je n'arrive pas du tout a compiler ton tuto. J'ai déjà un problème a propos des bibliotèques. Il ne les reconnait pas Merci de m'aider
Bonjour,
Tout d'abord bravo pour ce tuto qui est super bien illustré et expliqué (nécessaire pour un débutant pour moi lool)
Je suis novice dans la matière, j'ai tenté désespérément pendant 2 jours d'essayer de faire marcher la compile de vlc en utilisant les tutos videolan mais je m'en sors pas... :-(
Ainsi je voulais savoir si:
c'est obligatoire de compiler vlc en utilisant leurs tutos qui me sont incaptables?
mon but est juste de pouvoir utiliser #include <vlc/libvlc.h> dans mon code donc est il possible de se procurer les .dll et .lib directement pour pouvoir remédier à cette difficuté?
Bonjour , Je suis sur une distribution linux et par mon manque d'expérience je me retrouve bloqué aux début de se tuto , Je ne comprend pas comment installé corectement la/les librairie vlc et aussi quoi mettre réelement dans le .pro et dans mon makefile pour que , je puisse avec l'include <vlc/libvlc.h> seulement pouvoir utilisé ses fonction vlc . Merci de votre aide .
Bonjour,
J'ai essayé de faire ce tuto à plusieurs reprises et je rencontre un problème lors de l'utilisation, voici en gros comment j'ai fait (sous WinXP) :
- J'ai téléchargé les sources de vlc (1.0.1) ainsi que les binaires (même version)
- J'ai extrait les sources, puis j'ai copié le dossier 'vlc' qui se trouve dans le dossier '\vlc-1.0.1\include' dans le dossier 'C:\Qt\2009.03\qt\include'
- Une fois l'installation des binaires effectuée, j'ai copier les fichiers libvlc.dll et libvlccore.dll dans 'C:\Qt\2009.03\qt\lib'
- J'ai compilé les projet sans aucun problème (les DLLs faisant office de LIBs) en ajoutant un bouton pour pouvoir ouvrir un fichier vidéo
- Lors de l'utilisation (les dll de vlc doivent aussi se trouver dans le dossier de votre appli pour debug et release) je rencontre un problème : la vidéo ne s'affiche pas (n'est pas lue) et je ne comprend pas les messages debug de VLC, quelqu'un a-t-il réussi a y faire fonctionner avec la LibVLC 1.0.1 ?
Merci d'avance, Bonne soirée
Jeje
[Info supplémentaire : ne pas oublier de mettre "LIBS += -lvlc" dans le .pro]