MAC环境编译Android环境下的FFmpeg6.0版本

这篇具有很好参考价值的文章主要介绍了MAC环境编译Android环境下的FFmpeg6.0版本。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一. 下载FFmpeg源码

该项目是基于FFmpeg6.0环境编写。文中涉及代码在不同版本可能会有变动
从以下两个地址任选其一下载源码:

  1. https://github.com/FFmpeg/FFmpeg
  2. https://ffmpeg.org/

二、对FFmpeg进行安装编译

执行根目录的configure文件,

./configure 

该方式会生成相关文件,否则项目不可运行,
参考如下:
https://ffmpeg.org/doxygen/6.0/md_INSTALL.html

编译过程中会出现错误,根据错误进行修改,通常会缺少pkg-config安装包,这个会在编译时候提示缺少这个,不提示就是不缺少。安装如下:
brew install pkg-config
整体错误大概分为缺少依赖的安装包和环境。这个根据提示进行安装即可。没办法绕过

编译成.so参考如下
Android 集成 FFmpeg (一) 基础知识及简单调用
https://blog.csdn.net/yhaolpz/article/details/76408829

如果使用sh文件进行编译的话会出现权限拒绝的情况,可以使用以下命令:

chmod +x build_android.sh

然后再执行sh文件。

以下为sh配置的文件,不需要在项目中配置环境变量,但是所有文件中用到的具体路径需要进行修改。
需要注意的是每次添加新的命令需要使用\ 进行分割。在进行配置的时候对于高级选项的命令,比如优化部分--disable-neon最好不要使用,否则容易出现错误。相关命令可以通过configure --help进行查看

#!/bin/bash 
NDK=/Users/c/Documents/sdk/android/ndk/25.1.8937393
TOOLCHAIN_ROOT_DIR=darwin-x86_64
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$TOOLCHAIN_ROOT_DIR/
API=21
#要编译的ffmpeg内容方法
function build_android {
	echo "Compiling FFmpeg for $CPU" 
	./configure \
	--prefix=$PREFIX \
	--disable-hwaccels \
	--disable-gpl \
	--disable-postproc \
	--disable-programs \
	--disable-mediacodec \
	--disable-decoder=h264_mediacodec \
	--disable-static \
	--disable-vulkan \
	--disable-doc \
	--disable-ffmpeg \
	--disable-ffplay \
	--disable-ffprobe \
	--disable-avdevice \
	--disable-doc \
	--disable-symver \
	--disable-x86asm \
	--disable-filters \
	--enable-cross-compile \
	--enable-jni \
	--enable-shared \
	--cross-prefix=$CROSS_PREFIX \
	--nm=$NM \
	--strip=$STRIP \
	--pkgconfigdir=$PKG_CONFIG_DIR \
	--pkg-config=$PKG_CONFIG \
	--target-os=android \
	--arch=$ARCH \
	--cpu=$CPU \
	--cc=$CC \
	--cxx=$CXX \
	--sysroot=$SYSROOT \
	--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \
	--extra-ldflags="$ADDI_LDFLAGS" \
	$ADDITIONAL_CONFIGURE_FLAG 
	make clean 
	make 
	make install 
	echo "The Compilation of FFmpeg for $CPU is completed" 
}
#接下来是根据需要来决定
#armv8-a 
ARCH=arm64 
CPU=armv8-a 
CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang 
CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
LLVM_TOOLCHAIN=$TOOLCHAIN/bin
PKG_CONFIG_DIR=/opt/homebrew/Cellar/pkg-config/0.29.2_3
PKG_CONFIG=$PKG_CONFIG_DIR/bin/pkg-config
NM=$LLVM_TOOLCHAIN/llvm-nm
STRIP=$LLVM_TOOLCHAIN/llvm-strip
SYSROOT=$TOOLCHAIN/sysroot 
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
PREFIX=$(pwd)/android/$CPU 
OPTIMIZE_CFLAGS="-march=$CPU" 
build_android

#x86_64
ARCH=x86_64 
CPU=x86-64
CC=$TOOLCHAIN/bin/x86_64-linux-android$API-clang 
CXX=$TOOLCHAIN/bin/x86_64-linux-android$API-clang++
LLVM_TOOLCHAIN=$TOOLCHAIN/bin
PKG_CONFIG_DIR=/usr/local/Cellar/pkg-config/0.29.2_3
PKG_CONFIG=$PKG_CONFIG_DIR/bin/pkg-config
NM=$LLVM_TOOLCHAIN/llvm-nm
STRIP=$LLVM_TOOLCHAIN/llvm-strip
SYSROOT=$TOOLCHAIN/sysroot 
CROSS_PREFIX=$TOOLCHAIN/bin/x86_64-linux-android-
PREFIX=$(pwd)/android/$CPU
OPTIMIZE_CFLAGS="-march=$CPU"
build_android

其实最初文件可以写成以下方式:

export ANDROID_NDK=<NDK路径>
export TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64
export SYSROOT=$ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot

./configure \
--prefix=$PWD/build \
--enable-shared \
--disable-static \
--disable-doc \
--disable-programs \
--disable-symver \
--arch=arm64 \
--target-os=android \
--cc=$TOOLCHAIN/bin/aarch64-linux-android21-clang \
--cxx=$TOOLCHAIN/bin/aarch64-linux-android21-clang++ \
--cross-prefix=$TOOLCHAIN/bin/aarch64-linux-android- \
--sysroot=$SYSROOT

但是编译中会出现各种错误,最终要么重新指定路径,要么禁止使用,就改成了如此。
关于命令的含义参考如下:
FFmpeg中configure的参数配置解释

对于pkg-config的配置如果编译时候找不到,要么禁用--disable-pkgconfig,要么使用以下方式进行配置

./configure --pkg-config=/path/to/pkg-config --pkgconfigdir=/path/to/pkgconfigdir

最终会在ffmpeg的根目录生成android/<CPU>目录(这里是android/<armv8-a >),里面共有三个文件夹includelibshare。.so位于lib文件夹下:
vulkan_beta.h ffmpeg6.0,C++,ffmpeg

shell脚本参考如下:
shell脚本语言(超全超详细)

对于cpu和ABI的配置可以Android ABI

三、进行JNI接口编写代码

在FFmpeg编译成.so完成后,需要添加JNI编码,否则的话无法在Android项目中直接使用。该操作需要配置ndk-build环境
参考链接:
Android 集成 FFmpeg (一) 基础知识及简单调用

这里使用文本工具进行代码编写和编译,不使用Android Studio进行编译。
首先在上述的FFmpeg根目录下后面生成的文件夹android中创建文件ndkBuild\com\jni\FFmpeg.javandkBuild\jni文件夹
FFmpeg.java代码如下:

package com.jni;

public class FFmpeg {
    
    public static native void run();

}

然后在ndkBuild目录下执行命令生成com_jni_FFmpeg.h文件
该命令的中间的.表示当前路径,可以更改为其余路径,后面是具体的类的名字

javah -classpath .  com.jni.FFmpeg

然后在ndkBuild\jni文件夹下创建com_jni_FFmpeg.cAndroid.mkApplication.mk
代码如下:
com_jni_FFmpeg.c

#include <android/log.h>
#include "com_jni_FFmpeg.h"

#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/frame.h>
#include <libavutil/mem.h>
# 这里是把AV_CODEC_ID_MP2的编码信息打印一下
JNIEXPORT void JNICALL Java_com_jni_FFmpeg_run(JNIEnv *env, jclass obj) {
	char info[40000] = {0};
	const AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
	AVCodecContext *avcodecContext = avcodec_alloc_context3(codec);
	const char *license = avcodec_license();
	if(avcodecContext->codec_type == AVMEDIA_TYPE_VIDEO){//音频
		sprintf(info,"%s[Video]",info);
	}else{//视频	
		sprintf(info,"%s[Audio]",info);
	}
	sprintf(info,"%s[%10s]\n",info,codec->name);
	avcodec_free_context(&avcodecContext); //释放内存
	__android_log_print(ANDROID_LOG_INFO,"myTag","info:\n%s",info);
}

Android.mk

LOCAL_PATH:= $(call my-dir)

FFMPEG_PATH:=/Users/c/Documents/CTest/ffmpeg-6.0
FFMPEG_ANDROID:=$(FFMPEG_PATH)/android/armv8-a
INCLUDE_PATH:=$(FFMPEG_ANDROID)/include
FFMPEG_LIB_PATH:=$(FFMPEG_ANDROID)/lib

include $(CLEAR_VARS)
LOCAL_MODULE:= libavcodec
LOCAL_SRC_FILES:= $(FFMPEG_LIB_PATH)/libavcodec.so
LOCAL_EXPORT_C_INCLUDES := $(INCLUDE_PATH)
include $(PREBUILT_SHARED_LIBRARY)
 
include $(CLEAR_VARS)
LOCAL_MODULE:= libavformat
LOCAL_SRC_FILES:= $(FFMPEG_LIB_PATH)/libavformat.so
LOCAL_EXPORT_C_INCLUDES := $(INCLUDE_PATH)
include $(PREBUILT_SHARED_LIBRARY)
 
include $(CLEAR_VARS)
LOCAL_MODULE:= libswscale
LOCAL_SRC_FILES:= $(FFMPEG_LIB_PATH)/libswscale.so
LOCAL_EXPORT_C_INCLUDES := $(INCLUDE_PATH)
include $(PREBUILT_SHARED_LIBRARY)
 
include $(CLEAR_VARS)
LOCAL_MODULE:= libavutil
LOCAL_SRC_FILES:= $(FFMPEG_LIB_PATH)/libavutil.so
LOCAL_EXPORT_C_INCLUDES := $(INCLUDE_PATH)
include $(PREBUILT_SHARED_LIBRARY)
 
include $(CLEAR_VARS)
LOCAL_MODULE:= libavfilter
LOCAL_SRC_FILES:= $(FFMPEG_LIB_PATH)/libavfilter.so
LOCAL_EXPORT_C_INCLUDES := $(INCLUDE_PATH)
include $(PREBUILT_SHARED_LIBRARY)
 
include $(CLEAR_VARS)
LOCAL_MODULE:= libswresample
LOCAL_SRC_FILES:= $(FFMPEG_LIB_PATH)/libswresample.so
LOCAL_EXPORT_C_INCLUDES := $(INCLUDE_PATH)
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := ffmpeg
LOCAL_SRC_FILES := com_jni_FFmpeg.c 
LOCAL_C_INCLUDES := $(FFMPEG_PATH)
LOCAL_LDLIBS := -lm -llog
LOCAL_SHARED_LIBRARIES := libavcodec libavfilter libavformat libavutil libswresample libswscale
include $(BUILD_SHARED_LIBRARY)

Application.mk

APP_ABI := arm64-v8a
APP_PLATFORM=android-21

然后在当前目录下执行命令:

ndk-build

生成Android.mk中定义的.so文件。最终会在ndkBuild下面生成两个文件夹libsobj。在libs\arm64-v8a下面会有生成的.so库。共七个libavcodec.so libavfilter.so libavformat.so libavutil.so libswresample.so libswscale.so libffmpeg.so。其中libffmpeg.so为编写的JNI生成的so库,其余为依赖库。

额外的内容:
上述是使用makefile编译的.so,如果使用cmake的话需要做下额外处理,因为这个库只编译了arm64-v8a,默认Android Studio是编译所有架构的,所以需要使用以下方式进行限制:

android {
    defaultConfig {
        ndk {
            abiFilters 'arm64-v8a'//, 'x86_64'
        }
    }
}

编译完的.so库暂时没找到固定存放的目录,不过可以全局搜索文件,例如"ffmpeg.so"。可以找到相关位置。拷贝出来即可

四、在Android 项目中调用.so库

将上述的七个.so库复制到项目的libs文件夹下,可以将整个libs文件夹对Android项目下的libs进行覆盖。app目录下的build.gradle修改如下:

android{
sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
}
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
}

将刚才编写的java文件连同com.jni的文件夹一起复制到src目录下。整体结构如下:
vulkan_beta.h ffmpeg6.0,C++,ffmpeg
如果将.so连同arm64-v8a文件夹复制到main下面的jniLibs文件夹下面则不需要对build.gradle进行修改。如下
vulkan_beta.h ffmpeg6.0,C++,ffmpeg

然后在项目中调用代码

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val btn: Button = findViewById(R.id.button)
        btn.setOnClickListener {
            FFmpeg.run()
        }
        FFmpeg.test()
    }
}

可以在logcat下看到结果

2023-06-08 11:36:01.783  5346-5346  myTag                   com.test.ffmpeg                      I  info:
                                                                                                    [Audio][       mp2]

五、FFmpeg的代码学习技巧

1、整体学习步骤

在学习一个技巧的时候最好根据官方来进行学习,因为其余人的教程可能存在无法实时更新导致的api变动问题,这样使用旧版代码可能无法运行,也就无从下手。在学习ffmpeg的开发过程中主要有以下几个步骤

  1. 编译ffmpeg为.so。参考:https://ffmpeg.org/doxygen/6.0/md_INSTALL.html,编译过程需要的命令可以通过configure --help进行查看
  2. 将编译成功的结果.so和本地的环境比如Android进行编写桥接代码JNI,这里可以参考Android官方网站: https://developer.android.com/ndk?hl=zh-cn
  3. 在编写JNI时候需要使用ffmpeg的api来完成我们的目的,这里的学习方式最好使用官方教程: https://ffmpeg.org/documentation.html , 以及相关论坛

2、FFmpeg的代码学习步骤

FFmpeg本身是一个工具系列的库,是一个开源性质的库,所以教程相对于那些商业化的框架会比较难以上手,比如OkHttp框架。最初通过浏览器搜索的结果,代码基本上都难以运行,大部分都是api过时,这样其实不利于入门,毕竟通过别人的代码学会了,但是api过时了,又不知道怎么更新api。通过仔细查阅官方网站整理了一条路径(不一定是最优学习方式,有更好的可以留言)。
首先官网提供了必要的api文档和一些基本的示例(虽然示例可能不是我们想象中的示例程序)。通过官方文档我们知道整体文档分为: 命令行工具文档组件文档图书馆文件一般文件API文档社区贡献文档
vulkan_beta.h ffmpeg6.0,C++,ffmpeg

通过每一个都点进去后可以简单知道,内容很多,但是作为初学者来说,实在是难以接受,茫然无措,不知道从何开始。如果是用命令行就可以完成需求的话,当然命令行工具文档是很好的选择,但是如果需要自己通过api开发,就只能查看api文档了。其余的文档可以等后面熟悉了再进行阅读。
api文档位于:https://ffmpeg.org/doxygen/trunk/index.html。每天都会更新。整体页面如下
vulkan_beta.h ffmpeg6.0,C++,ffmpeg
通过此我们知道的有用信息如下:
整个库分为八个部分

  1. libavcodec编码/解码库
  2. libavfilter基于图形的帧编辑库
  3. libavformat I/O 和 muxing/demuxing 库
  4. libavdevice特殊设备复用/解复用库
  5. libavutil通用实用程序库
  6. libswresample音频重采样、格式转换和混合
  7. libpostproc后处理库
  8. libswscale颜色转换和缩放库

在上面的Modules选项下面可以看到都有哪些模块:
vulkan_beta.h ffmpeg6.0,C++,ffmpeg
通过Examples选项下面可以看到有哪些例子
vulkan_beta.h ffmpeg6.0,C++,ffmpeg
如果恰巧自己想实现的需求是例子中所有的,那就非常完美,可是点进去例子后发现,例子对初学者来说写的很复杂。我们最初只想写一个简单的测试例子,测试程序是否编译通过,比如打印下ffmpeg的基础信息,打印下基本的信息。如果不这样做,直接完成一个音视频播放的例子,无疑会显得特别困难。然后我们进行需求分析,什么样的场景满足这样的需求?通过上述信息搜集,可以知道我们打印下ffmpeg支持的格式会比较简单,也不需要进行文件读写。这里的话就锁定使用libavformat。点击进去后发现内容如下:
vulkan_beta.h ffmpeg6.0,C++,ffmpeg
模块如下,文件有三个头文件,一个avformat.h,剩下两个是版本信息,其余的库也是如此,我们的主要参考api就位于第一个文件中,点击进去后发现,里面包含了定义的常量和函数。
vulkan_beta.h ffmpeg6.0,C++,ffmpeg
被标记的就是会用到的遍历函数。我们点击第一个函数。
vulkan_beta.h ffmpeg6.0,C++,ffmpeg
这里是函数的定义,解释了需要从传参数为NULL开始便利,下面是引用该函数的位置(有的api下面还要示例程序的引用地址,不过这个api没有)。选择第一个引用的位置点击进去查看:
vulkan_beta.h ffmpeg6.0,C++,ffmpeg
这里是一个简单的使用方式。将该代码拷贝到实际项目中去,然后别忘了添加相应的头文件,格式如下:<库名/头文件名.h> #include <libavformat/avformat.h>。相应的库名和头文件名在上述步骤已经给出。
所以整体代码如下:

#include <android/log.h>
#include "com_jni_FFmpeg.h"

#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <libavformat/avformat.h>

JNIEXPORT void JNICALL Java_com_jni_FFmpeg_run(JNIEnv *env, jclass obj) {
	 const AVOutputFormat *fmt = NULL;
	     const AVOutputFormat *fmt_found = NULL;
	     void *i = 0;
	     int score_max, score;
	 while ((fmt = av_muxer_iterate(&i))) {
	         score = 0;
			 const char *fmtName = fmt->name;
			 __android_log_print(ANDROID_LOG_INFO,"myTag","fmtName:\n%s",fmtName);
	     }
}

运行程序后可再logcat控制台看到如下内容:

2023-06-08 14:56:30.886  8824-8824  myTag                   com.test.ffmpeg                      I  fmtName:
                                                                                                    a64
2023-06-08 14:56:30.886  8824-8824  myTag                   com.test.ffmpeg                      I  fmtName:
                                                                                                    ac3
2023-06-08 14:56:30.886  8824-8824  myTag                   com.test.ffmpeg                      I  fmtName:
                                                                                                    adts
2023-06-08 14:56:30.886  8824-8824  myTag                   com.test.ffmpeg                      I  fmtName:
                                                                                                    adx
2023-06-08 14:56:30.886  8824-8824  myTag                   com.test.ffmpeg                      I  fmtName:
                                                                                                    aiff
2023-06-08 14:56:30.886  8824-8824  myTag                   com.test.ffmpeg                      I  fmtName:
                                                                                                    alp
2023-06-08 14:56:30.886  8824-8824  myTag                   com.test.ffmpeg                      I  fmtName:
                                                                                                    amr
2023-06-08 14:56:30.886  8824-8824  myTag                   com.test.ffmpeg                      I  fmtName:
                                                                                                    amv
                                                                                                    ...
                                                                                                    ...

不过这种代码编写方式不太好,没办法发挥ide的特性,想了解使用ide编写代码的方式可以查看Mac环境下使用Clion编译测试运行Ffmpeg。
下面是根据网上其余人的需求写的代码,打印出支持的编解码类型

#include <android/log.h>
#include "com_jni_FFmpeg.h"

#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <libavformat/avformat.h>
#include "libavcodec/avcodec.h" //编码器格式
#include <libavutil/frame.h>
#include <libavutil/mem.h>

void iterateAvOutFormat(){
	const AVOutputFormat *fmt = NULL;
	    const AVOutputFormat *fmt_found = NULL;
	    void *i = 0;
	    int score_max, score;
	 
	while ((fmt = av_muxer_iterate(&i))) {
	        score = 0;
				 const char *fmtName = fmt->name;
				 __android_log_print(ANDROID_LOG_INFO,"myTag","fmtName:\n%s",fmtName);
	    }
}
void printMp2Decoder(){
	char info[40000] = {0};
	const AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
	AVCodecContext *avcodecContext = avcodec_alloc_context3(codec);
	const char *license = avcodec_license();
	if(avcodecContext->codec_type == AVMEDIA_TYPE_VIDEO){//音频
		sprintf(info,"%s[Video]",info);
	}else{//视频	
		sprintf(info,"%s[Audio]",info);
	}
	sprintf(info,"%s[%10s]\n",info,codec->name);
	avcodec_free_context(&avcodecContext); //释放内存
	__android_log_print(ANDROID_LOG_INFO,"myTag","info:\n%s",info);
}

void iterateMimeType(AVCodecDescriptor *desc){
    if (desc == NULL){
        return;
    }
    const char *const *const mime_types = desc->mime_types; //这是个数组类型
    if (mime_types == NULL){
        return;
    }
    char** current_str = mime_types;
    while (*current_str != NULL) {
//        printf("类型:%s\n", *current_str);
        __android_log_print(ANDROID_LOG_INFO,"myTag","mimeType:\n%1c",*current_str);
        current_str++;
    }
}

//打印编码信息
//代码源自: https://ffmpeg.org/doxygen/trunk/opt__common_8c_source.html#l00635
void iterateCodec(){
	     const AVCodecDescriptor *desc = NULL;
	     const AVCodecDescriptor **codecs;
		 unsigned nb_codecs = 0, i = 0;
		  while ((desc = avcodec_descriptor_next(desc))){
			nb_codecs++; //计算有多少个编码器
			enum AVCodecID avCodecId = desc->id;
			enum AVMediaType avCodecType = desc->type;
			const char *avCodecName = desc->name;
			const char *avCodecLongName = desc->long_name;
			const char *const *const mime_types = desc->mime_types; //这是个数组类型
			__android_log_print(ANDROID_LOG_INFO,"myTag","avCodecName:\n%1s, avCodecLongName: %2s",avCodecName, avCodecLongName);
			iterateMimeType(desc);
		  }
}

JNIEXPORT void JNICALL Java_com_jni_FFmpeg_run(JNIEnv *env, jclass obj) {
	// printMp2Decoder();
	// iterateAvOutFormat();
	iterateCodec();
}

六、关于编译报错的解决思路

有时候编译会出现错误,比如如下:

ym@192 ffmpeg-6.0 % ./build_android.sh
Compiling FFmpeg for x86_64
/Users/ym/Work/AndroidDevelop/AndroidSdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/darwin-x86_64/bin/x86_64-linux-android21-clang is unable to create an executable file.
C compiler test failed.

If you think configure made a mistake, make sure you are using the latest
version from Git.  If the latest version fails, report the problem to the
ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.libera.chat.
Include the log file "ffbuild/config.log" produced by configure as this will help
solve the problem.
GEN	libavutil/libavutil.version
GEN	libswscale/libswscale.version
GEN	libswresample/libswresample.version
GEN	libavcodec/libavcodec.version
GEN	libavformat/libavformat.version
GEN	libavfilter/libavfilter.version
CC	libavfilter/aarch64/vf_nlmeans_init.o
CC	libavfilter/aeval.o
....

vulkan_beta.h ffmpeg6.0,C++,ffmpeg
当出现错误时候即使最终执行结束了,后面没有提示失败,也是不会有.so生成的,这里可以看下报错下面的提示,提示去查看"ffbuild/config.log"文件,这个文件位于ffmpeg源码根目录下面,打开后拉到最下面,可以看到以下内容:

test_ld cc
test_cc
BEGIN /var/folders/0c/q0xxnz590915l9vf7njtx3mc0000gn/T//ffconf.0lN8TtaD/test.c
    1	int main(void){ return 0; }
END /var/folders/0c/q0xxnz590915l9vf7njtx3mc0000gn/T//ffconf.0lN8TtaD/test.c
/Users/ym/Work/AndroidDevelop/AndroidSdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/darwin-x86_64/bin/x86_64-linux-android21-clang --sysroot=/Users/ym/Work/AndroidDevelop/AndroidSdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/darwin-x86_64/sysroot -Os -fpic -march=x86_64 -m64 -mtune=intel -c -o /var/folders/0c/q0xxnz590915l9vf7njtx3mc0000gn/T//ffconf.0lN8TtaD/test.o /var/folders/0c/q0xxnz590915l9vf7njtx3mc0000gn/T//ffconf.0lN8TtaD/test.c
error: unknown target CPU 'x86_64'
note: valid target CPU values are: nocona, core2, penryn, bonnell, atom, silvermont, slm, goldmont, goldmont-plus, tremont, nehalem, corei7, westmere, sandybridge, corei7-avx, ivybridge, core-avx-i, haswell, core-avx2, broadwell, skylake, skylake-avx512, skx, cascadelake, cooperlake, cannonlake, icelake-client, rocketlake, icelake-server, tigerlake, sapphirerapids, alderlake, knl, knm, k8, athlon64, athlon-fx, opteron, k8-sse3, athlon64-sse3, opteron-sse3, amdfam10, barcelona, btver1, btver2, bdver1, bdver2, bdver3, bdver4, znver1, znver2, znver3, x86-64, x86-64-v2, x86-64-v3, x86-64-v4
C compiler test failed.

vulkan_beta.h ffmpeg6.0,C++,ffmpeg

然后根据提示发现是找不到'x86_64'的cpu架构,然后从提示中找到可以使用的架构x86-64。其实就是名字写错了。文章来源地址https://www.toymoban.com/news/detail-808734.html

七、参考链接:

  1. ndk-build 脚本
  2. Android studio添加第三方库和so
  3. Mac环境下使用Clion编译测试运行Ffmpeg
  4. 编译ffmpeg安卓库(clang篇),含armeabi-v7a , arm64-v8a, x86, x86_64
  5. Android ABI

到了这里,关于MAC环境编译Android环境下的FFmpeg6.0版本的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Mac ffmpeg编译支持绘制文字

     Could not load font \\\"arial.ttf\\\": cannot open resource  是因为ffmpeg编译没有--enable-libfontconfig。ffmpeg 打开开关后,编译ffmpeg 2  ERROR: fontconfig not found using pkg-config。 https://github.com/r-lib/systemfonts/issues/21

    2024年02月16日
    浏览(30)
  • ffmpeg在windows环境下的详细安装教程

    这两天整理好用的录屏软件,发现了Captura这个软件,软件本身的安装很简单,但由于Captura需要依赖 ffmpeg (一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序),而ffmpeg在安装上会略费些功夫。 看了很多网上的回答,有的因为时间太久,页面已

    2024年02月16日
    浏览(27)
  • xcode 的app工程与ffmpeg 4.4版本的静态库联调,ffmpeg内下的断点无法暂停。

            先阐述一下我的业务场景,我有一个iOS的app sdk项目,下面简称 A ,以及运行 A 的 app 项目,简称 A demo 。         引用关系为 A demo 引用了 A ,而 A 引用了 ffmpeg 的静态库(.a文件)。此时业务出现了 bug ,测试后得知,bug 来自于ffmpeg。现在无法定位ffmpeg的问题出在哪

    2024年02月14日
    浏览(29)
  • 【FFmpeg】在 Mac OS 中编译 FFmpeg 源码 ① ( homebrew 安装 | 通过 gitee 源安装 homebrew | 安装 FFmpeg 编译所需的软件包 )

    在 Mac 系统中 homebrew 是一款 软件包管理工具 , 可以 轻松的 安装 / 卸载 / 更新 / 查看 / 搜索 软件包 , 可以简单方便地对软件包进行管理 , 无需用户 处理 复杂的依赖关系 问题 ; homebrew 是 基于 Git 的仓库 的 , 用户 跟踪 和 获取最新版本的软件包 ; homebrew 的 默认安装位置是 /u

    2024年04月13日
    浏览(47)
  • 编译可调试的debug版本的ffmpeg

    1、首先需要到官网下载ffmpeg,网上的例子很多在此不进行赘述。 2、下载完成后,进入到ffmpeg源码的文件夹中 configure是一个关键的文件,编译主要用到此文件外加一些自定义的条件实现编译,可以通过./configure --help来查看可提供的选项及其含义,下图中仅列出了一小部分 3、

    2023年04月08日
    浏览(25)
  • Android ffmpeg入门(1)—— 使用NDK交叉编译ffmpeg集成到Android项目

    最近在学习android NDK开发相关内容,借ffmpeg练练手。ffmpeg是做音视频方面功能的基础,后面会随着个人的学习更新一系列ffmpeg博客,防止自己遗忘。 这个系列博客主要目的是基于ffmpeg通过NDK开发的方式完成一个基本的视频播放器。 本篇博客主要实现了 ffmpeg编译 以及 引入 a

    2023年04月08日
    浏览(32)
  • 不同版本的 .NET Framework 下的 csc编译器的版本

    以下是不同版本的 .NET Framework 下的 csc.exe 编译器的版本: .NET Framework 2.0 - 3.5: csc.exe 版本:2.0.xxxxxx .NET Framework 4.x: .NET Framework 4.0: csc.exe 版本:4.0.xxxxxx .NET Framework 4.5 - 4.8: csc.exe 版本:4.0.xxxxxx .NET Framework 4.5.1 以及更新版本(4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8): csc.exe 版本

    2024年02月12日
    浏览(31)
  • FFmpeg开发笔记(八)Linux交叉编译Android的FFmpeg库

    ​ 《FFmpeg开发实战:从零基础到短视频上线》一书的“12.1.2  交叉编译Android需要的so库”介绍了如何在Windows环境交叉编译Android所需FFmpeg的so库,接下来介绍如何在Linux环境交叉编译Android所需FFmpeg的so库。 登录Linux服务器(比如华为云的欧拉系统),依次执行下面的命令。 重

    2024年03月24日
    浏览(38)
  • Android编译ijkplayer和ffmpeg4.0

    最近编译了iOS的ijkplayer和android的ijkplayer,记录一下: 1、bilibili/ijkplayer地址:https://github.com/bilibili/ijkplayer 2、bilibili/ffmpeg地址:GitHub - bilibili/FFmpeg: mirror of git://git.videolan.org/ffmpeg.git 3、ffmpeg官方下载地址:Download FFmpeg ---------------------------------------------------------------- 默认按照

    2024年02月11日
    浏览(35)
  • 【交叉编译】编译生成 x86、arm 环境下的FFTW库

    FFTW是一个快速计算离散傅里叶变换的标准C语言程序集,可计算一维或多维实和复数据以及任意规模的DFT。下面主要介绍的是 x86 环境下 FFTW库的编译过程,arm环境下的编译过程和FFTW类似,不同之处在于需要手动指定 编译环境 和 编译器 。 FFTW有三个版本的数据类型:double、

    2024年02月06日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包