mpv

mpv est un lecteur vidéo, basé sur mplayer et mplayer2 (fork de ces deux projets).

mpv.io

En plus de son développement qui est très actif, ce lecteur vidéo supporte non seulement l’accélération matérielle, mais supporte en plus les effets et autres filtres de ffmpeg.

Malheureusement, sur les pages officielles de ffmpeg et de mpv, outre le fait que peu de détails soient donnés, aucun exemple concret n’est fourni.

http://ffmpeg.org/ffmpeg-filters.html#Multimedia-Filters

Effets applicables à l’audio

Tous les exemples (en vidéo) ont été effectués avec le titre Mesmerize, de t r y Δ d, disponible sur jamendo. https://www.jamendo.com/track/26744/mesmerize

Pour des raisons de visibilité, la pochette de l’album Public Domain (et non de Listen) du même groupe a été utilisée.

Certains paramètres sont communs à plusieurs filtres. Notamment :

  • r : framerate. Par défaut, défini à 25fps.

  • s (ou size) : Dimensions. À définir sous le format (width)x(height), sans les parenthèses. Dans les exemples, c’est défini à 720x720.

À noter : afin de forcer un affichage en 1280x720, le filtre et la pochette sont redimensionnés en 1280x720 via scale et pad. Et oui, il aurait été possible de dimensionner les effets directement en 1280x720.

Comme la pochette est en niveaux de gris et non en couleurs, l’utilisation de colorspace a été nécessaire. Sinon, tous les effets auraient été affichés en niveaux de gris.

En fonction des filtres, une rotation à 90° peut être nécessaire. Ici, c’est fait via rotate.

abitscope

Commande utilisée : :

mpv t\ r\ y\ Δ\ d\ -\ mesmerize.mp3 --lavfi-complex="[aid1]asplit[ao][a];[a]abitscope=r=60:s=720x720[vecPrep];[vecPrep]rotate=PI/2[vecOut];[vecOut]pad=1280:720:(ow-iw)/2:(oh-ih)/2[padOut];[vid1]colorspace=smpte240m:format=yuv420p[vidc];[vidc]scale=-2:720[vidScale];[vidScale]pad=1280:720:(ow-iw)/2:(oh-ih)/2[vpoc];[vpoc][padOut]blend=shortest=0:all_mode=overlay:all_opacity=1[vo]"

Résultat :

ahistogram (dmode single)

Commande utilisée :

mpv t\ r\ y\ Δ\ d\ -\ mesmerize.mp3 --lavfi-complex="[aid1]asplit[ao][a];[a]ahistogram=dmode=single:r=60:s=720x720[vecPrep];[vecPrep]rotate=PI/2[vecOut];[vecOut]pad=1280:720:(ow-iw)/2:(oh-ih)/2[padOut];[vid1]colorspace=smpte240m:format=yuv420p[vidc];[vidc]scale=-2:720[vidScale];[vidScale]pad=1280:720:(ow-iw)/2:(oh-ih)/2[vpoc];[vpoc][padOut]blend=shortest=0:all_mode=overlay:all_opacity=1[vo]"

Résultat :

ahistogram (dmode separate)

Commande utilisée :

mpv t\ r\ y\ Δ\ d\ -\ mesmerize.mp3 --lavfi-complex="[aid1]asplit[ao][a];[a]ahistogram=dmode=separate:r=60:s=720x720[vecPrep];[vecPrep]rotate=PI/2[vecOut];[vecOut]pad=1280:720:(ow-iw)/2:(oh-ih)/2[padOut];[vid1]colorspace=smpte240m:format=yuv420p[vidc];[vidc]scale=-2:720[vidScale];[vidScale]pad=1280:720:(ow-iw)/2:(oh-ih)/2[vpoc];[vpoc][padOut]blend=shortest=0:all_mode=overlay:all_opacity=1[vo]"

Résultat :

avectorscope

Commande utilisée :

mpv t\ r\ y\ Δ\ d\ -\ mesmerize.mp3 --lavfi-complex="[aid1]asplit[ao][a];[a]avectorscope=m=lissajous:zoom=1.5:rc=0:bc=0:gc=255:r=60:gf=32:af=255:s=720x720:draw=line[vecPrep];[vecPrep]rotate=PI/2[vecOut];[vecOut]pad=1280:720:(ow-iw)/2:(oh-ih)/2[padOut];[vid1]colorspace=smpte240m:format=yuv420p[vidc];[vidc]scale=-2:720[vidScale];[vidScale]pad=1280:720:(ow-iw)/2:(oh-ih)/2[vpoc];[vpoc][padOut]blend=shortest=0:all_mode=overlay:all_opacity=1[vo]"

Résultat :

Note

J’avoue que le résultat n’est pas très visible sur cet exemple.

Autre exemple :

mpv 06\ Planets.wav --lavfi-complex "[aid1]asplit[ao][a];[a]avectorscope=m=lissajous_xy:zoom=1:rc=0:bc=0:r=60:gf=127:af=127:s=720x720:mirror=xy[vo]"

Résultat :

Note

Ici, il s’agit d’un fichier RIFF/wav PCM provenant de Jerobeam Fenderson - Oscilloscope Music - WAV files. À la base, c’est concu pour être visualisé sur un oscilloscope. Le filtre avectorscope fonctionne très bien avec ces fichiers audio.

J’avoue avoir triché pour ce second exemple. J’ai utilisé la commande suivante (ffmpeg et non mpv, mais ça revient au même) :

ffmpeg -i 06\ Planets.wav -i 06\ Planets.wav -c:v libx264 -filter_complex "[aid1]avectorscope=m=lissajous_xy:zoom=1:rc=0:bc=0:r=60:gf=127:af=127:s=720x720:mirror=xy[vo]" -map "[vo]" -pix_fmt yuv420p -map 1:0 -c:a aac -t 30 avectorscope2.mp4

À noter : l’utilisation de deux fois le même fichier wav en entrée. En effet, asplit levant une erreur dans l’évaluation du graphe (l’ordre des filtres à appliquer), j’ai trouvé plus simple de spécifier deux fois le fichier en entrée, d’utiliser le premier comme source pour les filtres complexe pour générer la vidéo, et le second comme source audio pour l’encodage (d’où l’utilisation de map 1:0).

showcqt

Commande utilisée :

mpv t\ r\ y\ Δ\ d\ -\ mesmerize.mp3 --lavfi-complex="[aid1]asplit[ao][a];[a]showcqt=s=720x720:r=60[vecOut];[vecOut]pad=1280:720:(ow-iw)/2:(oh-ih)/2[padOut];[vid1]colorspace=smpte240m:format=yuv420p[vidc];[vidc]scale=-2:720[vidScale];[vidScale]pad=1280:720:(ow-iw)/2:(oh-ih)/2[vpoc];[vpoc][padOut]blend=shortest=0:all_mode=overlay:all_opacity=1[vo]"

Résultat :

Note

On peut retirer l’affichage du texte sur l’axe des abscisses, en ajoutant axis=0.

Commande sans le texte sur l’axe des x :

mpv t\ r\ y\ Δ\ d\ -\ mesmerize.mp3 --lavfi-complex="[aid1]asplit[ao][a];[a]showcqt=axis=0:s=720x720:r=60[vecOut];[vecOut]pad=1280:720:(ow-iw)/2:(oh-ih)/2[padOut];[vid1]colorspace=smpte240m:format=yuv420p[vidc];[vidc]scale=-2:720[vidScale];[vidScale]pad=1280:720:(ow-iw)/2:(oh-ih)/2[vpoc];[vpoc][padOut]blend=shortest=0:all_mode=overlay:all_opacity=1[vo]"

showfreqs

Commande utilisée :

mpv t\ r\ y\ Δ\ d\ -\ mesmerize.mp3 --lavfi-complex="[aid1]asplit[ao][a];[a]showfreqs=s=720x720[vecOut];[vecOut]pad=1280:720:(ow-iw)/2:(oh-ih)/2[padOut];[vid1]colorspace=smpte240m:format=yuv420p[vidc];[vidc]scale=-2:720[vidScale];[vidScale]pad=1280:720:(ow-iw)/2:(oh-ih)/2[vpoc];[vpoc][padOut]blend=shortest=0:all_mode=overlay:all_opacity=1[vo]"

Résultat :

showspectrum

Commande utilisée :

mpv t\ r\ y\ Δ\ d\ -\ mesmerize.mp3 --lavfi-complex="[aid1]asplit[ao][a];[a]showspectrum=s=720x720:mode=separate:color=plasma[vecOut];[vecOut]pad=1280:720:(ow-iw)/2:(oh-ih)/2[padOut];[vid1]colorspace=smpte240m:format=yuv420p[vidc];[vidc]scale=-2:720[vidScale];[vidScale]pad=1280:720:(ow-iw)/2:(oh-ih)/2[vpoc];[vpoc][padOut]blend=shortest=0:all_mode=overlay:all_opacity=1[vo]"

Résultat :

showvolume

Commande utilisée :

mpv t\ r\ y\ Δ\ d\ -\ mesmerize.mp3 --lavfi-complex="[aid1]asplit[ao][a];[a]showvolume=r=60[vecOut];[vecOut]pad=1280:720:(ow-iw)/2:(oh-ih)/2[padOut];[vid1]colorspace=smpte240m:format=yuv420p[vidc];[vidc]scale=-2:720[vidScale];[vidScale]pad=1280:720:(ow-iw)/2:(oh-ih)/2[vpoc];[vpoc][padOut]blend=shortest=0:all_mode=overlay:all_opacity=1[vo]"

Résultat :

showvolume (variante)

Commande utilisée :

mpv t\ r\ y\ Δ\ d\ -\ mesmerize.mp3 --lavfi-complex="[aid1]asplit[ao][a];[a]showvolume=r=60:w=720:h=300[vecOut];[vecOut]pad=1280:720:(ow-iw)/2:(oh-ih)/2[padOut];[vid1]colorspace=smpte240m:format=yuv420p[vidc];[vidc]scale=-2:720[vidScale];[vidScale]pad=1280:720:(ow-iw)/2:(oh-ih)/2[vpoc];[vpoc][padOut]blend=shortest=0:all_mode=overlay:all_opacity=1[vo]"

Résultat :

showwaves

Commande utilisée :

mpv t\ r\ y\ Δ\ d\ -\ mesmerize.mp3 --lavfi-complex="[aid1]asplit[ao][a];[a]showwaves=s=720x720:mode=line[vecOut];[vecOut]pad=1280:720:(ow-iw)/2:(oh-ih)/2[padOut];[vid1]colorspace=smpte240m:format=yuv420p[vidc];[vidc]scale=-2:720[vidScale];[vidScale]pad=1280:720:(ow-iw)/2:(oh-ih)/2[vpoc];[vpoc][padOut]blend=shortest=0:all_mode=overlay:all_opacity=1[vo]"

Résultat :

EBU R128

Pourquoi le traiter à part ? Parce que ce filtre sort non seulement de l’audio mais aussi de la vidéo.

EBU R128 simple

Commande utilisée :

mpv t\ r\ y\ Δ\ d\ -\ mesmerize.mp3 --lavfi-complex="[aid1]ebur128=video=1:meter=18 [vo][ao]"

Résultat :

EBU R128 avec une pochette

Commande utilisée :

mpv t\ r\ y\ Δ\ d\ -\ mesmerize.mp3 --lavfi-complex="[aid1]ebur128=video=1:meter=18[ebu1][ao];[ebu1]pad=640:480:(ow-iw)/2:(oh-ih)/2[padOut];[vid1]colorspace=smpte240m:format=yuv420p[vidc];[vidc]scale=-2:480[vidScale];[vidScale]pad=640:480:(ow-iw)/2:(oh-ih)/2[vpoc];[padOut][vpoc]blend=shortest=0:all_mode=overlay:all_opacity=0.3[vo]"

Résultat :

Afficher un synthé

Sérieusement ? O_O ; avec une barre transparente, un logo et du texte sur deux lignes ? Et ne l’afficher qu’au début de la vidéo, pendant 15 secondes, puis l’afficher 15 secondes avant la fin de la vidéo (il faut alors connaître la durée avant d’exécuter la commande). Ici, la vidéo durant 2 minutes et 50 secondes, ce qui fait 170 secondes.

Commande utilisée :

mpv FRE\ Bernard\ Minet\ -\ MV\ -\ Dragon\ Ball\ et\ Dragon\ Ball\ Z.mp4 --lavfi-complex="movie='synthe.png'[logo];[logo]drawtext=text='Bernard Minet - Dragon Ball et Dragon Ball Z':fontsize=40:fontcolor=white:shadowx=3:shadowy=3:x=130:y=10,drawtext=text='Demandé par alex':fontsize=40:fontcolor=white:shadowx=3:shadowy=3:x=130:y=60[synthe];[vid1][synthe]overlay=x='if(between(t,0,15)+(between(t,155,170)),0,NAN)':y=950[vo]"
Exemple de synthé

Bon, alors là, c’est un peu compliqué. Je pars d’une image de base pour le synthé. L’image est au format PNG, avec un canal alpha (transparence).

Image de base pour le synthé

En utilisant cette image comme source vidéo, j’ajoute du texte via le filtre drawtext, en blanc (white), avec une ombre noire (par défaut), décalée de 3 pixels par rapport au texte d’origine. Le texte de la première ligne commence aux coordonnées x=130:y=10 (coordonnées par rapport à l’image de base du synthé et non par rapport à la vidéo). Le texte de la seconde ligne commence aux coordonnées x=130:y=60 (idem, par rapport à l’image de base).

Note

Pourquoi x=130 ? Pour tenir compte du logo présent sur le synthé.

Avec une image plus haute et en jouant avec la taille du texte (ici, en taille 40), on pourrait afficher une troisième ligne.

La sortie de ce filtre (image de base + texte) est utilisée avec le filtre overlay pour le superposer avec la vidéo d’origine. Revoir la section « Affichage complexe » pour les informations sur l’utilisation des intervalles (between).

Avertissement

Le formatage du texte (gras, italique, souligné) n’est pas faisable de manière simple.