web-dev-qa-db-fra.com

Utilisation de FFMPEG pour diffuser en continu des fichiers vidéo sur un serveur RTMP

ffmpeg gère le streaming RTMP en entrée ou en sortie, et cela fonctionne bien.

Je souhaite diffuser des vidéos (une liste de lecture dynamique gérée par un script python) sur un serveur RTMP, et je fais actuellement quelque chose de très simple: diffuser mes vidéos une par une avec FFMPEG sur le serveur RTMP, ce qui entraîne toutefois une rupture de connexion. chaque fois qu'une vidéo se termine et que le flux est prêt à commencer lorsque la vidéo suivante commence.

Je souhaite diffuser ces vidéos en continu, sans interruption de la connexion, afin que le flux puisse être correctement visualisé.

J'utilise cette commande pour diffuser mes vidéos une par une sur le serveur.

ffmpeg -re -y -i myvideo.mp4 -vcodec libx264 -b:v 600k -r 25 -s 640x360 \
-filter:v yadif -ab 64k -ac 1 -ar 44100 -f flv \
"rtmp://mystreamingserver/app/streamName"

J'ai cherché des solutions de contournement sur Internet pendant plusieurs jours, et j'ai trouvé certaines personnes qui parlaient d'utiliser un canal nommé comme entrée dans ffmpeg, je l'ai essayé et cela n'a pas bien fonctionné puisque ffmpeg ne ferme pas seulement le flux RTMP lorsque une nouvelle vidéo vient mais se ferme elle aussi.

Y a-t-il un moyen de faire ça ? (Diffusez une liste de lecture dynamique de vidéos avec ffmpeg sur un serveur RTMP sans interruption de la connexion

21
kketch

Update (car je ne peux pas supprimer la réponse acceptée): la solution appropriée consiste à implémenter un démultiplexeur personnalisé, similaire à celui de concat. Il n'y a actuellement pas d'autre moyen propre. Vous devez vous salir les mains et coder!

Ci-dessous est un bidouillage laid. C'est une très mauvaise façon de le faire, mais ne le faites pas!

La solution utilise le démultiplicateur concat et suppose que tous vos fichiers multimédias sources utilisent le même codec. L'exemple est basé sur MPEG-TS mais la même chose peut être faite pour RTMP.

  1. Créez un fichier de liste de lecture contenant une liste énorme de points d’entrée pour votre liste de lecture dynamique au format suivant:

    file 'item_1.ts' file 'item_2.ts' file 'item_3.ts' [...] file 'item_[ENOUGH_FOR_A_LIFETIME].ts'

    Ces fichiers ne sont que des espaces réservés.

  2. Créez un script qui garde la trace de votre index de playlist actuel et crée des liens symboliques à la volée pour current_index + 1

    ln -s /path/to/what/to/play/next.ts item_1.ts

    ln -s /path/to/what/to/play/next.ts item_2.ts

    ln -s /path/to/what/to/play/next.ts item_3.ts

    [...]

  3. Commencer à jouer ffmpeg -f concat -i playlist.txt -c copy output -f mpegts udp://<ip>:<port>

  4. Faites-vous poursuivre et appeler des noms par un administrateur système en colère

5
aergistal

Vous pouvez diriger votre boucle vers un tampon, puis depuis ce tampon vers votre instance de diffusion en continu.

Dans Shell, cela ressemblerait à:

#!/bin/bash

for i in *.mp4; do
       ffmpeg -hide_banner -nostats -i "$i" -c:v mpeg2video [proper settings] -f mpegts -
done | mbuffer -q -c -m 20000k | ffmpeg -hide_banner -nostats -re -fflags +igndts -thread_queue_size 512 -i pipe:0 -fflags +genpts [proper codec setting] -f flv rtmp://127.0.0.1/live/stream

Bien sûr, vous pouvez utiliser n’importe quel type de boucle, y compris une liste de lecture. 

  • Je me rends compte que MPEG est un peu plus stable, puis x264 pour le flux d'entrée
  • Je ne sais pas pourquoi, mais un minimum de 2 threads pour la compression MPEG fonctionne mieux
  • la compression en entrée doit être plus rapide que la cadence de sortie, nous obtenons donc assez rapidement de nouvelles entrées
  • En raison de l'horodatage non continu, nous devons les ignorer et en générer un nouveau dans la sortie
  • La taille de la mémoire tampon doit être suffisamment grande pour que la boucle ait suffisamment de temps pour obtenir le nouveau clip.

Je travaille sur une solution basée sur Python, elle n’est pas encore complète, mais à part quelques avertissements, mon flux de test dure plusieurs jours:

ffplayout

Cela utilise un format de liste de lecture XML. Et la liste de lecture est dynamique, de sorte que vous pouvez toujours modifier la liste de lecture actuelle et changer de piste ou en ajouter de nouvelles.

1
jb_alvarado

Vous devez créer deux fichiers de liste de lecture et spécifier un lien vers un autre fichier à la fin de chaque fichier.

list_1.txt

ffconcat version 1.0
file 'item_1.mp4'
file 'list_2.txt'

list_2.txt

ffconcat version 1.0
file 'item_2.mp4'
file 'list_1.txt'

Il ne vous reste plus qu'à modifier dynamiquement le contenu du fichier de liste de lecture suivant.

0
bnku