Mac下编译FFMpeg(AndroidStudio)

本文介绍了如何在Mac系统下编译FFmpeg,并将其集成到Android Studio项目中。首先下载FFmpeg,配置NDK环境,然后通过修改configure文件和编写build_android.sh脚本来编译FFmpeg。编译完成后,将生成的so库放入项目的jni目录,并编写Android.mk和Application.mk文件。最后,提供了一个简单的JNI代码示例,完成FFmpeg库的调用,运行项目展示推流和播放器的实现效果。
摘要由CSDN通过智能技术生成

最近想仔细研究一下公司的推流以及播放器的底层代码,可是我是做Java的c不是特别的懂,没有办法,先一步步来吧。
ndk配置其实都很简单,我这里就不赘述了,网上大神的帖子也比较多,其实也就下载安装那么几步,然后这里用到的主要也就是是ndk-build这个命令,我用的是mac系统其他的环境变量的配置大同小异,windows下的可能还需要Cywing。
ffmpeg的下载地址:https://ffmpeg.org/download.html#build-mac
下载完成解压(得到如图不包括android文件夹):
这里写图片描述
配置ndk环境
open ~/.bash_profile 配置环境变量
这里写图片描述
配置ndk(添加ndk的目录位置)
执行source ~/.bash_profile(生效配置)
执行$PATH:如果得到命令行结果里已经包含你配置的ndk路径那就是成功了
这里写图片描述

编译FFMpeg

本文的第一张图里边有一个configure,使用sublime Text打开,其他编辑程序也可以,然后找到如下几行

SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'  
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'  
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'  
SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR)$(SLIBNAME)'

然后替换为

SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'  
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'  
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'  
SLIB_INSTALL_LINKS='$(SLIBNAME)'

这个主要是生成的lib包的包名规范成以libxxx.so的形式。
然后编写编译脚本 :
编写脚本的时候需要注意windows下可能会有问题:

1.在WIN底下用文本编辑工具修改过参数变量,在保存的时候没注意编码格式造成的,
2.新建一个名为build_android.sh。代码如下:

#!/bin/sh
NDK=/Users/hejunlin/Downloads/android-ndk-r10e
SYSROOT=$NDK/platforms/android-21/arch-arm
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
function build_one
{
./configure \
--prefix=$PREFIX \
--enable-shared \
--disable-static \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-avdevice \
--disable-doc \
--disable-symver \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--target-os=linux \
--arch=arm \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
}
CPU=arm
PREFIX=$(pwd)/android/$CPU
ADDI_CFLAGS="-marm"
build_one

前三行的路径配置,需要跟橘子机的电脑需改,之前配置过NDK应该记得自己的路径吧。
然后在终端上进入build_android.sh所在的文件夹输入./build_android.sh,然后等一段时间,你会发现在FFmpeg中出现了一个名为android的文件夹,格式如下:
这里写图片描述
这样所需要的ffmpeg的so库都做好了提前准备的工作。
接下来导入到项目中:
新建项目——》在src/main下建一个jni目录 ——》把上边编译出来的android的目录放到jni文件加下。
最后的目录应该是这样的,
这里写图片描述
Android.mk的代码:

LOCAL_PATH :=$(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := avcodec
LOCAL_SRC_FILES := libavcodec-57.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := avfilter
LOCAL_SRC_FILES := libavfilter-6.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := avformat
LOCAL_SRC_FILES := libavformat-57.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := avutil
LOCAL_SRC_FILES := libavutil-55.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := swresample
LOCAL_SRC_FILES := libswresample-2.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := swscale
LOCAL_SRC_FILES := libswscale-4.so
include $(PREBUILT_SHARED_LIBRARY)

#Program
include $(CLEAR_VARS)
LOCAL_MODULE :=sffhelloworld
LOCAL_SRC_FILES := simplest_ffmpeg_helloworld.c
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_LDLIBS := -llog -lz
LOCAL_SHARED_LIBRARIES := avcodec avfilter avformat avutil swresample swscale
include $(BUILD_SHARED_LIBRARY)

Application.mk这个文件简单的说一下就是需要变异那种平台或格式的so库,我只写了一种情况的,代码特别简单:
这里写图片描述
最后就是C的代码,这个代码是从逆流的鱼的博客上copy的,不过他上边大部分都是图片,为了大家快速上手避免一些不必要的麻烦我自己写了一遍,直接贴代码,注意JNI的签名要用自己的JAVA+包名+类名+方法名,我的代码如下:

#include <stdio.h>
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavfilter/avfilter.h"

#ifdef ANDROID
#include <jni.h>
#include <android/log.h>
#define LOGE(format,...) __android_log_print(ANDROID_LOG_ERROR,"myndk",format,##__VA_ARGS__)
#else
#define LOGE(format,...) printf("(>_<)"format "\n",##__VA_ARGS__)
#endif

JNIEXPORT jstring Java_com_shenpengliang_sample_ndkdemo_MainActivity_avcodecinfo(JNIEnv *env,jobject obj)
{
    char info[40000] ={0};
    av_register_all();
    AVCodec *c_temp = av_codec_next(NULL);
    while(c_temp != NULL){
        if(c_temp->decode!=NULL){
            sprintf(info,"%s[Dec]",info);
        }else{
            sprintf(info,"%s[Enc]",info);
        }
        switch(c_temp->type){
           case AVMEDIA_TYPE_VIDEO:
            sprintf(info,"%s[Video]",info);
            break;
           case AVMEDIA_TYPE_AUDIO:
            sprintf(info,"%s[AUDIO]",info);
            break;
           default:
            sprintf(info,"%s[Other]",info);
            break;
        }
        sprintf(info,"%s[%10s]\n",info,c_temp->name);
        c_temp=c_temp->next;
        LOGE("shenpengliang1");
    }
    return (*env)->NewStringUTF(env,info);
}

然后进入到terminal,cd到jni目录,执行ndk-build,(一般情况下ndk的目录应该在local.properties由系统自动创建了,如果没有收到呢添加)
然后会在lib目录下会生成几个so库,如图:
这里写图片描述
将lib里边的so库拷贝到jniLibs目录下,或者去更改build.gradle的配置文件,将jni指向到lib目录,看个人喜好了。
我的MainActivity的代码是这样的,大家参考吧

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private TextView textView;
    static {
        try{
            System.loadLibrary("avutil-55");
            System.loadLibrary("swresample-2");
            System.loadLibrary("avcodec-57");
            System.loadLibrary("avformat-57");
            System.loadLibrary("swscale-4");
            System.loadLibrary("avfilter-6");
            System.loadLibrary("sffhelloworld");
        }catch(Exception e){
            e.printStackTrace();
        }

    }
    public native String avcodecinfo();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView= (TextView) findViewById(R.id.test_demo);
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.setText(avcodecinfo());
            }
        });
    }
}

运行出来的效果图:
这里写图片描述
最近在看Android视频方面的编码,所以有时间和大家一起学习分享,欢迎指正,共同进步,一起向更高的方向进击吧。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值