web-dev-qa-db-fra.com

HTTP Live Streaming: Le cauchemar de Linux

Je travaille sur une application de musique à la demande sur un iPhone et, conformément aux directives d'Apple, je dois exécuter un flux en direct HTTP pour pouvoir être accepté sur l'AppStore. Mais comme Apple ne s’occupe pas de 98% des serveurs sur la planète, ils ne fournissent pas leurs outils de diffusion en direct HTTP si magiques pour les systèmes Linux. Et à partir de ce moment, le cauchemar commence.

Mon objectif est simple: prendre un MP3, le segmenter et générer un simple fichier d'index .m3u8 . J'ai cherché dans Google "HTTP Live Streaming Linux" et "Oh, génial! Beaucoup de gens l'ont déjà fait"!

Tout d’abord, j’ai visité le post (si célèbre) de Carson McDonald .. Résultat: le svn segmentate.c était vieux, un buggy et un cauchemar à compiler (Personne dans ce monde ne peut préciser quelle version de ffmpeg ils sont. en utilisant!) . Ensuite, je suis tombé sur le dépôt Git de Carson , mais tant pis, il y a beaucoup de choses énervantes sur Ruby et live_segmenter.c ne peut pas prendre de fichiers mp3.

Puis j'ai cherché plus profondément. J'ai trouvé ce sujet stackoverflow , et c'est exactement ce que je veux faire. J'ai donc suivi le conseil de juuni d'utiliser ce script (httpsegmenter) . Résultat: Impossible de compiler quoi que ce soit, 2 jours de travail et finalement j'ai réussi à le compiler (ffmpeg 8.1 avec httpsegmenter rev17). Et non, ce n'est pas un bon script, il prend des fichiers mp3, mais les fichiers ts générés et le fichier d'index ne peuvent pas être lus par un lecteur.

Ensuite, l'auteur du message, krisbulman, est venu avec une solution et a même donné une version patchée de m3u8-segmenter par lui-même ( git repo ). Je le teste: ne compile pas, ne fait rien. J'ai donc pris la version originale de johnf https://github.com/johnf/m3u8-se augmenter . J'ai réussi à compiler et miracle cela fonctionne (pas vraiment). J'ai utilisé cette ligne de commande (ffmpeg 0.8.1):

ffmpeg -er 4 -i music.mp3 -f mpegts -acodec libmp3lame -ar 44100 -ab 128k -vn - | m3u8-segmenter -i - -d 10 -p outputdir/prefix -m outputdir/output.m3u8 -u http://test.com/

Ce script encode mon fichier mp3 (cela prend 4 secondes, trop longtemps) et le passe au m3u8-segmenter pour le segmenter en fichiers .TS de 10 secondes.

J'ai testé ce flux avec mediastreamvalidator d'Apple sur mon mac, et il a dit que tout allait bien. Donc, je l'ai joué dans quicktime, mais il y a environ 0,2 seconde vierge entre chaque fichier .TS !!

Voici donc ma situation, c'est un cauchemar, je ne peux pas obtenir un simple flux MP3 via le protocole HLS. Existe-t-il une solution WORKING simple pour segmenter un mp3? Pourquoi ne puis-je pas segmenter directement le fichier mp3 en plusieurs fichiers MP3 comme le fait le médiafilese augmenter d'Apple?

21
Ethan0026

Utilisez libfaac dans l'insteam de libmp3lame qui élimine la pause de 0,2 seconde.

5
vchola

Elastic Transcoder Service - si vous n'avez pas besoin du cryptage AES, envoyez simplement votre MP3 dans un compartiment S3 et terminez-le: 

http://aws.Amazon.com/elastictranscoder/

Vous pouvez ensuite même ajouter le support Cloudfront CDN. (P.S. J'apprécie pleinement votre douleur, tout cet espace est un cauchemar). 

4
Francis Shanahan

Pour la diffusion en direct uniquement, vous devriez essayer Nginx avec le module RTMP pour celui-ci. https://github.com/arut/nginx-rtmp-module Le HLS en direct fonctionne plutôt bien, mais avec une mémoire tampon looooong . Cependant, il ne prend pas en charge le streaming HLS sur demande. 

Morceau de configuration du module par exemple 

# HLS requires libavformat & should be configured as a separate
# NGINX module in addition to nginx-rtmp-module:
# ./configure ... --add-module=/path/to/nginx-rtmp-module/hls ...
# For HLS to work please create a directory in tmpfs (/tmp/app here)
# for the fragments. The directory contents is served via HTTP (see
# http{} section in config)
#
# Incoming stream must be in H264/AAC/MP3. For iPhones use baseline H264
# profile (see ffmpeg example).
# This example creates RTMP stream from movie ready for HLS:
#
# ffmpeg -loglevel verbose -re -i movie.avi  -vcodec libx264 
#    -vprofile baseline -acodec libmp3lame -ar 44100 -ac 1 
#    -f flv rtmp://localhost:1935/hls/movie
#
# If you need to transcode live stream use 'exec' feature.
#
application hls {
    live on;
    hls on;
    hls_path /tmp/app;
    hls_fragment 5s;
}
2
kubanoid

Quels problèmes aviez-vous avec httpsegmenter? C'est un fichier source C unique qui ne lie que certaines bibliothèques fournies par ffmpeg (ou libav). Je maintiens un ebuild Gentoo pour celui-ci, car je l'utilise pour chronométrer une radio de conversation. Si vous utilisez Gentoo, la construction est aussi simple que cela:

Sudo bash -l
layman -S
layman -a salfter
echo media-video/httpsegmenter ~\* >>/etc/portage/package.accept_keywords
emerge httpsegmenter
exit

Sur Ubuntu, je devais m'assurer que libavutil-dev et libavformat-dev étaient tous les deux installés, afin que la construction ressemble à ceci:

Sudo apt-get install libavutil-dev libavformat-dev
git clone https://gitlab.com/salfter/httpsegmenter.git
cd httpsegmenter
make -f Makefile.txt
Sudo make -f Makefile.txt install

Une fois qu'il est construit (et une fois que j'ai une URL de source audio), l'utilisation est assez simple: utilisez curl pour diffuser l'audio, ffmpeg pour le transcoder de ce qu'il est à la source (souvent au format MP3) en AAC et segmenteur pour le décomposer:

curl -m 3600 http://invalid.tld/stream | \
ffmpeg -i - -acodec libvo_aacenc -ac 1 -ab 32k -f mpegts - 2>/dev/null | \
segmenter -i - -d 20 -o ExampleStream -x ExampleStream.m3u8 2>/dev/null

Cela prend une heure de streaming audio (MP3 ou AAC, pas Flash), le convertit au format AAC mono à 32 kbps et le réduit au streaming HTTP en direct. Faites-le vider dans un répertoire servi par votre serveur Web et vous êtes prêt à partir.

Une fois l'émission terminée, la conversion en un seul fichier .m4a pouvant être diffusé en podcast est également simple:

cat `ls -rt ExampleStream-*.ts` | \
ffmpeg -i - -acodec copy -absf aac_adtstoasc ExampleStream.m4a 2>/dev/null
1
salfter

Je sais que c’est une vieille question, mais j’utilise cela dans VLC:

## To start playing the playlist out to the encoder
cvlc -vvv playlist.m3u --sout rtp:127.0.0.1 --ttl 2

## To start the encoder
cvlc rtp://  --sout='#transcode{acodec=mp3,ab=96}:duplicate{dst=std{access=livehttp{seglen=10,splitanywhere=true,delsegs=true,numsegs=15,index=/var/www/vlctest/mystream.m3u8,index-url=http://IPANDPORT/vlctest/mystream-########.ts},mux=ts,dst=/var/www/vlctest/mystream-########.ts},select=audio}'

J'avais des problèmes si je ne transmettais pas le fichier de playlist à une autre copie de VLC, la première étape est facultative si vous avez déjà une source de diffusion en direct. (mais vous pouvez utiliser n’importe quelle source pour la partie "encodeur").

0
jeremy

Vous pouvez essayer d'utiliser nos services de médias sur la plateforme Windows Azure: http://mingfeiy.com/how-to-generate-http-live-streaming-hls-content-using-windows-Azure-media-services/

Vous pouvez encoder et diffuser votre vidéo au format HLS en utilisant notre portail, sans configuration ni codage requis. 

0
Mingfei Yan

Ton anglais est bon.

Votre frustration est apparente.

Q: Quel est le vrai problème ici? On dirait que vous avez juste besoin d'un serveur HLS en état de marche, n'est-ce pas? En raison des exigences d'Apple, correct?

Pouvez-vous utiliser n'importe laquelle des implémentations toutes faites énumérées ici:

0
paulsm4