#include <iostream>
using namespace std;
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/avutil.h>
#include <libswresample/swresample.h>
}
#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"swscale.lib")
#pragma comment(lib,"swresample.lib")
int p = 0;
int main()
{
const char* inFile = "./file/testOut.wmv";
const char* oFile = "./file/out.aac";
//注册所有的封装器解封装器
av_register_all();
//注册所有的编码器和解码器
avcodec_register_all();
//1,打开音频编码器
AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_AAC);
if (!codec)
{
cout << "avcodec_find_encoder" << endl;
return -1;
}
//创建编码器上下文
AVCodecContext* c = avcodec_alloc_context3(codec);
if (!c)
{
cout << "avcodec_alloc_context3" << endl;
return -1;
}
//设置比特率
c->bit_rate = 64000;
//采样率
c->sample_rate = 44100;
c->sample_fmt = AV_SAMPLE_FMT_FLTP;
//通道类型
c->channel_layout = AV_CH_LAYOUT_STEREO;
//通道数
c->channels = 2;
//
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
int ret = avcodec_open2(c, codec, NULL);
if (ret < 0)
{
cout << "avcodec_open2" << endl;
return -1;
}
cout << "打开文件成功" << endl;
//2,打开输出封装的上下文
AVFormatContext *oc = NULL;
avformat_alloc_output_context2(&oc, NULL, NULL, oFile);
if (!oc)
{
cout << "avformat_alloc_output_context2" << endl;
return -1;
}
AVStream* st = avformat_new_stream(oc, NULL);
st->codecpar->codec_tag = 0;
avcodec_parameters_from_context(st->codecpar, c);
//打印信息
av_dump_format(oc, 0, oFile, 1); //索引是0,
//3,open io , write head
ret = avio_open(&oc->pb, oFile, AVIO_FLAG_WRITE);
if (ret < 0)
{
cout << "avio_open" << endl;
return -1;
}
ret = avformat_write_header(oc, NULL);
if (ret < 0)
{
cout << "avformat_write_header" << endl;
return -1;
}
//4,创建音频重采样上下文
SwrContext* actx = NULL;
actx = swr_alloc_set_opts(actx,
c->channel_layout, c->sample_fmt, c->sample_rate, //输出格式
AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, 44100, //输入格式
0, 0);
if (!actx)
{
cout << "swr_alloc_set_opts" << endl;
return -1;
}
ret = swr_init(actx);
if (ret<0)
{
cout << "swr_init" << endl;
return -1;
}
//5,打开输入音频文件,进行重采样
AVFrame* frame = av_frame_alloc();
frame->format = AV_SAMPLE_FMT_FLTP;
frame->channels = 2;
frame->channel_layout = AV_CH_LAYOUT_STEREO;
frame->nb_samples = 1024; //一帧音频存放的样本数量
ret = av_frame_get_buffer(frame, 0);
if (ret < 0)
{
cout << "av_frame_get_buffer" << endl;
return -1;
}
int readSize = frame->nb_samples * 2 * 2; //一次读取的大小,样本数*样本大小
char* pcm = new char[readSize];
FILE* fp = fopen(inFile, "rb");
for (;;)
{
int len = fread(pcm, 1, readSize, fp);
if (len <= 0)
break;
const uint8_t* data[1];
data[0] = (uint8_t*)pcm;
len = swr_convert(actx, frame->data, frame->nb_samples,
data, frame->nb_samples);
if (len <= 0)
break;
cout << "《" << len << "》";
//6,音频编码
AVPacket pkt;
av_init_packet(&pkt);
ret = avcodec_send_frame(c, frame);
if (ret != 0)
continue;
ret = avcodec_receive_packet(c, &pkt);
if (ret != 0)
continue;
//7,音频封装acc文件
pkt.stream_index = 0;
pkt.pts = 0;
pkt.dts = 0;
ret = av_interleaved_write_frame(oc, &pkt);
}
delete pcm;
pcm = NULL;
//写入视频索引
av_write_trailer(oc);
//关闭视频输出io
avio_close(oc->pb);
//清理封装输出上下文
avformat_free_context(oc);
//关闭编码器
avcodec_close(c);
//清理编码器上下文
avcodec_free_context(&c);
getchar();
return 0;
}
FFmpeg+SDL学习笔记4,音频编码(pcm to acc)
最新推荐文章于 2023-04-21 10:36:33 发布