/*
* 一笑奈何
* cn-yixiaonaihe.blog.csdn.net
*/#include <iostream>
#include <thread>
extern "C" {
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"
#include "libswresample/swresample.h"
}
using namespace std;
static double r2d(AVRational r)
{return r.den == 0 ? 0 : (double)r.num / (double)r.den;
}
void XSleep(int ms)
{//c++ 11chrono::milliseconds du(ms);this_thread::sleep_for(du);
}
int main(int argc, char *argv[])
{cout << "Test Demux FFmpeg.club" << endl;const char *url = "test.pcm";const char *outfile = "test.aac";//初始化封装库av_register_all();//初始化网络库 (可以打开rtsp rtmp http 协议的流媒体视频)avformat_network_init();//注册解码器avcodec_register_all();//1 打开音频编码器AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_AAC);if (!codec){cout << "avcodec_find_encoder NO" << endl;return -1;}AVCodecContext *c = avcodec_alloc_context3(codec);if (!codec){cout << "avcodec_alloc_context3 NO" << 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 NO" << endl;return -1;}cout << "avcodec_open2 OK" << endl;//2 打开输出封装上下文AVFormatContext *oc = NULL;avformat_alloc_output_context2(&oc, NULL,NULL,outfile);if (!oc){cout << "avformat_alloc_output_context2 NO" << 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, outfile, 1);//3 open io & write head ret=avio_open(&oc->pb, outfile, AVIO_FLAG_WRITE);if (ret<0){cout << "avio_open NO" << endl;return -1;}ret = avformat_write_header(oc,NULL);//44100 16位 双通道//4 创建音频重采样上下文//音频重采样 上下文初始化SwrContext *actx = swr_alloc();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);ret = swr_init(actx);if (ret != 0){char buf[1024] = { 0 };av_strerror(ret, buf, sizeof(buf) - 1);cout << "swr_init failed! :" << buf << 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 No :" << endl;return -1;}char *pcm = NULL;int readSize = frame->nb_samples * 2 * 2;pcm = new char[readSize];FILE *fp = fopen(url,"rb");for (;;){int len = fread(pcm, 1, readSize, fp);if (len <= 0)break;const uint8_t *data[1];data[0] = (uint8_t*)pcm;ret = swr_convert(actx,frame->data, frame->nb_samples, //输出data, frame->nb_samples); //输入if (len <= 0)break;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 音频封装进AAC文件pkt.stream_index = 0;pkt.pts = 0;pkt.dts = 0;ret = av_interleaved_write_frame(oc, &pkt);cout << "[" << len << "]";}delete pcm;//写入视频索引尾部信息av_write_trailer(oc);//主动关闭后才可以把缓冲区的内容写到文件avio_close(oc->pb);//清理空间av_frame_free(&frame);//先关闭后释放swr_close(actx);swr_free(&actx);//清理封装输出上下文avformat_free_context(oc);//关闭编码器avcodec_close(c);//清理编码器上下文avcodec_free_context(&c);fclose(fp);cout << "==================end===============" << endl;return 0;}