android-studio使用cmake编译ffmpeg实践

音视频实践学习

本例使用的是合并的libffmpeg库,可参考之前的实践操作 android全平台编译ffmpeg合并为单个库实践

目录

配置环境

操作系统: ubuntu 16.05

注意: ffmpeg库的编译使用的是android-ndk-r10e版本,使用高版本编译会报错

android-studio工程中配合cmake使用的版本则是android-ndk-r16b版本

新建工程ffmpeg-single-hello

  • 配置build.gradle如下
android {
    ......
    defaultConfig {
        ......
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
            ndk {
                abiFilters "armeabi-v7a"
            }
        }
        sourceSets {
            main {
                //库地址
                jniLibs.srcDirs = ['libs']
            }
        }
    }
    ......
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}
  • 新建CMakeLists.txt文件,配置如下

cmake_minimum_required(VERSION 3.4.1)

add_library(ffmpeg-hello
           SHARED
           src/main/cpp/ffmpeg_hello.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)

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

笔者这里考虑到后续的都是基于同一个libffmpeg.so库,因此不必每个module都放置一个,因此单独分离了一个组件ffmpeg-single,将所需要的头文件和库放置在libs目录
其他的单个库例子则都是依赖这个库

  • 新建类FFmpegHello.java
package com.onzhou.ffmpeg.hello;

public class FFmpegHello {

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

    public native String urlprotocolinfo();

    public native String avformatinfo();

    public native String avcodecinfo();

    public native String avfilterinfo();

    public native String configurationinfo();

}
  • src/main/cpp目录新建源文件ffmpeg_hello.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    "FFmpegHello"
#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

JNIEXPORT jstring JNICALL Java_com_onzhou_ffmpeg_hello_FFmpegHello_urlprotocolinfo
  (JNIEnv * env, jobject obj){

    char info[40000]={0};
	av_register_all();

	struct URLProtocol *pup = NULL;
	//input
	struct URLProtocol **p_temp = &pup;
	avio_enum_protocols((void **)p_temp, 0);
	while ((*p_temp) != NULL){
		sprintf(info, "%s[in ][%10s]\n", info, avio_enum_protocols((void **)p_temp, 0));
	}
	pup = NULL;
	//output
	avio_enum_protocols((void **)p_temp, 1);
	while ((*p_temp) != NULL){
		sprintf(info, "%s[out][%10s]\n", info, avio_enum_protocols((void **)p_temp, 1));
	}
	LOGE("%s", info);
	return (*env)->NewStringUTF(env, info);
}


JNIEXPORT jstring JNICALL Java_com_onzhou_ffmpeg_hello_FFmpegHello_avformatinfo
  (JNIEnv * env, jobject obj){

    char info[40000] = { 0 };

	av_register_all();

	AVInputFormat *if_temp = av_iformat_next(NULL);
	AVOutputFormat *of_temp = av_oformat_next(NULL);
	//input
	while(if_temp!=NULL){
		sprintf(info, "%s[in ][%10s]\n", info, if_temp->name);
		if_temp=if_temp->next;
	}
	//output
	while (of_temp != NULL){
		sprintf(info, "%s[out][%10s]\n", info, of_temp->name);
		of_temp = of_temp->next;
	}
	LOGE("%s", info);
	return (*env)->NewStringUTF(env, info);
}


JNIEXPORT jstring JNICALL Java_com_onzhou_ffmpeg_hello_FFmpegHello_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("%s", info);
	return (*env)->NewStringUTF(env, info);
}

JNIEXPORT jstring JNICALL Java_com_onzhou_ffmpeg_hello_FFmpegHello_avfilterinfo
  (JNIEnv * env, jobject obj){

    char info[40000] = { 0 };

	avfilter_register_all();

	AVFilter *f_temp = (AVFilter *)avfilter_next(NULL);
	while (f_temp != NULL){
		sprintf(info, "%s[%10s]\n", info, f_temp->name);
	}
	LOGE("%s", info);
	return (*env)->NewStringUTF(env, info);
}


JNIEXPORT jstring JNICALL Java_com_onzhou_ffmpeg_hello_FFmpegHello_configurationinfo
  (JNIEnv * env, jobject obj){

    char info[10000] = { 0 };
	av_register_all();

	sprintf(info, "%s\n"avcodec_configuration());

	LOGE("%s", info);
	return (*env)->NewStringUTF(env, info);
}
  • 编译打包运行,输出如下信息:

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

参考:
https://blog.csdn.net/leixiaohua1020/article/details/47008825

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: obs-studio的编译过程是将源代码转换为可执行文件的过程。对于obs-studio而言,它的编译过程涉及多个步骤。 首先,需要将编写的源代码保存为合适的文件格式,通常是使用C++语言进行开发。在编写代码时,需要考虑到obs-studio的特定要求和功能需求。 其次,在编译过程中,需要使用编译器来将源代码转换为机器语言。obs-studio常用的编译器包括GNU编译器集合(GCC)和Clang。编译过程中,编译器会检查代码中的语法错误和逻辑错误,并生成相应的目标文件。 然后,将生成的目标文件与必要的库文件进行链接。obs-studio依赖于许多外部库,如FFmpeg、libobs和libobs-scripting。链接过程的目的是将这些库文件与目标文件进行连接,形成完整的可执行文件。 最后,进行测试和调试。通过测试和调试,可以发现并解决代码中的错误和问题,确保obs-studio能够正常运行并拥有所需功能。 总结来说,obs-studio的编译过程包括保存源代码、使用编译器进行编译、链接库文件以及进行测试和调试。这些步骤将源代码转换为可执行文件,使obs-studio能够顺利运行。 ### 回答2: obs-studio是一款开源的跨平台音视频录制和直播软件。下面将用300字中文回答obs-studio编译过程。 obs-studio的编译过程分为几个主要步骤: 1. 准备环境:首先需要安装相应的编译工具和依赖库。这些工具和库包括cmake、git、gcc等。安装完成后需要进行相关配置,如设置环境变量等。 2. 下载源代码:使用git从obs-studio的官方仓库下载最新的源代码。可以选择稳定版本或开发版,然后通过指定分支或标签来获取对应的代码。 3. 生成编译配置:使用cmake生成编译所需的配置文件。这些配置文件会指明编译器、依赖库路径、编译选项等。 4. 编译代码:运行指定的编译命令,如make或ninja。这将根据配置文件中的指示编译源代码,并生成对应的可执行文件。 5. 安装可执行文件:通过运行make install或ninja install命令,将编译生成的可执行文件和相关的资源文件复制到系统指定的目录中。 6. 设置环境:根据需要,可能需要进行一些环境的配置。比如,设置obs-studio的路径、输入输出设备的选择、直播平台的账号配置等。 综上所述,obs-studio的编译过程包括准备环境、下载源代码、生成配置、编译代码、安装可执行文件和设置环境等步骤。这样就能够成功地将obs-studio软件编译成可用的版本,以供音视频录制和直播等用途。 ### 回答3: OBS-Studio是一款开源的视频录制和直播软件,可以在Windows、Mac和Linux操作系统上使用编译过程通常包括以下几个步骤: 1. 首先,需要准备编译所需的软件和工具。这包括安装C++编译器、CMake、Git和其他相关的库和依赖项。 2. 接下来,从OBS-Studio的官方GitHub页面上克隆或下载源代码。可以使用Git命令`git clone`或直接下载压缩文件。 3. 一旦源代码被获取,就可以开始配置编译环境。在命令行中导航到源代码的根目录,并执行CMake命令来生成Makefile文件。 4. 在生成的Makefile文件中,可以设置一些选项,如编译类型(Debug或Release)、安装目录等。 5. 确定好编译选项后,就可以运行Make命令进行编译了。这个过程可能需要一些时间,取决于计算机性能和源代码的规模。 6. 编译完成后,将生成可执行文件和相关的库文件。可以通过运行编译后的可执行文件来启动OBS-Studio。 总体来说,OBS-Studio的编译过程相对较简单,但需要一些基本的编译知识和工具的使用经验。通过正确配置编译环境,并按照编译流程进行操作,就可以成功地编译出OBS-Studio的可执行文件,并开始使用这款强大的视频录制和直播软件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值