❶ android ffmpeg 解碼前需要編碼嗎
近弄了下android ffmpeg解碼,下面把流程總結一下方便大家參考
1.ffmpeg移植
網上有一些關於ffmpeg移植的文章,試了很多次但是最後生成的libffmpeg.so就只有幾KB所以這里換一種方式,網上也有文章說到了,其實我覺得這種方式反而要好一點,只需要生成一個庫就行了。
我修改好的ffmpeg下載地址:http://download.csdn.net/detail/hcly/6865961
下載後,解壓進入ffmpeg-1.2.4-android目錄,裡面有一個mkconfig.sh文件,打開這個文件,你需要修改幾個地方.
mkconfig.sh內容如下:
[python] view plain
#!/bin/sh
export PREBUILT=//work/tools/android-ndk-r5b/toolchains/arm-linux-androideabi-4.4.3
export PLATFORM=//work/tools/android-ndk-r5b/platforms/android-9/arch-arm
export TMPDIR=//tmp
./configure \
--target-os=linux \
--arch=arm \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-avdevice \
--disable-avfilter \
--disable-postproc \
--disable-swresample \
--disable-avresample \
--disable-symver \
--disable-debug \
--disable-stripping \
--disable-yasm \
--disable-asm \
--enable-gpl \
--enable-version3 \
--enable-nonfree \
--disable-doc \
--enable-static \
--disable-shared \
--enable-cross-compile \
--prefix=//_install \
--cc=$PREBUILT/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc \
--cross-prefix=$PREBUILT/prebuilt/linux-x86/bin/arm-linux-androideabi- \
--nm=$PREBUILT/prebuilt/linux-x86/bin/arm-linux-androideabi-nm \
--extra-cflags="-fPIC -DANDROID -I$PLATFORM/usr/include" \
--extra-ldflags="-L$PLATFORM/usr/lib -nostdlib"
sed -i 's/HAVE_LRINT 0/HAVE_LRINT 1/g' config.h
sed -i 's/HAVE_LRINTF 0/HAVE_LRINTF 1/g' config.h
sed -i 's/HAVE_ROUND 0/HAVE_ROUND 1/g' config.h
sed -i 's/HAVE_ROUNDF 0/HAVE_ROUNDF 1/g' config.h
sed -i 's/HAVE_TRUNC 0/HAVE_TRUNC 1/g' config.h
sed -i 's/HAVE_TRUNCF 0/HAVE_TRUNCF 1/g' config.h
sed -i 's/HAVE_CBRT 0/HAVE_CBRT 1/g' config.h
sed -i 's/HAVE_CBRTF 0/HAVE_CBRTF 1/g' config.h
sed -i 's/HAVE_ISINF 0/HAVE_ISINF 1/g' config.h
sed -i 's/HAVE_ISNAN 0/HAVE_ISNAN 1/g' config.h
sed -i 's/HAVE_SINF 0/HAVE_SINF 1/g' config.h
sed -i 's/HAVE_RINT 0/HAVE_RINT 1/g' config.h
sed -i 's/#define av_restrict restrict/#define av_restrict/g' config.h
最開始的環境變數要設置一下:
[python] view plain
export PREBUILT=//work/tools/android-ndk-r5b/toolchains/arm-linux-androideabi-4.4.3
export PLATFORM=//work/tools/android-ndk-r5b/platforms/android-9/arch-arm
export TMPDIR=//tmp
這個為你的NDK的路徑,以及臨時目錄
還有一個地方需要修改:
[python] view plain
--prefix=//_install \
這個為安裝目錄,請改成你自己的。
然後執行./mkconfig.sh
應該會有一個警告,不用管。直接執行make幾分鍾左右應該就會編譯完成了,然後執行make install
在你的安裝目錄下就會生成兩個目錄include和llib到這里 我們移植就完成了,先把這些文件放在這,後面我們需要用到。
2.jni的編寫
在你的android工程目錄下新建一個jni的目錄(其實我是在另一個工程里新建的,前面我試了一次執行ndk-build的時候把工程里的東西給刪除了),把前面我們安裝的include整個目錄拷貝到jni目錄下,把lib目錄里的所有.a文件拷貝到jni目錄下,新建Android.mk文件,內容如下:
[java] view plain
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := avformat
LOCAL_SRC_FILES := libavformat.a
LOCAL_CFLAGS :=-Ilibavformat
LOCAL_EXPORT_C_INCLUDES := libavformat
LOCAL_EXPORT_CFLAGS := -Ilibavformat
LOCAL_EXPORT_LDLIBS := -llog
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avcodec
LOCAL_SRC_FILES := libavcodec.a
LOCAL_CFLAGS :=-Ilibavcodec
LOCAL_EXPORT_C_INCLUDES := libavcodec
LOCAL_EXPORT_CFLAGS := -Ilibavcodec
LOCAL_EXPORT_LDLIBS := -llog
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avutil
LOCAL_SRC_FILES := libavutil.a
LOCAL_CFLAGS :=-Ilibavutil
LOCAL_EXPORT_C_INCLUDES := libavutil
LOCAL_EXPORT_CFLAGS := -Ilibavutil
LOCAL_EXPORT_LDLIBS := -llog
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := swscale
LOCAL_SRC_FILES :=libswscale.a
LOCAL_CFLAGS :=-Ilibavutil -Ilibswscale
LOCAL_EXPORT_C_INCLUDES := libswscale
LOCAL_EXPORT_CFLAGS := -Ilibswscale
LOCAL_EXPORT_LDLIBS := -llog -lavutil
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ffmpegutils
LOCAL_SRC_FILES := native.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_LDLIBS := -L$(LOCAL_PATH) -lm -lz
LOCAL_STATIC_LIBRARIES := avformat avcodec avutil swscale
include $(BUILD_SHARED_LIBRARY)
新建native.c文件,這個是我們最終要調用到的文件,內容如下:
[java] view plain
/*
* Copyright 2011 - Churn Labs, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This is mostly based off of the FFMPEG tutorial:
* http://dranger.com/ffmpeg/
* With a few updates to support Android output mechanisms and to update
* places where the APIs have shifted.
*/
#include <jni.h>
#include <string.h>
#include <stdio.h>
#include <android/log.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#define LOG_TAG "FFMPEGSample"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
AVCodecContext * pCodecCtx = NULL;
AVFrame * pFrame=NULL;
AVPacket avpkt;
struct SwsContext *swsctx = NULL;
AVFrame * picture=NULL;
JNIEXPORT jint JNICALL Java_com__iclient_FfmpegIF_getffmpegv(JNIEnv * env, jclass obj)
{
LOGI("getffmpegv");
return avformat_version();
}
JNIEXPORT jint JNICALL Java_com__iclient_FfmpegIF_DecodeInit(JNIEnv * env, jclass obj,jint width,jint height)
{
LOGI("Decode_init");
AVCodec * pCodec=NULL;
avcodec_register_all();
//av_register_all();
//avcodec_init();
av_init_packet(&avpkt);
pCodec=avcodec_find_decoder(CODEC_ID_H264);
if(NULL!=pCodec)
{
pCodecCtx=avcodec_alloc_context3(pCodec);
if(avcodec_open2(pCodecCtx,pCodec,NULL)>=0)
{
pCodecCtx->height = height;
pCodecCtx->width = width;
pFrame=avcodec_alloc_frame();
}
return 1;
}
else
return 0;
}
JNIEXPORT jint JNICALL Java_com__iclient_FfmpegIF_Decoding(JNIEnv * env, jclass obj,const jbyteArray pSrcData,const jint DataLen,const jbyteArray pDeData)
{
//LOGI("Decoding");
int frameFinished;
int i,j;
int consumed_bytes;
jbyte * Buf = (jbyte*)(*env)->GetByteArrayElements(env, pSrcData, 0);
jbyte * Pixel= (jbyte*)(*env)->GetByteArrayElements(env, pDeData, 0);
avpkt.data = Buf;
❷ 如何用Android NDK編譯FFmpeg
Android NDK編譯FFmpeg
配置編譯環境
在 VirtualBox 中創建一個 Ubuntu 虛擬機
在 Ubuntu 虛擬機中使用 sudo passwd root 命令啟動 root 賬戶
用 root 賬戶登錄進入 Ubuntu
將 android-ndk-r4b-linux-x86.zip 中的內容解壓縮到 /root 目錄下
將 android-sdk_r07-linux_x86.tgz 中的內容解壓縮到 /root 目錄下
將 ffmpeg-0.6.1.tar.bz2 中的內容解壓縮到 /root/ffmpeg/jni 目錄下
三、准備編譯 FFmpeg
編寫 mk 文件
在 /root/ffmpeg/jni 目錄中創建一個 Android.mk 文件,內容如下
?1include $(all-subdir-makefiles)
在 /root/ffmpeg/jni/ffmpeg-0.6.1 目錄中創建一個 Android.mk 文件,內容如下
6LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_WHOLE_STATIC_LIBRARIES := libavformat libavcodec libavutil
libpostproc libswscale
LOCAL_MODULE := ffmpeg
include $(BUILD_SHARED_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))
在 /root/ffmpeg/jni/ffmpeg-0.6.1 目錄中創建一個 av.mk 文件,內容如下
# LOCAL_PATH is one of libavutil, libavcodec, libavformat, or
libswscale
#include $(LOCAL_PATH)/../config-$(TARGET_ARCH).mak
include $(LOCAL_PATH)/../config.mak
OBJS :=
OBJS-yes :=
MMX-OBJS-yes :=
include $(LOCAL_PATH)/Makefile
# collect objects
OBJS-$(HAVE_MMX) += $(MMX-OBJS-yes)
OBJS += $(OBJS-yes)
FFNAME := lib$(NAME)
FFLIBS := $(foreach,NAME,$(FFLIBS),lib$(NAME))
FFCFLAGS = -DHAVE_AV_CONFIG_H -Wno-sign-compare -Wno-switch
-Wno-pointer-sign
FFCFLAGS += -DTARGET_CONFIG=/"config-$(TARGET_ARCH).h/"
ALL_S_FILES := $(wildcard $(LOCAL_PATH)/$(TARGET_ARCH)/*.S)
ALL_S_FILES := $(addprefix $(TARGET_ARCH)/, $(notdir $(ALL_S_FILES)))
ifneq ($(ALL_S_FILES),)
ALL_S_OBJS := $(patsubst %.S,%.o,$(ALL_S_FILES))
C_OBJS := $(filter-out $(ALL_S_OBJS),$(OBJS))
S_OBJS := $(filter $(ALL_S_OBJS),$(OBJS))
else
C_OBJS := $(OBJS)
S_OBJS :=
endif
C_FILES := $(patsubst %.o,%.c,$(C_OBJS))
S_FILES := $(patsubst %.o,%.S,$(S_OBJS))
FFFILES := $(sort $(S_FILES)) $(sort $(C_FILES))
在 /root/ffmpeg/jni/ffmpeg-0.6.1/libavcodec 目錄中創建一個 Android.mk 文件,內容如下
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES := /
$(LOCAL_PATH) /
$(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_LDLIBS := -lz
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)
在 /root/ffmpeg/jni/ffmpeg-0.6.1/libavformat 目錄中創建一個 Android.mk 文件,內容如下
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES := /
$(LOCAL_PATH) /
$(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_CFLAGS += -include "string.h" -Dipv6mr_interface=ipv6mr_ifindex
LOCAL_LDLIBS := -lz
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)
在 libavfilter、libavutil、libpostproc 和 libswscale 目錄中各創建一個 Android.mk
文件,內容如下
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES := /
$(LOCAL_PATH) /
$(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)
修改 libm.h 文件和 Makefile 文件
編輯 /root/ffmpeg/jni/ffmpeg-0.6.1/libavutil 目錄中的 libm.h 文件,刪除以下 static
方法
#if !HAVE_LRINT
static av_always_inline av_const long int lrint(double x)
{
return rint(x);
}
#endif /* HAVE_LRINT */
#if !HAVE_LRINTF
static av_always_inline av_const long int lrintf(float x)
{
return (int)(rint(x));
}
#endif /* HAVE_LRINTF */
#if !HAVE_ROUND
static av_always_inline av_const double round(double x)
{
return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5);
}
#endif /* HAVE_ROUND */
#if !HAVE_ROUNDF
static av_always_inline av_const float roundf(float x)
{
return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5);
}
#endif /* HAVE_ROUNDF */
#if !HAVE_TRUNCF
static av_always_inline av_const float truncf(float x)
{
return (x > 0) ? floor(x) : ceil(x);
}
#endif /* HAVE_TRUNCF */
編輯 libavcodec、libavfilter、libavformat、libavutil、libpostproc 和 libswscale
目錄中的 Makefile 文件,刪除
?1include $(SUBDIR)../subdir.mak
和
?1include $(SUBDIR)../config.mak
生成 config.h 文件
在 /root/ffmpeg/jni/ffmpeg-0.6.1 目錄中創建一個 config.sh 文件,使用 Android NDK r4b
編譯時內容如下
#!/bin/bash
PREBUILT=/root/android-ndk-r4b/build/prebuilt/linux-x86/arm-eabi-4.4.0
PLATFORM=/root/android-ndk-r4b/build/platforms/android-8/arch-arm
./configure --target-os=linux /
--arch=arm /
--enable-version3 /
--enable-gpl /
--enable-nonfree /
--disable-stripping /
--disable-ffmpeg /
--disable-ffplay /
--disable-ffserver /
--disable-ffprobe /
--disable-encoders /
--disable-muxers /
--disable-devices /
--disable-protocols /
--enable-protocol=file /
--enable-avfilter /
--disable-network /
--disable-mpegaudio-hp /
--disable-avdevice /
--enable-cross-compile /
--cc=$PREBUILT/bin/arm-eabi-gcc /
--cross-prefix=$PREBUILT/bin/arm-eabi- /
--nm=$PREBUILT/bin/arm-eabi-nm /
--extra-cflags="-fPIC -DANDROID" /
--disable-asm /
--enable-neon /
--enable-armv5te /
--extra-ldflags="-Wl,-T,$PREBUILT/arm-eabi/lib/ldscripts/armelf.x
-Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib
$PREBUILT/lib/gcc/arm-eabi/4.4.0/crtbegin.o
$PREBUILT/lib/gcc/arm-eabi/4.4.0/crtend.o -lc -lm -ldl"
使用 Android NDK r5 編譯時內容如下
#!/bin/bash
PREBUILT=/root/android-ndk-r5/toolchains/arm-eabi-4.4.0/prebuilt/linux-x86
PLATFORM=/root/android-ndk-r5/platforms/android-8/arch-arm
./configure --target-os=linux /
--arch=arm /
--enable-version3 /
--enable-gpl /
--enable-nonfree /
--disable-stripping /
--disable-ffmpeg /
--disable-ffplay /
--disable-ffserver /
--disable-ffprobe /
--disable-encoders /
--disable-muxers /
--disable-devices /
--disable-protocols /
--enable-protocol=file /
--enable-avfilter /
--disable-network /
--disable-mpegaudio-hp /
--disable-avdevice /
--enable-cross-compile /
--cc=$PREBUILT/bin/arm-eabi-gcc /
--cross-prefix=$PREBUILT/bin/arm-eabi- /
--nm=$PREBUILT/bin/arm-eabi-nm /
--extra-cflags="-fPIC -DANDROID" /
--disable-asm /
--enable-neon /
--enable-armv5te /
--extra-ldflags="-Wl,-T,$PREBUILT/arm-eabi/lib/ldscripts/armelf.x
-Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib
$PREBUILT/lib/gcc/arm-eabi/4.4.0/crtbegin.o
$PREBUILT/lib/gcc/arm-eabi/4.4.0/crtend.o -lc -lm -ldl"
打開終端,進入 /root/ffmpeg/jni/ffmpeg-0.6.1 目錄,運行下面的命令
❸ Android端webapp開發視頻壓縮有什麼解決方案嗎
圖片/視頻的選擇,編輯和壓縮是業務中的常見需求,Phoenix完整的實現了這些功能,並提供了優雅的調用方式。Phoenix的核心功能基於Kotlin實現,外層介面基於Java實現,方便Kotlin與Java雙方的調用。
特點
❹ android ffmpeg 是啥意思
FFmpeg是一套可以用來記錄、轉換數字音頻、視頻,並能將其轉化為流的開源計算機程序。
用來開發音視頻的~!
❺ 如何在Android用FFmpeg解碼圖像
fetch code
用git把ffmpeg(我用的github上FFmpeg-Android)和x264(vlc的官方git)分別都clone下來。
build x264
在x264目錄裡面寫一個myconfig.sh(其實直接把這些命令打在終端也行,問題是有的時候需要改來改去,不如寫個文件改起來方便)
export NDK=/opt/android-ndk
export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.6/prebuilt
export PLATFORM=$NDK/platforms/android-14/arch-arm
export PREFIX=/home/mingkai/softwares/x264
./configure \
--enable-pic \
--enable-static \
--enable-shared \
--disable-asm \
--disable-cli \
--host=arm-linux \
--cross-prefix="/opt/android-ndk/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/arm-linux-androideabi-"
\
--sysroot=$PLATFORM \
--prefix=$PREFIX
其中prefix貌似直接用"arm-linux-androideabi-「也可以。
然後可以make和make install了。(記得改PREFIX等環境變數)
build FFmpeg
這個是從github上FFmpeg-Android裡面的FFmpeg-Android.sh裡面改了改一些參數。
最主要的是FFMPEG_FLAGS,裡面都是一些關於FFmpeg的參數設定,尤其是是否啟用encoder/decoder之類的。
還有一點就是再下面EXTRA_CFLAGS裡面加上
「-I/path/to/x264/include」
EXTRA_LDFLAGS裡面加上
「-L/path/to/x264/lib -lx264」。