本文主要是介绍NDKr20编译ffmpeg-4.2.2,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在前面,我们已经将ffmpeg引入到Android工程中去了,如果你还不知道如何在Android中使用ffmpeg,可以回头看看这篇文章:
将ffmpeg引入到Android Studio工程中
那么如何使用ffmeg对音视频做一些开发工作呢?今天我们学习来学习一下使用ffmpeg对音视频进行解封装。
我们先来看一张图:
从图中可以看出要想对音视频进行解码,首先需要的是对音视频进行解封装。
解封装主要是为了获取一些音视频的信息,比如时长,视频所使用的编码器,音频流的索引、视频流的索引等等。
我们用一张图展示一下解封装的步骤以及需要用到的一些相关API:
首先引入log库,定义一个宏,方便后面打印日志。
#ifndef FLYPLAYER_FLYLOG_H
#define FLYPLAYER_FLYLOG_H#include <android/log.h>//定义一个宏,使用log库输出日志#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,"FFMPEG",__VA_ARGS__)#endif //FLYPLAYER_FLYLOG_H
解封装的主要代码:
//引入ffmpeg的头文件
// 因为ffmpeg是纯C代码,要在cpp中使用则需要使用 extern "C"
extern "C" {
#include "libavutil/avutil.h"
#include <libavformat/avformat.h>
}/*** 将数据转换成double类型的一个方法* @param r* @return*/
static double r2d(AVRational r)
{return r.num==0||r.den == 0 ? 0 :(double)r.num/(double)r.den;
}extern "C"
JNIEXPORT jint JNICALL
Java_com_flyer_ffmpeg_FFmpegUtils_analyzeMedia(JNIEnv *env, jclass clazz, jstring media_path) {//初始化解封装av_register_all();//初始化网络avformat_network_init();//打开文件AVFormatContext *ic = NULL;const char *path = env->GetStringUTFChars(media_path, 0);int re = avformat_open_input(&ic,path,0,0);if(re != 0){LOGE("avformat_open_input failed!:%s",av_err2str(re));return -1;}LOGE("avformat_open_input %s success!",path);//获取流信息re = avformat_find_stream_info(ic,0);if(re != 0){LOGE("avformat_find_stream_info failed!");return -3;}LOGE("duration = %lld nb_streams = %d",ic->duration,ic->nb_streams);int fps = 0;int videoStream = -1;int audioStream = -1;// 有两个方法获取视频或者视频流的索引,一种是遍历,一种是使用自动探测的api// 通过遍历的方法获取索引for(int i = 0; i < ic->nb_streams; i++){AVStream *as = ic->streams[i];if(as->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){LOGE("视频数据");videoStream = i;fps = r2d(as->avg_frame_rate);LOGE("videoStream=%d,fps = %d,width=%d height=%d codeid=%d pixformat=%d",videoStream,fps,as->codecpar->width,as->codecpar->height,as->codecpar->codec_id,as->codecpar->format);}else if(as->codecpar->codec_type ==AVMEDIA_TYPE_AUDIO ){LOGE("音频数据");audioStream = i;LOGE("audioStream=%d,sample_rate=%d channels=%d sample_format=%d",audioStream,as->codecpar->sample_rate,as->codecpar->channels,as->codecpar->format);}}// 通过探测的方式获取索引//获取音频流信息audioStream = av_find_best_stream(ic,AVMEDIA_TYPE_AUDIO,-1,-1,NULL,0);LOGE("av_find_best_stream audioStream = %d",audioStream);env->ReleaseStringUTFChars(media_path, path);//关闭上下文avformat_close_input(&ic);LOGE("解封装成功","");return 0;
}
运行看看打印的日志有没有解封装成功:
最后如果你对音视频开发感兴趣可扫码关注,笔者在各个知识点学习完毕之后也会使用ffmepg从零开始编写一个多媒体播放器,包括本地播放及网络流播放等等。欢迎关注,后续我们共同探讨,共同进步。
这篇关于NDKr20编译ffmpeg-4.2.2的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!