2016-02-17 19 views
6

Próbuję Mux h264 i AAC utworzone za pomocą MediaCodec za pomocą FFMPEG, a także używać FMPMPEG RTMP do wysyłania do youtube. Stworzyłem dwie fajki i piszę z java (android) poprzez WriteableByteChannels. Mogę wysłać do jednej rury w porządku (przyjmującej zerowej audio) tak:Jak uruchomić wiersz poleceń FFMPEG i akceptować wiele potoków (wideo i audio) bez blokowania na pierwszym wejściu?

./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" 

YouTube Streaming działa perfekcyjnie (ale nie mam dźwięku). Korzystanie z dwóch rur to moje polecenie:

./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"" 

Rury są tworzone z mkfifo i otwarte od Java tak:

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

Kolejność realizacji (do tej pory w moim fazie testów) jest stworzenie plików, uruchamianie ffmpeg (poprzez powłokę adb), a następnie uruchamianie nagrywania, które otwiera kanały. ffmpeg natychmiast otworzy strumień h264, a następnie poczeka, ponieważ odczytuje z potoku pierwszy otwarty kanał (dla wideo). Jeśli chodzi o próbę otwarcia audio w ten sam sposób, to się nie powiedzie, ponieważ ffmpeg nie rozpoczął odczytu z potoku. Mogę otworzyć drugie okno terminala i umieścić w nim plik audio, a moja aplikacja wypluwa to, co mam nadzieję, jest zakodowane w formacie AAC, ale ffmpeg nie działa, zwykle po prostu czekając. Oto pełne wyjście:

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-compile 
    --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' 

Myślę, że gdybym mógł po prostu dostać ffmpeg, aby zacząć słuchać obu rur, reszta by się udała!

Dzięki za poświęcony czas.

EDYTOWANIE: Dokonałem postępu poprzez oddzielenie połączenia i kodowania przewodów audio, ale teraz, gdy tylko strumień wideo został przekazany, wystąpiły błędy w dźwięku. Rozpocząłem osobny wątek, aby utworzyć WriteableByteChannel dla dźwięku i nigdy nie zostanie on przekazany do utworzenia FileOutputStream.

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 

Oto gdzie próbuję otworzyć rurę 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(); 

Dzięki.

+0

Czy należy sparować '-acodec ... -i filename -vcodec -i filename'? . Również w wynikach gadatliwych można zawijać linię konfiguracyjną według '--option', bardzo trudną do odczytania. Powodzenia. – shellter

+0

Nie sądzę, widziałem wiele przykładów z flagami kodek na końcu. Po prostu spróbowałem i otrzymałem ten sam wynik. Zastanawiam się, czy muszę spróbować strumieniować kanały audio i wideo całkowicie niezależnie (może, jeśli aktywny strumień wideo jest obecny w pierwszej rurze, przejdzie do drugiego?). Spróbuję zaadaptować mój kod do tego. – Version135b

+0

Ponieważ nie miałeś żadnych prawdziwych odpowiedzi, szukałbym stron internetowych, które są bardziej specyficzne dla przetwarzania dźwięku lub nawet specyficznego dla ffmpeg. Jestem pewien, że istnieje "oficjalne" forum ffmpeg, na którym możesz uzyskać ostateczną odpowiedź. Dziękuję za edycję. Powodzenia! – shellter

Odpowiedz

4

Twoje wyjaśnienie nie jest bardzo jasne, widzę, że próbujesz dokładnie wyjaśnić, co robisz, ale to nie działa.

Po pierwsze: czy możesz opisać aktualny numer . Muszę przeczytać do połowy wpisu w akapicie 8-liniowym i wygląda na to, że sugerujesz, że ffmpeg to wisi. Czy to jest problem? Naprawdę chcesz o tym powiedzieć otwarcie.

Po drugie: w jaki sposób dane są przesyłane do FIFO? To się liczy. Twój wpis jest całkowicie niejasny, sugerujesz, że ffmpeg czyta cały plik wideo, a następnie przechodzi do dźwięku. Czy to jest poprawne? Czy oba strumienie są podawane jednocześnie do ffmpeg?

Na koniec: jeśli ffmpeg się zawiesza, najprawdopodobniej blokuje jeden z twoich przewodów wejściowych (przesyłasz dane do FIFO-1, a bufor jest pełny, ale ffmpeg chce danych z FIFO-2, a bufor jest pusty) . Oba FIFO muszą zawsze być niezależnie wypełniane danymi.

+0

Dzięki za opinie, przepraszam za to, że byłem niejasny. Myślę, że mam dwie kwestie, ale prawdopodobnie są ze sobą powiązane. 1: Nie mogę otworzyć audio FIFO, 2: ffmpeg zwleka z oglądaniem wideo FIFO. Proces jest (był) uruchomienie ffmpeg za pomocą powyższego polecenia, a następnie otwórz FIFO do pisania (najpierw wideo, potem audio) w aplikacji. I * think * ffmpeg oczekuje danych wideo w rurze przed przejściem do drugiego wejścia. Obecnie pracuję nad odłączeniem kodu kodera, dzięki czemu mogę natychmiast napisać wideo do potoku (będę się martwić o synchronizację później). Czy to coś wyjaśnia? – Version135b

+0

Niezupełnie. Wciąż mówisz o indywidualnych FIFO, jakbyś je wypełniał jeden po drugim. Nie powinieneś. Oba FIFO muszą zawsze być stale wypełniane danymi, niezależnie (tj. Zazwyczaj gwintowane lub podobne). –

+0

Powodem, dla którego mówię o nich niezależnie jest to, że nie jestem w stanie otworzyć drugiego FIFO do pisania, dopóki coś z niego nie odczyta. Jeśli wpiszesz "cat files/audio.mp4" w drugim terminalu, a następnie uruchom mój kod Android, mogę otworzyć oba fileoutputstreams, ale jeśli nie ma nic aktualnie słuchającego (dla audio) to nie pozwoli mi otworzyć pliku outputoutstream. Czy muszę inaczej tworzyć FIFO? PS: Edytowałem odpowiedź z kilkoma nowymi informacjami. – Version135b