在Android中使用FFMPEG如何减小默认相机捕获的视频大小?

4

我正在试图减小Android默认摄像头拍摄的视频大小(它生成高分辨率视频)。 FFMPEG是否有一个属性可以使用给定的分辨率对视频进行编码? 我尝试过在Google上搜索,但所有示例都使用FFMPEG的命令行模式。

我的问题是:

  1. 我们能在Android中使用ffmpeg命令行吗?
  2. 如果不行,那么我们该如何实现?
  3. 我们能否直接使用ffmpeg在Android上录制视频?
  4. 还有其他解决方案吗?

http://stackoverflow.com/questions/7459183/interact-with-ffmpeg-from-a-net-program-write-input/7608163#7608163 - Miserable Variable
嗨,Hemal,抱歉我认为你分享的链接是针对.NET的,但我需要它用于Android(JAVA)。而且你正在尝试在命令行中执行FFmpeg。问题是我知道如何在Android中运行命令行方法,但问题是默认情况下,Android设备上不会有FFmpeg可执行文件,因此FFmpeg必须成为我的应用程序的一部分,我认为我必须本地调用它。 - Krishnendu
是的,我能够将FFmpeg与我的应用程序捆绑在一起。但现在的问题是,我必须编写一个C/C++代码来实际使用FFmpeg库,并从Java中调用该本地C/C++方法。 - Krishnendu
没有因为默认情况下ffmpeg不会安装在Android设备中。 - Krishnendu
请问@Krishnendu,你明白了吗?我在这个问题上需要一些指示... - Gonzalo Solera
显示剩余4条评论
1个回答

3

可以将ffmpeg编译为适用于Android的版本,并且可以在命令行中运行ffmpeg。除非需要比命令行提供的更高级的用法,否则不需要深入研究本地代码和jni调用。

以下是我运行的shell脚本,用于编译ffmpeg(在Ubuntu下运行,比Windows更容易)

#!/bin/bash


ANDROID_API=android-3
export ANDROID_NDK=${HOME}/android-ndk
export ANDROID_SDK=${HOME}/android-sdk
SYSROOT=$ANDROID_NDK/platforms/$ANDROID_API/arch-arm
ANDROID_BIN=$ANDROID_NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/*-x86/bin/
CROSS_COMPILE=${ANDROID_BIN}/arm-linux-androideabi-
export PATH=$PATH:$ANDROID_SDK/tools:$ANDROID_SDK/platform-tools

export ARM_ROOT=${HOME}android-ndk
export ARM_INC=$ARM_ROOT/platforms/android-5/arch-arm/usr/include
export ARM_LIB=$ARM_ROOT/platforms/android-5/arch-arm/usr/lib
export LIB_INC=${HOME}/include
export LIB_LIB=${HOME}/lib
CFLAGS=" -I$ARM_INC -fPIC -DANDROID -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__  -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -DANDROID  -Wa,--noexecstack -MMD -MP "
LDFLAGS=" -nostdlib -Bdynamic  -Wl,--no-undefined -Wl,-z,noexecstack  -Wl,-z,nocopyreloc -Wl,-soname,/system/lib/libz.so -Wl,-rpath-link=$ARM_LIB,-dynamic-linker=/system/bin/linker -L$ARM_LIB -nostdlib $ARM_LIB/crtbegin_dynamic.o $ARM_LIB/crtend_android.o -lc -lm -ldl -lgcc "

FLAGS="--target-os=linux --enable-cross-compile --cross-prefix=$CROSS_COMPILE --arch=arm --prefix=$HOME --disable-shared --enable-static --extra-libs=-static --extra-cflags=--static --enable-small --disable-asm --disable-yasm --disable-amd3dnow --disable-amd3dnowext --disable-mmx --disable-mmx2 --disable-sse --disable-ssse3 --disable-indevs"
export CFLAGS=$EXTRA_CFLAGS
export LDFLAGS=$EXTRA_LDFLAGS
./configure $FLAGS --extra-cflags="$CFLAGS" --extra-ldflags="$LDFLAGS" \
--cc="${CROSS_COMPILE}gcc --sysroot=${SYSROOT}" --extra-ldflags="$LDFLAGS" \
--cxx="${CROSS_COMPILE}g++ --sysroot=${SYSROOT}" \
--nm="${CROSS_COMPILE}nm" \
--ar="${CROSS_COMPILE}ar"
make clean
make -j4 || exit 1
make install || exit 1

关于运行ffmpeg,首先需要将ffmpeg复制到应用程序文件目录中,使用getRuntime.exec()对其进行chmod 755操作,如下所示,然后使用以下命令运行ffmpeg:

Process p = Runtime.getRuntime().exec("/data/data/yourpackagename/files/ffmpeg -i in.mp4 out.mp4")

现在,让相机的输入以ffmpeg能够理解的格式传输是比较困难的一步,我仍在尝试弄清楚这个问题。我在stackoverflow上发布了一个关于此主题的问题:在实时中使用ffmpeg解码Android硬件编码的H264相机视频流


嗨,感谢你的回复。我按照你提到的所有步骤完成了。我使用你的脚本编译了FFmpeg,然后将它复制到应用程序的文件目录中,并设置了755权限。到这里为止都没问题,但是当我试图调用FFmpeg时,什么也没有发生,它既没有抛出任何错误,也没有生成输出文件。 - Krishnendu
我不能与您分享我的代码,但是我可以告诉您,如果您想找出问题出在哪里,您应该创建一个DataInputStream,它接收ffmpeg进程的标准输出和标准错误流。不要运行p.waitFor(),而是设置某种循环来将进程输出写入到您可以读取的位置。很可能是ffmpeg没有找到输入文件,您可以在getRuntime.exec命令中设置启动环境位置,以便您可以使用相对目录,例如“in.mp4”。 - joebobfrank
谢谢回复。现在它正在运行,但问题是它只是一直在运行!我输入了一个9MB的3gp文件,它生成了一个0字节的输出文件,并且在后台一直运行(等待20分钟)。你需要多长时间? - Krishnendu
我没有遇到任何错误,只是将一个视频转换为所需的分辨率。 - Krishnendu
我该如何获取FFmpeg可执行文件?请帮帮我,这对我很重要! - Gonzalo Solera
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接