7 Stimmen

Wie man von Android aus an ffserver streamt

Ich muss von einer Android-Kamera/einer Datei zu einem entfernten ffserver streamen, der mein Video übertragen wird. Auf dem Desktop in Ubuntu kann ich dies tun, indem ich einen Befehl wie folgt ausgebe:

ffmpeg -f video4linux2 -s 640x480 -r 25 -i /dev/video0 http://192.168.0.20:8090/cam1.ffm

oder eine Datei so streamen:

ffmpeg -i /home/kev/share/movie.mp4 http://192.168.0.20:8090/cam1.ffm

Also will ich im Grunde das oben genannte von Android aus tun können. Nach mehreren Suchen habe ich bis jetzt folgendes getan - ich bin auf diesen Link gestoßen http://bambuser.com/opensource von dem ich die ffmpeg-Quelle heruntergeladen und erstellt habe. Der Build gibt mehrere Dinge aus: 1. Shared Libraries [libavcodec, libavcore, libavdevice, libavfilter,libavformat,libavutil,libswscale] 2. Ausführbare Dateien [ffmpeg, ffprobe]

Ich bin mir nicht sicher, wie ich meine Funktionalität mit diesen Ressourcen verbinden soll. Dies ist, was ich bis jetzt versucht habe: 1. Die Libraries in meiner Activity geladen, indem ich System.loadLibrary() verwendet habe, dann die ffmpeg-Ausführbare Datei in den Assets-Ordner kopiert, die ich zur Laufzeit in das "files"-Verzeichnis meiner Anwendung kopiert habe. Dann habe ich Berechtigungen für die Ausführbare Datei mit Runtime.getRuntime().exec() gesetzt. Der letzte Schritt war dann, sie in Java mit folgender Anweisung auszuführen:

Runtime.getRuntime().exec("ffmpeg -i file:///android_asset/movie.mp4http://:8090/cam1.ffm");

2. ffmpeg.c, die Shared Libraries und den "include"-Ordner, der vom Build generiert wurde, in meinen jni-Ordner kopiert und eine JNI-Funktion hinzugefügt, die sich um die main() Funktion in ffmpeg.c wickelt. Mit diesem Ansatz musste ich mehrere Header-Dateien aus der ffmpeg-Quelle kopieren, damit der ndk-build erfolgreich ist, und ich bezweifle stark, ob dies der richtige Weg ist.

Die oben genannten beiden Ansätze haben bei mir nicht funktioniert, ich bin mir nicht sicher, wo ich falsch liege, also wäre jegliche Hilfe, wie man einfach ein ffmpeg-Streaming wie eine mp4-Datei von Android aus durchführen kann, sehr geschätzt.

3voto

kev Punkte 1018

Ich habe es zum Laufen gebracht, indem ich Ansatz 2 verwendet habe, das ist was ich getan habe. 1. kopierte ffmpeg.c, den "include" Ordner und die gemeinsamen Bibliotheken in den jni-Ordner meines Projekts.

  1. modifizierte ffmpeg.c mit Bezug auf diesen Blog-Beitrag http://demo860.blogspot.com/2010/07/android-ffmpeg-dynamic-module-jni.html

  2. Es gab mehrere Fehler beim Erstellen mit NDK, also habe ich einfach die fehlenden Abhängigkeiten hinzugefügt, bis das Build schließlich erfolgreich war.

Zu Beginn würde die App starten und dann sofort beenden, dies lag an ein paar Dingen, die ich vergessen hatte zu tun, also stellen Sie sicher, dass Sie Folgendes erledigt haben, um sich einige Stunden und Haarausfall zu sparen: - setzen Sie die Internetberechtigung im Manifest (wenn die Mediendatei auf der SD-Karte liegt, setzen Sie die Berechtigung zum Schreiben externer Speicher und stellen Sie sicher, dass die SD-Karte eingebunden ist) - stellen Sie sicher, dass der entfernte ffserver läuft und korrekt konfiguriert ist. Sie können dies bestätigen, indem Sie von einem Desktop streamen - stellen Sie sicher, dass die richtigen Parameter übergeben wurden

Jetzt kann ich von einer mp4-Datei auf meiner SD-Karte zu einem entfernten ffserver streamen, habe noch nicht versucht, von der Kamerades Geräts zu streamen.

3voto

Stryker33 Punkte 473

Es scheint ein wenig spät zu sein, um diese Frage zu beantworten, aber wenn Sie eine Lösung benötigen, hier ist eine...

Nun, ich hatte eine Lösung für dasselbe Problem entwickelt, aber durch den ersten Ansatz, der die Verwendung eines kompilierten FFmpeg-Binärs anstelle von JNI beinhaltet...

Zunächst einmal, wie es mir scheint, sind die von Bambuser bereitgestellten Builds viel zu alt und FFmpeg hat einen sehr schnellen Entwicklungszyklus... Daher würde ich vorschlagen, Ihren eigenen Binärdateien aus den neuesten FFmpeg-Quellen zu erstellen...

Hier ist ein Skript, das verwendet werden könnte, um eine zu generieren:

#!/bin/bash

echo ""
echo " ********** FFmpeg Android Build ********** "
echo ""

NDK=$HOME/android-ndk-r8d
PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86
PLATFORM=$NDK/platforms/android-14/arch-arm
PREFIX=$HOME/FFmpeg.Binaries.Android
FFMPEG_BASE=$HOME/FFmpeg.Build

if [ -d "$FFMPEG_BASE" ]; then
    rm -v -r -f $FFMPEG_BASE
fi
if [ -d "$PREFIX" ]; then
    rm -v -r -f $PREFIX
fi

mkdir $FFMPEG_BASE
mkdir $PREFIX

# x264 Installation
echo ""
echo " ********** libx264 Installation ********** "
echo ""

cd $FFMPEG_BASE
git clone --depth 1 git://git.videolan.org/x264
cd $FFMPEG_BASE/x264

./configure --prefix=$PREFIX \
--enable-static \
--enable-pic \
--disable-asm \
--disable-cli \
--host=arm-linux \
--cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \
--sysroot=$PLATFORM

make
sudo make install
sudo ldconfig

#FFmpeg Installation
echo ""
echo " ********** FFmpeg (Android) Installation ********** "
echo ""
cd $FFMPEG_BASE
# git clone --depth 1 git://source.ffmpeg.org/ffmpeg
cd $FFMPEG_BASE/ffmpeg

./configure --target-os=linux --prefix=$PREFIX \
--enable-cross-compile \
--enable-runtime-cpudetect \
--disable-asm \
--arch=arm \
--cc=$PREBUILT/bin/arm-linux-androideabi-gcc \
--cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \
--disable-stripping \
--nm=$PREBUILT/bin/arm-linux-androideabi-nm \
--sysroot=$PLATFORM \
--enable-nonfree \
--enable-version3 \
--enable-gpl \
--disable-doc \
--enable-avresample \
--enable-demuxer=rtsp \
--enable-muxer=rtsp \
--disable-ffserver \
--disable-ffprobe \
--enable-ffmpeg \
--enable-ffplay \
--enable-libx264 \
--enable-encoder=libx264 \
--enable-decoder=h264 \
--enable-protocol=rtp \
--enable-hwaccels \
--enable-zlib \
--extra-cflags="-I$PREFIX/include -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=armv7-a" \
--extra-ldflags="-L$PREFIX/lib"

make -j4 install

$PREBUILT/bin/arm-linux-androideabi-ar d libavcodec/libavcodec.a inverse.o
$PREBUILT/bin/arm-linux-androideabi-ld -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -L$PREFIX/lib  -soname libffmpeg.so -shared -nostdlib  -z,noexecstack -Bsymbolic --whole-archive --no-undefined -o $PREFIX/libffmpeg.so libavcodec/libavcodec.a libavfilter/libavfilter.a libavresample/libavresample.a libavformat/libavformat.a libavutil/libavutil.a libswscale/libswscale.a -lc -lm -lz -ldl -llog -lx264 --warn-once --dynamic-linker=/system/bin/linker $PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3/libgcc.a

# rm -v -r -f $FFMPEG_BASE
clear
echo ""
echo "FFmpeg Android Build Erfolgreich..."
echo ""

ls -l -R $PREFIX

exit    

Für das obige Skript ist das Android NDK erforderlich und kann von hier heruntergeladen werden. Laden Sie das NDK herunter und entpacken Sie es in Ihr /home/ Verzeichnis oder passen Sie das Skript entsprechend Ihren Bedürfnissen an...

Vermeiden Sie auch die Verwendung des file:// Protokolls in der Befehlszeile, geben Sie stattdessen den absoluten Pfad der Eingabedatei an. Und versuchen Sie, die Ausgabe des FFmpeg-Prozesses zu protokollieren, indem Sie Instanzen seiner stdout und stderr Streams erhalten...

0voto

Joey Punkte 133

Du musst keine gemeinsam genutzten Bibliotheken und Include-Ordner kopieren. Stattdessen kannst du die Funktion "PREBUILD_SHARED_LIBRARY" von Andriod.mk verwenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X