android 一直ffmpeg

本文详细记录了在Android环境下将ffmpeg工程移植到NDK中,通过JNI调用libffmpeg方法的过程。包括工程编译、源代码引用、jni方法实现及测试验证等关键步骤。最终展示了成功调用libffmpeg.so中的avcodec_version()方法,并输出版本信息的实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天折腾了一天,可算是有所收获,成功的用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

C代码 复制代码  收藏代码
  1. # Copyright (C) 2009 The Android Open Source Project   
  2. #   
  3. # Licensed under the Apache License, Version 2.0 (the "License");   
  4. # you may not use this file except in compliance with the License.   
  5. # You may obtain a copy of the License at   
  6. #   
  7. #      http://www.apache.org/licenses/LICENSE-2.0   
  8. #   
  9. # Unless required by applicable law or agreed to in writing, software   
  10. # distributed under the License is distributed on an "AS IS" BASIS,   
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   
  12. # See the License for the specific language governing permissions and   
  13. # limitations under the License.   
  14. #   
  15. LOCAL_PATH := $(call my-dir)   
  16.   
  17. include $(CLEAR_VARS)   
  18. PATH_TO_FFMPEG_SOURCE:=$(LOCAL_PATH)/ffmpeg   
  19. LOCAL_C_INCLUDES += $(PATH_TO_FFMPEG_SOURCE)   
  20. LOCAL_LDLIBS := -lffmpeg   
  21. LOCAL_MODULE    := hello-jni   
  22. LOCAL_SRC_FILES := hello-jni.c   
  23.   
  24. 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

C代码 复制代码  收藏代码
  1. /*  
  2.  * Copyright (C) 2009 The Android Open Source Project  
  3.  *  
  4.  * Licensed under the Apache License, Version 2.0 (the "License");  
  5.  * you may not use this file except in compliance with the License.  
  6.  * You may obtain a copy of the License at  
  7.  *  
  8.  *      http://www.apache.org/licenses/LICENSE-2.0  
  9.  *  
  10.  * Unless required by applicable law or agreed to in writing, software  
  11.  * distributed under the License is distributed on an "AS IS" BASIS,  
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
  13.  * See the License for the specific language governing permissions and  
  14.  * limitations under the License.  
  15.  *  
  16.  */  
  17. #include <string.h>   
  18. #include <stdio.h>   
  19. #include <android/log.h>   
  20. #include <stdlib.h>    
  21. #include <jni.h>   
  22. #include <ffmpeg/libavcodec/avcodec.h>   
  23. /* This is a trivial JNI example where we use a native method  
  24.  * to return a new VM String. See the corresponding Java source  
  25.  * file located at:  
  26.  *  
  27.  *   apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java  
  28.  */  
  29. jstring   
  30. Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,   
  31.                                                   jobject thiz )   
  32. {   
  33.     char str[25];   
  34.     sprintf(str, "%d", avcodec_version());    
  35.   
  36.   
  37.     return (*env)->NewStringUTF(env, str);   
  38. }  

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

 

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

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

Java代码 复制代码  收藏代码
  1. static {   
  2.        System.loadLibrary("ffmpeg");   
  3.         System.loadLibrary("hello-jni");   
  4.     }  
static {
       System.loadLibrary("ffmpeg");
        System.loadLibrary("hello-jni");
    }

     HelloJni.java

 

 

Java代码 复制代码  收藏代码
  1. /*  
  2.  * Copyright (C) 2009 The Android Open Source Project  
  3.  *  
  4.  * Licensed under the Apache License, Version 2.0 (the "License");  
  5.  * you may not use this file except in compliance with the License.  
  6.  * You may obtain a copy of the License at  
  7.  *  
  8.  *      http://www.apache.org/licenses/LICENSE-2.0  
  9.  *  
  10.  * Unless required by applicable law or agreed to in writing, software  
  11.  * distributed under the License is distributed on an "AS IS" BASIS,  
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
  13.  * See the License for the specific language governing permissions and  
  14.  * limitations under the License.  
  15.  */  
  16. package com.example.hellojni;   
  17.   
  18. import android.app.Activity;   
  19. import android.widget.TextView;   
  20. import android.os.Bundle;   
  21.   
  22.   
  23. public class HelloJni extends Activity   
  24. {   
  25.     /** Called when the activity is first created. */  
  26.     @Override  
  27.     public void onCreate(Bundle savedInstanceState)   
  28.     {   
  29.         super.onCreate(savedInstanceState);   
  30.   
  31.         /* Create a TextView and set its content.  
  32.          * the text is retrieved by calling a native  
  33.          * function.  
  34.          */  
  35.         TextView  tv = new TextView(this);   
  36.         tv.setText( "1111" );   
  37.         //System.out.println();   
  38.         setContentView(tv);   
  39.         tv.setText(String.valueOf(stringFromJNI()));   
  40.     }   
  41.   
  42.     /* A native method that is implemented by the  
  43.      * 'hello-jni' native library, which is packaged  
  44.      * with this application.  
  45.      */  
  46.     public native String  stringFromJNI();   
  47.   
  48.     /* This is another native method declaration that is *not*  
  49.      * implemented by 'hello-jni'. This is simply to show that  
  50.      * you can declare as many native methods in your Java code  
  51.      * as you want, their implementation is searched in the  
  52.      * currently loaded native libraries only the first time  
  53.      * you call them.  
  54.      *  
  55.      * Trying to call this function will result in a  
  56.      * java.lang.UnsatisfiedLinkError exception !  
  57.      */  
  58.     public native String  unimplementedStringFromJNI();   
  59.   
  60.     /* this is used to load the 'hello-jni' library on application  
  61.      * startup. The library has already been unpacked into  
  62.      * /data/data/com.example.HelloJni/lib/libhello-jni.so at  
  63.      * installation time by the package manager.  
  64.      */  
  65.     static {   
  66.           System.loadLibrary("ffmpeg");   
  67.         System.loadLibrary("hello-jni");   
  68.     }   
  69. }  
/*
 * 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库里的各种函数的使用方法,以实现自己想要的功能了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值