android ffmpeg 视频采集,FFmpeg编程开发笔记 —— Android环境使用FFmpeg录制视频

本文介绍了在Android环境下使用FFmpeg进行视频录制的完整流程,包括初始化FFmpeg、打开音频流和视频流、编码音频和视频、写入文件以及关闭媒体流等关键步骤。详细讲解了每个步骤的实现代码,为Android开发者提供了实用的FFmpeg视频录制指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天我们来谈谈Android 环境下,使用FFmpeg录制视频的流程。

基本流程解析

使用FFmpeg录制视频的流程大体如下:

1、初始化FFmpeg

2、打开音频流、视频流

3、将PCM编码为AAC

4、将YUV编码为H264

5、写入文件

6、写入文件尾部信息

7、关闭媒体流

初始化FFmpeg

初始化FFmpeg,主要是有一下几个步骤:

1、注册所有的编码器

2、分配输出格式上下文(AVFormatContext)

3、打开视频流,并初始化视频编码器

4、打开音频流,并初始化音频编码器

5、打开视频编码器

6、打开音频编码器

7、写入文件头不信息

整个过程实现代码如下:

/**

* 初始化编码器

* @return

*/

bool CainEncoder::initEncoder() {

if (isInited) {

return true;

}

do {

AVDictionary *opt = NULL;

int ret;

av_log_set_callback(ffmpeg_log);

// 注册

av_register_all();

// 分配输出媒体上下文

avformat_alloc_output_context2(&fmt_ctx, NULL, NULL, mOutputFile);

if (fmt_ctx == NULL) {

ALOGE("fail to avformat_alloc_output_context2 for %s", mOutputFile);

break;

}

// 获取AVOutputFormat

fmt = fmt_ctx->oformat;

// 使用默认格式编码器视频流,并初始化编码器

if (fmt->video_codec != AV_CODEC_ID_NONE) {

addStream(&video_st, fmt_ctx, &video_codec, fmt->video_codec);

have_video = true;

}

// 使用默认格式编码器音频流,并初始化编码器

if (fmt->audio_codec != AV_CODEC_ID_NONE && enableAudio) {

addStream(&audio_st, fmt_ctx, &audio_codec, fmt->audio_codec);

have_audio = true;

}

if(!have_video && !have_audio) {

ALOGE("no audio or video codec found for the fmt!");

break;

}

// 打开视频编码器

if (have_video) {

openVideo(video_codec, &video_st, opt);

}

// 打开音频编码器

if (have_audio) {

openAudio(audio_codec, &audio_st, opt);

}

// 打开输出文件

ret = avio_open(&fmt_ctx->pb, mOutputFile, AVIO_FLAG_READ_WRITE);

if (ret < 0) {

ALOGE("Could not open '%s': %s", mOutputFile, av_err2str(ret));

break;

}

// 写入文件头部信息

ret = avformat_write_header(fmt_ctx, NULL);

if (ret < 0) {

ALOGE("Error occurred when opening output file: %s", av_err2str(ret));

break;

}

isInited = true;

} while (0);

// 判断是否初始化成功,如果不成功,则需要重置所有状态

if (!isInited) {

reset();

}

return isInited;

}

其中,打开媒体流的方法如下:

/**

* 添加码流

* @param ost

* @param oc

* @param codec

* @param codec_id

* @return

*/

bool CainEncoder::addStream(OutputStream *ost, AVFormatContext *oc, AVCodec **codec,

enum AVCodecID codec_id) {

AVCodecContext *context;

// 查找编码器

*codec = avcodec_find_encoder(codec_id);

if (!(*codec)) {

ALOGE("Could not find encoder for '%s'\n", avcodec_get_name(codec_id));

return false;

}

// 创建输出码流

ost->st = avformat_new_stream(oc, *codec);

if (!ost->st) {

ALOGE("Could not allocate stream\n");

return false;

}

// 绑定码流的ID

ost->st->id = oc->nb_streams - 1;

// 创建编码上下文

context = avcodec_alloc_context3(*codec);

if (!context) {

ALOGE("Could not alloc an encoding context\n");

return false;

}

// 绑定编码上下文

ost->enc = context;

// 判断编码器的类型

switch ((*codec)->type) {

// 如果创建的是音频码流,则设置音频编码器的参数

case AVMEDIA_TYPE_AUDIO:

context->sample_fmt = (*codec)->sample_fmts

? (AVSampleFormat) (*codec)->sample_fmts[0]

: AV_SAMPLE_FMT_S16;

context->bit_rate = mAudioBitRate;

conte

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值