android全平台编译ffmpeg支持命令行实践

Android 集成 FFmpeg (二) 以命令方式调用 FFmpeg 除 android_log.h 之外,很显然,还需要添加 ffmpeg.c 、ffmpeg.h 文件,实际上 ffmpeg.c 的 main 函数中还会调用到其他文件,所以需要从源码中拷贝 ffmpeg.h、ffmpeg.c、ffmpeg_opt.c、ffmpeg_filter.c、cmdutils.c、cmdutils.h 以及 cmdutils_common_opts.h 共 7 个文件到 jni 目录下。本文的核心工作是 ffmpeg.c 等文件的修改及编译,其实这些文件的修改是一劳永逸的。 阅读详情

音视频实践学习

本例基于 android全平台编译ffmpeg合并为单个库实践 进行的

目录

环境准备

操作系统 ubuntu 16.05

编译准备好libffmpeg库和需要include头文件,我们还需要抽取ffmpeg-3.3.8中的部分头文件和源文件

笔者整理了一个copy_ffmpeg_files.sh脚本


FFMPEG_DIR=ffmpeg-3.3.8

mkdir include
mkdir include/compat
mkdir include/libavcodec
mkdir include/libavformat
mkdir include/libavutil
mkdir include/libavdevice
mkdir include/libpostproc

cp $FFMPEG_DIR/compat/va_copy.h include/compat/va_copy.h

cp $FFMPEG_DIR/libavcodec/mathops.h include/libavcodec/mathops.h

cp $FFMPEG_DIR/libavdevice/avdevice.h include/libavdevice/avdevice.h
cp $FFMPEG_DIR/libavdevice/version.h include/libavdevice/version.h

cp $FFMPEG_DIR/libavformat/ffm.h include/libavformat/ffm.h
cp $FFMPEG_DIR/libavformat/network.h include/libavformat/network.h
cp $FFMPEG_DIR/libavformat/os_support.h include/libavformat/os_support.h
cp $FFMPEG_DIR/libavformat/url.h include/libavformat/url.h


cp $FFMPEG_DIR/libavutil/libm.h include/libavutil/libm.h
cp $FFMPEG_DIR/libavutil/internal.h include/libavutil/internal.h
cp $FFMPEG_DIR/libavutil/reverse.h include/libavutil/reverse.h
cp $FFMPEG_DIR/libavutil/timer.h include/libavutil/timer.h


cp $FFMPEG_DIR/libpostproc/postprocess.h include/libpostproc/postprocess.h
cp $FFMPEG_DIR/libpostproc/version.h include/libpostproc/version.h

#cpp

mkdir cpp

cp $FFMPEG_DIR/cmdutils.c cpp/cmdutils.c
cp $FFMPEG_DIR/cmdutils.h cpp/cmdutils.h
cp $FFMPEG_DIR/cmdutils_common_opts.h cpp/cmdutils_common_opts.h

#
cp $FFMPEG_DIR/config.h cpp/config.h

cp $FFMPEG_DIR/ffmpeg.h cpp/ffmpeg.h
cp $FFMPEG_DIR/ffmpeg.c cpp/ffmpeg_mod.c
cp $FFMPEG_DIR/ffmpeg_filter.c cpp/ffmpeg_filter.c
cp $FFMPEG_DIR/ffmpeg_opt.c cpp/ffmpeg_opt.c

  • 文件目录结构如下:

将生成之后的include文件夹覆盖到项目中的include目录
本例中即覆盖到ffmpeg-single组件下的libs/armeabi-v7a的include目录

新建ffmpeg-single-cmd工程

将生成的cpp目录复制到src/main目录下

  • 新建FFmpegCmd类
public class FFmpegCmd {

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

    public native int exec(int argc, String[] argv);

}
  • 新建ffmpeg_cmd.c文件

#include <jni.h>
#include <stdio.h>
#include <time.h>
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavfilter/avfilter.h"
#include "libavutil/log.h"

#ifdef ANDROID

#include <android/log.h>

#define LOG_TAG    "HelloFFmpeg"
#define LOGE(format, ...)  __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, format, ##__VA_ARGS__)
#define LOGI(format, ...)  __android_log_print(ANDROID_LOG_INFO,  LOG_TAG, format, ##__VA_ARGS__)
#else
#define LOGE(format, ...)  printf(LOG_TAG format "\n", ##__VA_ARGS__)
#define LOGI(format, ...)  printf(LOG_TAG format "\n", ##__VA_ARGS__)
#endif

int exec(int argc, char **argv);

void custom_log(void *ptr, int level, const char *fmt, va_list vl) {
    FILE *fp=fopen("/storage/emulated/0/Android/data/com.onzhou.ffmpeg.cmd/files/av_log.txt","a+");
    if(fp){
        vfprintf(fp,fmt,vl);
        fflush(fp);
        fclose(fp);
    }
}

JNIEXPORT jint JNICALL Java_com_onzhou_ffmpeg_cmd_FFmpegCmd_exec
        (JNIEnv *env, jobject obj, jint cmdnum, jobjectArray cmdline) {

    av_log_set_callback(custom_log);

    int argc = cmdnum;
    char **argv = (char **) malloc(sizeof(char *) * argc);

    int i = 0;
    for (i = 0; i < argc; i++) {
        jstring string = (*env)->GetObjectArrayElement(env, cmdline, i);
        const char *tmp = (*env)->GetStringUTFChars(env, string, 0);
        argv[i] = (char *) malloc(sizeof(char) * 1024);
        strcpy(argv[i], tmp);
    }

    exec(argc, argv);

    for (i = 0; i < argc; i++) {
        free(argv[i]);
    }
    free(argv);
    return 0;
}
  • 新建ffmpeg_cmd.h头文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_onzhou_ffmpeg_cmd_FFmpegCmd */

#ifndef _Included_com_onzhou_ffmpeg_cmd_FFmpegCmd
#define _Included_com_onzhou_ffmpeg_cmd_FFmpegCmd
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_onzhou_ffmpeg_cmd_FFmpegCmd
 * Method:    exec
 * Signature: (I[Ljava/lang/String;)V
 */
JNIEXPORT jint JNICALL Java_com_onzhou_ffmpeg_cmd_FFmpegCmd_exec
        (JNIEnv *, jobject, jint, jobjectArray);

#ifdef __cplusplus
}
#endif
#endif

build.gradle中的配置不多说了,可以参考之前的实践配置

  • 配置CMakeLists.txt文件

cmake_minimum_required(VERSION 3.4.1)


add_library(ffmpeg-cmd
           SHARED
           src/main/cpp/ffmpeg_cmd.c
           src/main/cpp/cmdutils.c
           src/main/cpp/ffmpeg_filter.c
           src/main/cpp/ffmpeg_opt.c
           src/main/cpp/ffmpeg_mod.c)

find_library(log-lib
            log)

#获取上级目录
get_filename_component(PARENT_DIR ${CMAKE_SOURCE_DIR} PATH)
set(LIBRARY_DIR ${PARENT_DIR}/ffmpeg-single)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
set(CMAKE_VERBOSE_MAKEFILE on)

add_library(ffmpeg-single
           SHARED
           IMPORTED)

set_target_properties(ffmpeg-single
                    PROPERTIES IMPORTED_LOCATION
                    ${LIBRARY_DIR}/libs/${ANDROID_ABI}/libffmpeg.so
                    )

#头文件
include_directories(${LIBRARY_DIR}/libs/${ANDROID_ABI}/include src/main/cpp)

target_link_libraries(ffmpeg-cmd ffmpeg-single ${log-lib})

修改源文件

  • 修改cmdutils.c文件
void exit_program(int ret)
{
    if (program_exit)
        program_exit(ret);

    exit(ret);
}

#改为

int exit_program(int ret)
{
    if (program_exit)
        program_exit(ret);
    //exit(ret);
    return ret;
}
  • 修改cmdutils.h头文件
void exit_program(int ret) av_noreturn;

#改为

int exit_program(int ret) av_noreturn;
  • 修改ffmpeg_mod.c文件
int main(int argc, char **argv)

#改为

int exec(int argc, char **argv)

在return main_return_code;之前加上如下代码:

nb_filtergraphs = 0;
progress_avio = NULL;

input_streams = NULL;
nb_input_streams = 0;
input_files = NULL;
nb_input_files = 0;

output_streams = NULL;
nb_output_streams = 0;
output_files = NULL;
nb_output_files = 0;
  • 测试执行命令行进行转码
public void onCmdClick(View view) {
    if (fFmpegCmd == null) {
        fFmpegCmd = new FFmpegCmd();
    }
    btnTransfer.setEnabled(false);
    File outputFile = new File(getExternalFilesDir(null), "output.mkv");
    if (outputFile.exists()) {
        outputFile.delete();
    }
    Schedulers.newThread().scheduleDirect(new Runnable() {
        @Override
        public void run() {
            String filePath = getExternalFilesDir(null).getAbsolutePath();
            String cmdline = String.format("ffmpeg -i %s/input.mp4 %s/output.mkv", filePath, filePath);
            String[] argv = cmdline.split(" ");
            Integer argc = argv.length;
            fFmpegCmd.exec(argc, argv);
        }
    });
}

运行输出

项目地址
https://github.com/byhook/ffmpeg4android

参考雷神:
https://blog.youkuaiyun.com/leixiaohua1020/article/details/47056365

Android 接入FFmpeg命令-低成本完成各类音视频操作 cmdutils.c、ffmpeg.c、ffmpeg_opt.c、ffmpeg_filter.c、ffmpeg_hw.c、ffmpeg-cmd.c都有一定的依赖关系,这几个C文件共同编译成一个库ffmpeg-cmd,ffmpeg-cmd是我的JNI层方法,负责双边沟通,fftools中依赖了其它例如解码,滤镜,重采样等外部库,也是我们之前编译了的其它库,我们需要把它们作为ffmpeg-cmd的库链接进去。这其中我们要考虑很多条件,音频信息导致的不同处理,异常的捕捉等等,麻烦不说,兼容性都有一段路走。 阅读详情

相关推荐

【Android音视频】自编译FFMpeg-kit添加硬件编码支持并升级FFMpeg版本

上次解决了FFMpeg-kit编译的问题,但直接编译出来是没有硬件编码支持的,只有软件编解码,软编特别特别慢。所以这次还得继续改代码,让它支持在安卓上使用硬件编码。

天枢破军的博客 1659

使用Android Studio开发FFmpeg的正确姿势

原文地址:https://www.jianshu.com/p/0a7f3175c1b9 2018-04-21: 更新至 ffmpeg-4.0 使用AndroidStudio 开发 FFmpeg Keywords: gradle, cmake 关键步骤,编译FFmpeg,Android Studio 集成。 abi support: armeabi armeabi-v7a arm64-v8a...

过客2019 4782

Android Mac编译FFmpeg,并使用

Android Mac编译FFmpeg,并使用FFmpeg 全称(First Forward MPEG),是一款领先的开源多媒体框架,采用 LGPL 或 GPL 许可证,除了具有音视频编解码功能外,还有视频格式转换、视频抓图、视频水印、推流等功能。FFmpeg 在 Linux 平台下开发,但它同样也可以在其它操作系统环境中编译运行,包括 Windows 、Mac OS X 等。FFmpeg官网FFmpeg它主要含有以下几个核心库:1、libavcodec-提供了更加全面的编解码实现的合集。

qq_52703909的博客 1390

ffmpeg之api实现、ios集成和使用ffmpeg、iOS集成和使用SDL、MacOS使用FFmpeg

参考:https://blog.youkuaiyun.com/zwz1984/article/details/82824524

代码解释生活 2790

FFmpeg 集成 x265 编译及解码

x265 是一个免费的软件库和应用程序,用于将视频流编码为 H.265/MPEG-H HEVC 压缩格式,并在 GNU GPL 条款下发布。FFmpeg 为了支持 H.265 编、解码可以集成 x265 编译,在编译 FFmpeg 之前需要先编译 x265,但并不是所有的版本都能直接使用,比如笔者同时编译 Android、Window 和 Linux 三个平台时,使用 Android NDK r21e 会遇到很多报错,符号缺失,无法编译 .S 文件都是可能遇到的问题。

yinshipin007的博客 2321

Android-NDK-clang 编译 FFmpeg

前期准备NDK-21ffmpeg-4.4本文你可以了解到clang。

yinshipin007的博客 1669

android ffmpeg命令行,Android的FFMPEG使用之命令行

1.音频视频合并:"ffmpeg -i 音频 -i 视频 输出视频"例:"ffmpeg -i sdcard/soundtouch.wav -i sdcard/input.mp4 sdcard/output.avi"注:输出视频的格式不为.mp4的原因,好像是ffmpeg的版权原因,只有MP4的解码库,没有编码库(2016,8,11修改,音频视频顺序是可以变的,现在我用的命令行为-i sdcar...

weixin_42106357的博客 982

Android cmake编译FFmpeg

Android cmake编译FFmpeg 项目地址 通过阅读本文,你将学到以下内容: 如何编译多种CPU指令集的FFmpeg动态库 如何配置CMakeLists.txt和build.gradle构建Android项目 编译环境 ndk-r16 ffmpeg-4.0.2 一、交叉编译FFmpeg生成动态库 FFmpeg是一个强大的音视频处理库,我们有时候只需要用到这个库的部分功能,因此我们...

知用改创 1673

android全平台编译ffmpeg以及x264与fdk-aac实践

之前一篇移植的博客。 Android平台移植FFmpeg和x264 编译环境 ubuntu 16.04 android-ndk-r10e ffmpeg-3.3.8版本 fdk-aac-0.1.6版本 开始编译x264库 先获取最新的x264库 git clone http://git.videolan.org/git/x264.git 编写脚本,此脚本可以编译全平台版本 目录结构如下: ——x2...

handy周 4595

Android平台上FFmpeg的H264编码编译实践

FFmpeg是一个开源的多媒体框架,能够解码、编码、转码、复用、解复用、流、过滤和播放几乎所有已知格式的视频和音频。其强大的多媒体处理能力和灵活的使用方式使其成为在视频处理领域不可或缺的工具。在Android平台上,FFmpeg的集成与应用为开发人员提供了无限的可能性,使他们能够在移动设备上执行复杂的媒体处理任务。H264编码,又称作ITU-T H.264或ISO/IEC MPEG-4 AVC,是一种广泛使用的视频压缩标准。它的起源可以追溯到1984年,当时由于视频会议的需求推动了视频编码技术的发展。

weixin_42588672的博客 902

FFmpeg在Android上的编译与多媒体处理实践指南

FFmpeg是一个开源项目,致力于音视频数据流的处理。其功能强大,支持几乎所有的音视频编解码格式,广泛应用于视频处理、流媒体处理和音视频转换等场景。FFmpeg的配置过程包括选择编译选项,这些选项决定了FFmpeg将要编译哪些组件。**常用配置选项**:- `--enable-shared`: 生成共享库。- `--enable-static`: 生成静态库。- `--enable-gpl`: 启用GPL协议。- `--enable-nonfree`: 启用非免费功能。

weixin_35706255的博客 890

android平台下音频编码之编译LAME库转码PCM为MP3

交叉编译 编写基本的配置脚本:config.sh #NDK路径 export ANDROID_NDK_ROOT=/home/byhook/android/android-ndk-r10e export AOSP_TOOLCHAIN_SUFFIX=4.9 export AOSP_API=&amp;amp;quot;android-21&amp;amp;quot; #架构 if [ &amp;amp;quot;$#&amp;amp;quot; -lt 1 ]; the

handy周 2036

从东南大学906被刷到调剂过程(内含个人感想)

介绍了自己在看到初试成绩,到后期复习以及调剂的全过程,当中也包含了自己的复试中的感想,希望大家理性看待。

Philo的博客 2855

Shell生成支持x264的ffmpeg安卓全平台so

前两张实现了ffmpeg全平台so的生成,但是ffmpeg依赖的第三方库是需要另外编译的,所以本章将提供编译x264库并加入ffmpeg的方法。本章提供的脚本在ubuntu以及windows的wsl、msys2都适用。以上就是今天讲述的内容,生成ffmpeg安卓so其实并不难,如果熟悉交叉编译以及shell,编译起来还是比较简单的,尤其是想生成最小或者完整依赖的包,最好还是自己生成。

codeofcc的博客 1357

实战案例:用多智能体系统模拟房地产市场的架构设计

房地产市场是典型的复杂自适应系统:买方纠结“要不要上车”、卖方盘算“挂多少钱能快速成交”、中介忙着“撮合两边赚佣金”、政府琢磨“怎么调政策稳房价”——每一个参与者的微小决策,最终都会汇聚成“房价暴涨”“成交冰点”这样的宏观现象。传统的计量经济学模型(比如线性回归)假设“所有人都是理性人”,但现实中没人能算清所有变量——你可能因为“同事买了学区房”就跟风,也可能因为“怕失业”而放弃买房。这时候,多智能体系统(MAS)

移动开发前沿的博客 1122

谈谈SAP顾问的几个发展趋势

大家新年好,今天想聊一下对SAP顾问发展趋势的一些个人见解。过去10多年得益于我国的经济发展,外资不断加大在中国的投资和中国企业的发展,SAP顾问行业得到了很大的发展和壮大。那么未来几年SAP顾问的职业发展到底怎么样呢?

syounger的专栏 2513

Windows 生成ffmpeg安卓全平台so

做安卓开发的时候,需要实现拉流渲染视频之类的功能,使用ffmpeg比较方便。但是要生成ffmpeg的安卓库是有点麻烦的,需要使用ndk的工具链以及shell。相对来说在Linux上操作是比较容易的,其实Windows上生成也不是很难,shell是基本一致的。........................

codeofcc的博客 2352

UG NX二次开发(C#)-建模-获取圆柱面信息(轴向、半径、深度)

获取圆柱面的信息前言一、在UG NX中面的类型有哪些?二、获取圆柱面信息的函数1.获取半径和轴向2、计算圆柱面的深度值3、测试用例总结 文章目录前言一、在UG NX中面的类型有哪些?二、获取圆柱面信息的函数1.获取半径和轴向2、计算圆柱面的深度值3、测试用例总结 前言 在一个项目中,需要遍历曲面,获得所有的圆柱面和圆柱面的信息,包括轴向、半径和圆柱面的深度。经过研究,采用uFModl.AskFaceData(face.Tag, out faceTypeInt, point, dir, box, out

GimiGimmy 4145

Ubuntu 生成ffmpeg安卓全平台so

做安卓开发的时候,需要实现拉流渲染视频之类的功能,使用ffmpeg比较方便。但是要生成ffmpeg的安卓库是有点麻烦的,需要使用ndk的工具链以及shell。但其实如果了解Linux上编译程序库以及bash,整个生成过程还是相对容易的。............

codeofcc的博客 1879

【YOLO11改进 - C3k2融合】C3k2融合AKConv(可改变核卷积)二次创新:任意数量的参数和任意采样形状的即插即用的卷积

【YOLO11改进 - C3k2融合】C3k2融合AKConv(可改变核卷积)二次创新:任意数量的参数和任意采样形状的即插即用的卷积

专注于图像领域,主要研究内容包括计算机视觉和深度学习,特别是在图像分类、目标检测和图像生成等方面有深入的研究和实践经验。 407

【时时三省】tessy 集成测试 总论

序论不积跬步无以至千里,不积小流无以成江海。正文。

时时三省的博客 1148

macOS上编译android的ffmpeg及ffmpeg.c

前段时间介绍过使用xcode和qt creator编译调试ffmepg.c,运行平台是在macOS上,本文拟介绍下android平台如何用NDK编译链编译ffmepg库并使用。macOS上使用qt creator编译调试ffmpeg.cmacOS上将ffmpeg.c编译成Framework其一,分别介绍使用GCC和CLang编译器来编译ffmpeg库的方法;其二,介绍如何将ffmpeg的多个so库打包成1个so库之法;

老中医的博客 1453

JavaFx 教程

JavaFx 教程

2012年开始工作,全栈开发老兵,目前已是一个老师,分享这么多年的心得体会 784

Android ffmpeg入门(1)—— 使用NDK交叉编译ffmpeg集成到Android项目

使用NDK交叉编译ffmpeg静态库,并集成到Android项目实现JNI互调。

孙先森的博客 8157

uniapp(全端兼容) - 最新详细uniapp全平台植入使用echarts图表插件,引入 Echarts 图表及使用详细教程,提供各种图表使用示例(拒绝复杂的过程,附带详细的使用示例保姆级教程)

uniapp 微信小程序 echats 图表,uni-app小程序引用echarts,niapp 微信小程序引入echats教程,uniapp 使用echats图表,uniapp开发如何在微信小程序平台使用echats图表,uniapp开发的小程序中怎么用echats,在uni-app中编译到微信小程序如何使用echarts,UNIAPP微信小程序使用Echarts,uni-app微信小程序使用echarts,Uniapp小程序端使用echarts最详细的教程,uni-app中使用Echarts绘画图表,u

✅ 精选推荐文章 1万+

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

上一篇: android全平台下基于ffmpeg解码MP4视频文件为YUV文件
下一篇: android全平台基于ffmpeg解码本地MP4视频推流到RTMP服务器
handy周
handy周 领域专家: 操作系统技术领域 领域专家: 操作系统技术领域
博客等级 码龄14年 507粉丝 240原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值