`
tq09931
  • 浏览: 1514068 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

android 移植ffmpeg后so库的使用

阅读更多

    今天折腾了一天,可算是有所收获,成功的用jni调用了libffmpeg中的一个方法-----avcodec_version(),至于avcodec_version()是干什么用的我不大清楚,应该是获取版本信息吧,没有深入的去研究ffmpeg。

    这里主要是想把折腾一天所获取的经验记录下来,以免时间长全忘了,也希望能给其他人一点借鉴,不至于和我一样一点头绪都没有连猜带蒙的,本文纯属个人心得,高手可以无视....

    要在android上用ffmpeg首先得奖ffmpeg工程移植到android上,这里就要用到ndk把这个开源工程编译成一个后缀为so的库,这个步骤这里就不多说了 网上的资料也挺多的,我是按照:http://www.cnblogs.com/scottwong/archive/2010/12/17/1909455.html在ubantu环境下编译的,你按照教程上一步一步来应该都没有问题,顺便给下在windows下编译ffmpeg的教程:http://abitno.me/compile-ffmpeg-android-ndk(这个要用非ie浏览器打开)。以上两篇文章给了我很大的指引,在此谢过。。。都是牛人啊~~~

编译完以后你会获得一个libffmpeg.so的文件,那么问题来了,怎么用呢。我在百度,google搜了半天也没有一个详细的教程,总是东一句西一句的,但思路是明确的,就是还得编译一个so文件,这个so里的是jni方法,可以由java层调用的,而这些jni方法里用到的函数则就是来至libffmpeg.so了。思路是有了,但是具体怎么做呢?又经过一顿摸索,n次的编译,终于编译成功了。我是拿一个标准的ndk例子来做的测试就是ndk samples文件夹里的hello-jni工程。进入该工程的jni目录,将ffmpeg的源代码拷到该目录下,做这部的原因是你要编译的so文件里需要调用ffmpeg的方法,自然要引用ffmpeg里的h文件,然后将libffmpeg.so文件拷到ndk目录下的platforms/android-5/arch-arm/usr/lib目录下(你会发现platfroms里有好几个android文件夹如 -3 -4 -5分别代表不同的版本,以防万一我每个目录都拷了,呵呵,应该是只要拷指定目录的),因为等等系统编译的时候要用。接下来就编辑android.mk和hello-jni.c文件了 代码如下

android.mk

# Copyright (C) 2009 The Android Open Source Project
#
# 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 copy 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.
#
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
PATH_TO_FFMPEG_SOURCE:=$(LOCAL_PATH)/ffmpeg
LOCAL_C_INCLUDES += $(PATH_TO_FFMPEG_SOURCE)
LOCAL_LDLIBS := -lffmpeg
LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := hello-jni.c

include $(BUILD_SHARED_LIBRARY)

 

PATH_TO_FFMPEG_SOURCE:=$(LOCAL_PATH)/ffmpeg

这行是定义一个变量,也就是ffmpeg源码的路径

LOCAL_C_INCLUDES += $(PATH_TO_FFMPEG_SOURCE)
这行是指定源代码的路径,也就是刚才拷过去的ffmpeg源码,$(LOCAL_PATH)是根目录,如果没有加这行那么引入ffmpeg库中的h文件编译就会出错说找不到该h文件。

LOCAL_LDLIBS := -lffmpeg
这行很重要,这是表示你这个so运行的时候依赖于libffmpeg.so这个库, 再举个例子:如果你要编译的so不仅要用到libffmpeg.so这个库还要用的libopencv.so这个库的话,你这个参数就应该写成

LOCAL_LDLIBS := -lffmpeg -lopencv

其他的参数都是正常的ndk编译用的了,不明白的话google一下。

 

hello-jni.c

/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * 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 copy 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.
 *
 */
#include <string.h>
#include <stdio.h>
#include <android/log.h>
#include <stdlib.h> 
#include <jni.h>
#include <ffmpeg/libavcodec/avcodec.h>
/* This is a trivial JNI example where we use a native method
 * to return a new VM String. See the corresponding Java source
 * file located at:
 *
 *   apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java
 */
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
	char str[25];
	sprintf(str, "%d", avcodec_version()); 


    return (*env)->NewStringUTF(env, str);
}

 #include <ffmpeg/libavcodec/avcodec.h>
这行是因为下面要用到avcodec_version()这个函数。

 

    改完这两个文件以后就可以编译了~~用ndk-build命令编译完后在工程的libs/armeabi目录底下就会有一个libhello-jni.so文件了!(两行眼泪啊~终于编译成功了)

    编译完成后就可以进行测试了,记得将libffmpeg.so也拷到armeabi目录底下,并在java代码中写上

static {
       System.loadLibrary("ffmpeg");
        System.loadLibrary("hello-jni");
    }

     HelloJni.java

 

 

/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * 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 copy 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.
 */
package com.example.hellojni;

import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;


public class HelloJni extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        /* Create a TextView and set its content.
         * the text is retrieved by calling a native
         * function.
         */
        TextView  tv = new TextView(this);
        tv.setText( "1111" );
        //System.out.println();
        setContentView(tv);
        tv.setText(String.valueOf(stringFromJNI()));
    }

    /* A native method that is implemented by the
     * 'hello-jni' native library, which is packaged
     * with this application.
     */
    public native String  stringFromJNI();

    /* This is another native method declaration that is *not*
     * implemented by 'hello-jni'. This is simply to show that
     * you can declare as many native methods in your Java code
     * as you want, their implementation is searched in the
     * currently loaded native libraries only the first time
     * you call them.
     *
     * Trying to call this function will result in a
     * java.lang.UnsatisfiedLinkError exception !
     */
    public native String  unimplementedStringFromJNI();

    /* this is used to load the 'hello-jni' library on application
     * startup. The library has already been unpacked into
     * /data/data/com.example.HelloJni/lib/libhello-jni.so at
     * installation time by the package manager.
     */
    static {
    	  System.loadLibrary("ffmpeg");
        System.loadLibrary("hello-jni");
    }
}

   到此就完成了,将程序装到手机可看到打印出“3426306”,google搜索“ffmpeg 3426306”得知果然是ffmpeg的东西,证明成功的调用了libffmpeg.so库里的方法了。欣慰啊~~

    接下来要做的就是学习ffmpeg库里的各种函数的使用方法,以实现自己想要的功能了。

分享到:
评论
6 楼 x22819 2014-03-26  
你好,我在Windows 7用android-ndk-r8b编译ffmpeg-1.2.6

编译成功后
将Source code放到Eclipse Project中的JNI目录
将libs放到Eclipse Project中的libs目录
将obj放到Eclipse Project中的obj目录

参考你这边设定

在JNI目录下创建SoftAp.C (SoftAp为Project名称)
jstring
Java_com_softap_SoftAP_stringFromJNI( JNIEnv* env,jobject thiz )
{
    char str[25];
    sprintf(str, "%d", avcodec_version());

    return (*env)->NewStringUTF(env, str);
}

Android.mk档案中只修改
LOCAL_MODULE    := SoftAP 
LOCAL_SRC_FILES := SoftAP.c 

但是下ndk-build指令出现此讯息
C:\Users\Wun\workspace\SoftAP>ndk-build
make: *** No rule to make target `/SoftAP.c', needed by `obj/local/armeabi/objs/

该如何解决呢?
SoftAP/SoftAP.o'.  Stop.
5 楼 dengzhangtao 2013-12-06  
我说你说了这么多,就不能把so库放上来么
4 楼 laozhangxiaoY 2013-06-18  
成功了,非常感谢!!
3 楼 yuyingsuifeng 2012-04-12  
我的按照你的步骤做,在运行的时候提示下面的错误,不知楼主碰过这种情况没?
04-12 16:07:12.009: D/dalvikvm(1673): Trying to load lib /data/data/sdi.ffmpeg.tset/lib/libffmpeg.so 0x40514468
04-12 16:07:12.009: D/dalvikvm(1673): Added shared lib /data/data/sdi.ffmpeg.tset/lib/libffmpeg.so 0x40514468
04-12 16:07:12.009: D/dalvikvm(1673): No JNI_OnLoad found in /data/data/sdi.ffmpeg.tset/lib/libffmpeg.so 0x40514468, skipping init
04-12 16:07:12.138: W/dalvikvm(1673): Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lsdi/ffmpeg/tset/Main;
04-12 16:07:12.138: W/dalvikvm(1673): Class init failed in newInstance call (Lsdi/ffmpeg/tset/Main;)
04-12 16:07:12.138: D/AndroidRuntime(1673): Shutting down VM
04-12 16:07:12.138: W/dalvikvm(1673): threadid=1: thread exiting with uncaught exception (group=0x40015560)
04-12 16:07:12.138: E/AndroidRuntime(1673): FATAL EXCEPTION: main
04-12 16:07:12.138: E/AndroidRuntime(1673): java.lang.ExceptionInInitializerError
04-12 16:07:12.138: E/AndroidRuntime(1673): at java.lang.Class.newInstanceImpl(Native Method)
04-12 16:07:12.138: E/AndroidRuntime(1673): at java.lang.Class.newInstance(Class.java:1409)
04-12 16:07:12.138: E/AndroidRuntime(1673): at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
04-12 16:07:12.138: E/AndroidRuntime(1673): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1561)
04-12 16:07:12.138: E/AndroidRuntime(1673): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
04-12 16:07:12.138: E/AndroidRuntime(1673): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
04-12 16:07:12.138: E/AndroidRuntime(1673): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
04-12 16:07:12.138: E/AndroidRuntime(1673): at android.os.Handler.dispatchMessage(Handler.java:99)
04-12 16:07:12.138: E/AndroidRuntime(1673): at android.os.Looper.loop(Looper.java:123)
04-12 16:07:12.138: E/AndroidRuntime(1673): at android.app.ActivityThread.main(ActivityThread.java:3683)
04-12 16:07:12.138: E/AndroidRuntime(1673): at java.lang.reflect.Method.invokeNative(Native Method)
04-12 16:07:12.138: E/AndroidRuntime(1673): at java.lang.reflect.Method.invoke(Method.java:507)
04-12 16:07:12.138: E/AndroidRuntime(1673): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
04-12 16:07:12.138: E/AndroidRuntime(1673): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
04-12 16:07:12.138: E/AndroidRuntime(1673): at dalvik.system.NativeStart.main(Native Method)
04-12 16:07:12.138: E/AndroidRuntime(1673): Caused by: java.lang.UnsatisfiedLinkError: Couldn't load hello-jni: findLibrary returned null
04-12 16:07:12.138: E/AndroidRuntime(1673): at java.lang.Runtime.loadLibrary(Runtime.java:429)
04-12 16:07:12.138: E/AndroidRuntime(1673): at java.lang.System.loadLibrary(System.java:554)
04-12 16:07:12.138: E/AndroidRuntime(1673): at sdi.ffmpeg.tset.Main.<clinit>(Main.java:21)
04-12 16:07:12.138: E/AndroidRuntime(1673): ... 15 more
2 楼 mzloon 2011-12-30  
http://www.iteye.chttp://www.iteye.com/images/smiles/icon_sad.gif       om/images/smiles/icon_surprised.gif
1 楼 kkandkkg 2011-06-05  
请问楼主如何使用在Android中使用FFMPEG命令行呢?
例如:ffmpeg -i video_origine.avi -acodec libmp3lame -ab 56K -ar 44100 -b 200K -r 15 -s 320x240 -f flv video_finale.flv这一类的命令行。
如果在jni中使用的话,如何调用呢

相关推荐

    android移植ffmpeg后so库的使用.docx

    本篇文章主要讲述了如何在Android环境下移植FFmpeg并使用其生成的SO库。移植过程分为几个关键步骤: 1. **移植FFmpeg到Android**: 首先,你需要在Ubuntu环境中按照提供的教程...

    android移植ffmpeg后so库的使用.pdf

    在Android平台上使用FFmpeg库通常涉及到移植FFmpeg源码并将其编译为适用于Android架构的动态链接库(.so文件),然后通过JNI(Java Native Interface)来调用FFmpeg库中的函数。以下是一些关键知识点: 1. **FFmpeg...

    FFmpeg移植到android平台使用的.so包

    以上就是将FFmpeg移植到Android平台并使用.so包的关键步骤和知识点。这个过程中需要对Android的NDK开发、C/C++编程以及FFmpeg的API有深入理解,才能顺利完成整个流程。在实际开发中,还需要不断调试和优化,以确保在...

    Android FFmpeg 6.1+FFmpeg 4.0.2

    2. **Android上的FFmpeg**:在Android平台上使用FFmpeg需要进行一些额外的配置工作,包括编译FFmpeg库以适应Android的NDK环境,创建适用于Android的静态或动态库。动态库(.so文件)通常体积较小,但需要在运行时...

    Android移植ffmpeg2.0解码器

    本资源深度裁剪于ffmpeg2.0解码器中的H264视频解码部分,编译成Android可调用的SO文件。附带有Android make文件以及JNI接口C源码文件等,特别适合于android下的视频开发(只适合H264视频格式的解码),可以通过简单...

    FFMPEG 移植到android

    - 使用 `make` 命令编译 FFmpeg 源码,生成静态或动态库文件(.a 或 .so)。 - 为了节省空间和提高性能,可以选择性地编译部分组件,例如只编译常用的解码器和编码器。 4. **集成到 Android 工程**: - 将编译后...

    android ffmpeg rtsp播放

    总的来说,"android ffmpeg rtsp播放"涉及到Android原生开发、FFmpeg库的移植和使用、RTSP协议解析以及Android多媒体框架的深入理解和应用。开发者需要具备扎实的C/C++编程基础,熟悉Android NDK开发环境,以及对...

    Android ffmpeg算法移植所需库文件armeabi

    4. **生成动态库**: 使用NDK的交叉编译工具链,编译FFmpeg源代码,生成armeabi架构下的.so动态库文件。这些库文件会用于Android应用的本地层。 5. **包含头文件**: 除了.so库文件,移植还包括.h头文件,这些头文件...

    ffmpeg移植android需要的android.mk

    移植FFmpeg到Android涉及到以下几个关键知识点: 1. **Android NDK**:FFmpeg是用C/C++编写的,Android原生应用主要使用Java编写,但为了利用FFmpeg,我们需要使用Android Native Development Kit (NDK)。NDK允许...

    android_ffmpeg配置文件

    FFmpeg是一款强大的...总结,移植FFmpeg到Android涉及配置FFmpeg源码、编译静态库、打包不同架构的动态库,以及将库集成到Android项目中。通过这些步骤,你可以在Android应用中利用FFmpeg的强大功能处理多媒体数据。

    xmt-FFMpeg.rar_ffmpeg_ffmpeg android _ffmpeg移植_surface

    移植FFmpeg时,通常会创建一个Android.mk或CMakeLists.txt文件来配置编译选项,指定需要的库和模块,以及对应的Android ABI。然后通过NDK的构建工具(如ndk-build或cmake)进行编译,生成.so动态库文件。 6. **...

    ffmpeg-compile-shared-library-for-android, 移植ffmpeg到android,编译可用于jni调用的so库..zip

    移植 FFmpeg 至 Android 需要经过一系列步骤,包括获取源代码、配置构建环境、修改构建脚本以及编译生成适用于Android的共享库(so文件)。以下是一个详细的步骤指南: 1. **获取源代码**: 从FFmpeg的官方仓库...

    FFmpeg 移植 Android

    在Android平台上移植FFmpeg,是为了让Android应用能够拥有处理多媒体文件的能力,比如在本地播放高清视频或实时音频处理等。 移植FFmpeg到Android的过程主要包括以下几个关键步骤: 1. 获取源码:首先,你需要从...

    ffmpeg移植到android项目

    总结起来,移植FFmpeg到Android项目涉及下载源码、配置NDK环境、编译生成SO库、创建JNI接口以及在Java代码中调用。这个过程需要对Android原生开发、NDK、C/C++编程以及FFmpeg有一定的了解。通过这些步骤,开发者可以...

    ffmpeg初次移植

    2. **Android移植环境搭建** - 安装NDK:FFmpeg移植需要Android Native Development Kit (NDK) 来编译C/C++代码。 - 配置NDK路径:确保Android Studio知道NDK的位置。 - 获取FFmpeg源码:从官方仓库克隆或下载...

    android ffmpeg

    移植FFmpeg到Android的步骤如下: 1. **环境准备**:在Ubuntu系统中,确保已经安装了NDK r9b。此外,还需要安装Android SDK,用于生成APK并配置Android.mk文件。设置好环境变量,如`ANDROID_NDK`指向NDK的路径。 2...

    ffmpeg移植到android的基础工程

    5. 将 FFmpeg 库添加到 Android 项目:将编译得到的库文件(.so)复制到项目的 jniLibs 目录下,按照不同架构分目录存放。 6. 编写 Java 或 Kotlin 代码:在 Android 应用中,通过 Java Native Interface (JNI) 来...

    AndroidFFmpeg

    2. 移植FFmpeg:针对Android平台,需要修改FFmpeg的配置脚本,以适应不同的CPU架构(armeabi、armeabi-v7a、arm64-v8a、x86、x86_64等)。 3. 构建FFmpeg:使用NDK和Android.mk文件编译生成.so动态库文件,将其放入...

    FFmpeg开源项目移植到Android的研究.pdf

    首先,移植FFmpeg到Android涉及的关键步骤包括: 1. **环境配置**:在Windows、Linux或macOS等平台上搭建交叉编译环境,安装NDK(Android Native Development Kit),设置相应的编译工具链。 2. **FFmpeg源码获取*...

Global site tag (gtag.js) - Google Analytics