Passer au contenu principal

Blog de Guillaume Seznec

Une mosaïque de vidéos avec ffmpeg

Aujourd’hui,étudions un script permettant de prendre 4 sources vidéos 16:9, de générer une composition mosaïque 2x2, et de la streamer.

ffmpeg permet beaucoup de chose et notamment la possibilité de créer des compositions avec les filtres complexes.

But du projet

  • 4 vidéos sources, qui peuvent être des fichiers statiques locaux, mais aussi un flux de notre webcam ou bien des flux réseaux. La limitation étant la faculté à ffmpeg de les ingérer. Ces 4 vidéos devront avoir le même format, au moins le même ratio (ex: 16/9).
  • On va les positionner sous forme de mosaïque de 2 lignes et 2 colonnes
  • Nous couperons le son sur la vidéo finale

Le script final

#!/usr/bin/env bash
# Génération d'une mosaïque muette 2x2 de vidéos
# et la streame en udp localement, avec des paquets de 1316 octets
# on considère que les vidéos source sont au même format

# vidéo haut gauche
INPUT_TL="rtmp://rtmp.example.com/live/cam1"
# vidéo haut droit
INPUT_TR="rtmp://rtmp.example.com/live/cam1"
# vidéo bas gauche
INPUT_BL="/home/gus/videos/videoA.mp4"
# vidéo bas droit
INPUT_BR="/home/gus/videos/videoB.mp4"

# taille du flux de sortie
OUTPUT_WIDTH=1280
OUTPUT_HEIGHT=720
# url du flux de sortie
OUTPUT_URL=udp://127.0.0.1:1234?pkt_size=1316

MOSA_WIDTH=$(($OUTPUT_WIDTH / 2))
MOSA_HEIGHT=$(($OUTPUT_HEIGHT / 2))

ffmpeg \
  -re \
  -i "$INPUT_TL" \
  -i "$INPUT_TR" \
  -i "$INPUT_BL" \
  -i "$INPUT_BR" \
  -filter_complex " \
    nullsrc=size="$OUTPUT_WIDTH"x"$OUTPUT_HEIGHT" [base]; \
    [0:v] setpts=PTS-STARTPTS, scale="$MOSA_WIDTH"x"$MOSA_HEIGHT" [upperleft]; \
    [1:v] setpts=PTS-STARTPTS, scale="$MOSA_WIDTH"x"$MOSA_HEIGHT" [upperright]; \
    [2:v] setpts=PTS-STARTPTS, scale="$MOSA_WIDTH"x"$MOSA_HEIGHT" [lowerleft]; \
    [3:v] setpts=PTS-STARTPTS, scale="$MOSA_WIDTH"x"$MOSA_HEIGHT" [lowerright]; \
    [base][upperleft] overlay=shortest=1 [tmp1]; \
    [tmp1][upperright] overlay=shortest=1:x="$MOSA_WIDTH" [tmp2]; \
    [tmp2][lowerleft] overlay=shortest=1:y="$MOSA_HEIGHT" [tmp3]; \
    [tmp3][lowerright] overlay=shortest=1:x="$MOSA_WIDTH":y="$MOSA_HEIGHT" \
  " \
  -c:v libx264 -b:v 2500k \
  -an \
  -f mpegts "$OUTPUT_URL"

Lecture

Dans VLC, saisissez l’url udp://@127.0.0.1:1324

Problèmes connus

Si un des flux source s’interrompt (ex dans le cas d’un flux réseau), le flux final est coupé, la lecture est donc coupée pour le téléspectateur aussi. Trouver un moyen d'être plus résiliant.