Comment puis-je exécuter la ligne de commande FFMPEG et accepter plusieurs canaux (vidéo et audio) sans bloquer la première entrée?

J’essaie de mux h264 et aac créés avec MediaCodec en utilisant FFMPEG, et aussi d’utiliser le support RTMP de FFMPEG pour envoyer sur youtube. J’ai créé deux tubes et j’écris depuis java (Android) via WriteableByteChannels. Je peux envoyer à un tuyau juste bien (acceptant un son nul) comme ceci:

./ffmpeg -f lavfi -i aevalsrc=0 -i "files/camera-test.h264" -acodec aac -vcodec copy -bufsize 512k -f flv "rtmp://a.rtmp.youtube.com/live2/XXXX" 

Le streaming sur YouTube fonctionne parfaitement (mais je n’ai pas de son). En utilisant deux pipes, c’est ma commande:

 ./ffmpeg \ -i "files/camera-test.h264" \ -i "files/audio-test.aac" \ -vcodec copy \ -acodec copy \ -map 0:v:0 -map 1:a:0 \ -f flv "rtmp://a.rtmp.youtube.com/live2/XXXX"" 

Les tubes sont créés avec mkfifo et ouverts depuis java comme ceci:

 pipeWriterVideo = Channels.newChannel(new FileOutputStream(outputFileVideo.toSsortingng())); 

L’ordre d’exécution (pour l’instant dans ma phase de test) est la création des fichiers, en démarrant ffmpeg (via le shell adb), puis en démarrant l’enregistrement qui ouvre les canaux. ffmpeg ouvrira immédiatement le stream h264 et attendra, puisqu’il lit depuis le canal le premier canal ouvert (pour la vidéo) qui s’exécutera avec succès. Quand il s’agit d’essayer d’ouvrir le son de la même manière, il échoue car ffmpeg n’a pas réellement commencé à lire le tube. Je peux ouvrir une seconde fenêtre de terminal et chatter le fichier audio et mon application crache ce que j’espère être encodé aac, mais ffmpeg échoue, généralement juste en attente. Voici la sortie verbeuse:

 ffmpeg version N-78385-g855d9d2 Copyright (c) 2000-2016 the FFmpeg developers built with gcc 4.8 (GCC) configuration: --prefix=/home/dev/svn/android-ffmpeg-with-rtmp/src/ffmpeg/android/arm --enable-shared --disable-static --disable-doc --disable-ffplay --disable-ffprobe --disable-ffserver --disable-symver --cross-prefix=/home/dev/dev/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi- --target-os=linux --arch=arm --enable-cross-comstack --enable-librtmp --enable-pic --enable-decoder=h264 --sysroot=/home/dev/dev/android-ndk-r10e/platforms/android-19/arch-arm --extra-cflags='-Os -fpic -marm' --extra-ldflags='-L/home/dev/svn/android-ffmpeg-with-rtmp/src/openssl-android/libs/armeabi ' --extra-ldexeflags=-pie --pkg-config=/usr/bin/pkg-config libavutil 55. 17.100 / 55. 17.100 libavcodec 57. 24.102 / 57. 24.102 libavformat 57. 25.100 / 57. 25.100 libavdevice 57. 0.101 / 57. 0.101 libavfilter 6. 31.100 / 6. 31.100 libswscale 4. 0.100 / 4. 0.100 libswresample 2. 0.101 / 2. 0.101 matched as AVOption 'debug' with argument 'verbose'. Trailing options were found on the commandline. Finished splitting the commandline. Parsing a group of options: global . Applying option async (audio sync method) with argument 1. Successfully parsed a group of options. Parsing a group of options: input file files/camera-test.h264. Successfully parsed a group of options. Opening an input file: files/camera-test.h264. [file @ 0xb503b100] Setting default whitelist 'file' 

Je pense que si je pouvais juste faire en sorte que ffmpeg commence à écouter les deux tubes, le rest marcherait!

Merci pour votre temps.

EDIT: J’ai fait des progrès en découplant la connexion et le codage du tube audio, mais maintenant, dès que le stream vidéo a été passé, des erreurs se sont produites sur le son. J’ai lancé un thread séparé pour créer le WriteableByteChannel pour l’audio et la création de FileOutputStream n’est jamais transmise.

 matched as AVOption 'debug' with argument 'verbose'. Trailing options were found on the commandline. Finished splitting the commandline. Parsing a group of options: global . Successfully parsed a group of options. Parsing a group of options: input file files/camera-test.h264. Successfully parsed a group of options. Opening an input file: files/camera-test.h264. [file @ 0xb503b100] Setting default whitelist 'file' [h264 @ 0xb503c400] Format h264 probed with size=2048 and score=51 [h264 @ 0xb503c400] Before avformat_find_stream_info() pos: 0 bytes read:15719 seeks:0 [h264 @ 0xb5027400] Current profile doesn't provide more RBSP data in PPS, skipping [h264 @ 0xb503c400] max_analyze_duration 5000000 reached at 5000000 microseconds st:0 [h264 @ 0xb503c400] After avformat_find_stream_info() pos: 545242 bytes read:546928 seeks:0 frames:127 Input #0, h264, from 'files/camera-test.h264': Duration: N/A, bitrate: N/A Stream #0:0, 127, 1/1200000: Video: h264 (Baseline), 1 reference frame, yuv420p(left), 854x480 (864x480), 1/50, 25 fps, 25 tbr, 1200k tbn, 50 tbc Successfully opened the file. Parsing a group of options: input file files/audio-test.aac. Applying option vcodec (force video codec ('copy' to copy stream)) with argument copy. Successfully parsed a group of options. Opening an input file: files/audio-test.aac. Unknown decoder 'copy' [AVIOContext @ 0xb5054020] Statistics: 546928 bytes read, 0 seeks 

Voici où je tente d’ouvrir le tuyau audio.

 new Thread(){ public void run(){ Log.d("Audio", "pre thread"); FileOutputStream fs = null; try { fs = new FileOutputStream("/data/data/android.com.android.grafika/files/audio-test.aac"); } catch (FileNotFoundException e) { e.printStackTrace(); } Log.d("Audio", "made fileoutputstream"); //never hits here mVideoEncoder.pipeWriterAudio = Channels.newChannel(fs); Log.d("Audio", "made it past opening audio pipe"); } }.start(); 

Merci.

Votre explication n’est pas très claire, je peux voir que vous essayez d’expliquer exactement ce que vous faites, mais cela ne fonctionne pas.

Premièrement: pouvez-vous décrire le problème réel ? Je dois lire jusqu’à mi-parcours dans un paragraphe de huit lignes et on dirait que vous suggérez que ffmpeg est suspendu . Est-ce le problème? Vous voulez vraiment être explicite à ce sujet.

Deuxièmement: comment transférer les données dans les FIFO? Cela compte. Votre message n’est pas clair du tout, vous semblez suggérer que ffmpeg lit tout un fichier vidéo et passe ensuite à l’audio. Est-ce exact? Ou les deux stream sont-ils envoyés à ffmpeg simultanément?

Enfin: si ffmpeg se bloque, c’est probablement parce que l’un de vos canaux d’entrée bloque (vous envoyez des données au FIFO-1 et le tampon est plein, mais ffmpeg veut des données du FIFO-2 et le tampon est vide). Les deux FIFO doivent toujours être remplis de manière indépendante avec des données.