streamer en RTMP avec ffmpeg

Il y a pas longtemps, j’ai découvert qu’on pouvait se servir de ffmpeg comme encodeur Flash, pour pousser en utilisant le protocole propriétaire d’Adobe (le RTMP). J’ai testé ça avec un serveur Wowza comme cible (c’est pratique dès fois de bosser dans une boîte qui fait du streaming).

Ça se passe donc comme ça:

ffmpeg -i $src <mes options> -f flv rtmp://mon_serveur_flash/mon_appli_flash/mon_flux
  • <mes options> : c’est détaillé  ;
  • -f flv : on prend un container Flash Video pour pousser du Flash (c’est plutôt logique :-)) ;
  • la destination: au lieu d’un fichier ou d’une spec de flux rtp (par exemple), on spécifie une URL en rtmp:// avec les infos qui sont normalement fournies par votre fournisseur (en général: un hostname, un nom d’«application» – c’est la partie du serveur Flash qui est dédiée à un client –), et un nom de flux que l’on choisit comme on veut (en respectant la règle habituelle: pas d’accents, pas d’espaces, pas de caractères bizarroïdes).

Si on a la bande passante pour, et que l’on veut pousser sur plusieurs serveur, on peut multiplier les <mes options> et les URLs de destinations:

ffmpeg -i $src <mes options> -f flv rtmp://serveur1/mon_appli/mon_flux <mes options> -f flv rtmp://serveur2/mon_appli/mon_flux [...]

On peut aussi pousser sur un ou plusieurs serveurs plusieurs versions du flux $src (pour avoir plusieurs débits quand on veut faire Apple HTTP Live Streaming ou du Adobe HTTP Dynamic Streaming). On peut s’aider de la cochonnerie que j’ai publiée sur commandelinefu pour un flux RTP 🙂

streamer du h264/aac en RTP avec ffmpeg

La version simple:

ffmpeg [source specification if needed] -i $src -an $mes_options_vidéo -f rtp rtp://$dstIP:$dstVideoPort -vn $mes_options_audio(aac) -async 2 -flags +global_header  -f rtp rtp://$dstIP:$dstAudioPort

Pour $mes_options* voir ici

$src peut-être n’importe quelle source reconnue par ffmpeg (un fichier, un flux audio/vidéo repompé quelque part)…

$dstIP est l’IP du client RTP qui aura besoin de savoir sur quels ports UDP il devra écouter pour la composante audio ($dstAudioPort) et pour la composante vidéo ($dstVideoPort).

Dans la sortie de ffmpeg, on trouvera aussi le nécessaire pour faire un beau fichier sdp.

J’avais publié une version crade de ce truc sur commandlinefu.

 

transcodage h264/aac – h264/mp3 avec ffmpeg/x264

Je fais ça comme ça (je détaille pas, le man est là pour ça):

  • $mes_options_audio (stéréo, 128kb/s, 48kHz):
    • aac:
-acodec libfaac -ac 2 -ar 48000 -ab 128000
    • mp3:
-acodec libmp3lame -ac 2 -ar 48000 -ab 128000
  • $mes_options_vidéo (1024kb/s, 1280×720 – 16:9, baseline 3.0, ~24fps):

Celles-ci sont optimisées pour iPhone et autre cochonneries vendues par Apple:

-vcodec libx264 -threads 0 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -subq 5 -trellis 1 -refs 1 -coder 1 -me_range 16 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 21 -qmax 25 -vprofile baseline -level 30 -g 23.98 -crf 25 -async 2 -s 1280x720 -aspect 16:9 -r 23.98 -b:v 1024000 -vb 1024000 -minrate 972800 -maxrate 1075200 -bt 51200 -bufsize 1209600 -muxrate 1075200

Là, on fait presque du cbr (c’est un peu con, mais Apple l’impose pour ses jouets): «presque» parce qu’il y a une tolérance de 5% sur le débit demandé (voir -minrate/-maxrate par rapport à -vb ou -b:v.

En dehors du cas particulier Apple, on peut tout à fait augmenter cette tolérance, et passer -qmin à 1 et -qmax à 51. On peut aussi jouer avec l’option -crf et ajouter un -mixed_refs 1.

Quelques détails utiles:

    • -bt : 5% de (-vb + -ab)
    • -bufsize: (-vb + -ab) * 1000
    • -muxrate: -bufsize + -bt
  • $mon_container peut prendre n’importe laquelle de ces valeurs:
    • mp4 (penser à passer par un fichier temporaire et à utiliser qt-faststart ensuite si vous voulez diffuser ce fichier sur Internet: ça évitera de devoir télécharger toute la vidéo avant de pouvoir la lire) ;
    • mpegts ;
    • flv (flash).

Utilisation:

ffmpeg -i ma_source $mes_options_vidéo $mes_options_audio -f $mon_container mon_fichier_transcodé

Dans le cas d’un fichier mp4 que je veux diffuser sur Internet, je fais plutôt comme ça:

ffmpeg -i ma_source $mes_options_vidéo $mes_options_audio -f mp4 fichier_temporaire
qt-faststart fichier_temporaire mon_fichier_transcodé
rm -f fichier_temporaire