ffmpeg音频编码
·
ffmpeg音频编码,程序如下:
extern "C"
{
#include <libavutil/avutil.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
}
#pragma warning(disable:4996)
// check sample format
int check_sample_fmt(const AVCodec *codec, AVSampleFormat sample_fmt)
{
const AVSampleFormat *p = codec->sample_fmts;
while (*p != AV_SAMPLE_FMT_NONE)
{
if (*p == sample_fmt)
{
return 1;
}
p++;
}
return 0;
}
int select_sample_rate(const AVCodec *codec)
{
const int *rate = codec->supported_samplerates;
if (!rate) {
return 44100;
}
int best_samplerate = 0;
while (*rate)
{
if (best_samplerate == 0 || abs(44100 - *rate) < (44100 - best_samplerate))
{
best_samplerate = *rate;
}
rate++;
}
return best_samplerate;
}
uint64_t select_channel_layout(const AVCodec *codec)
{
uint64_t best_ch_layout = 0;
int best_nb_channels = 0;
const uint64_t *p = codec->channel_layouts;
if (!p)
{
return AV_CH_LAYOUT_STEREO;
}
while (*p)
{
int nb_channels = av_get_channel_layout_nb_channels(*p);
if (nb_channels > best_nb_channels) {
best_ch_layout = *p;
best_nb_channels = nb_channels;
}
p++;
}
return best_ch_layout;
}
int main()
{
//parameter
int ret = 0;
char errors[200] = { 0 };
const char *destMedia = "out/test.mp3";
//
av_log_set_level(AV_LOG_INFO);
av_register_all();
//获取指定编解码器
AVCodec *avCodec = avcodec_find_encoder(AV_CODEC_ID_MP2);
//获取编解码上下文
AVCodecContext *avCodecCtx = avcodec_alloc_context3(avCodec);
//设置参数
avCodecCtx->bit_rate = 64000;
avCodecCtx->sample_fmt = AV_SAMPLE_FMT_S16;
if (!check_sample_fmt(avCodec, avCodecCtx->sample_fmt)) {
av_log(NULL, AV_LOG_WARNING, "not support sample format==%d\n", avCodecCtx->sample_fmt);
return -1;
}
avCodecCtx->sample_rate = select_sample_rate(avCodec);
avCodecCtx->channel_layout = select_channel_layout(avCodec);
avCodecCtx->channels = av_get_channel_layout_nb_channels(avCodecCtx->channel_layout);
//打开编码器
ret = avcodec_open2(avCodecCtx, avCodec, NULL);
//初始化frame, packet
AVFrame *avFrame = av_frame_alloc();
avFrame->nb_samples = avCodecCtx->frame_size;
avFrame->format = avCodecCtx->sample_fmt;
avFrame->channel_layout = avCodecCtx->channel_layout;
ret = av_frame_get_buffer(avFrame, 0);
float t = 0;
float tincr = 2.0f * M_PI * 440 / avCodecCtx->sample_rate;
AVPacket avPacket;
av_init_packet(&avPacket);
int getPacket = 0;
FILE *outFile = fopen(destMedia, "wb");
for (int i = 0; i < 200; i++)
{
av_packet_unref(&avPacket);
ret = av_frame_make_writable(avFrame);
//自己创造音频数据
uint8_t *samples = avFrame->data[0];
for (int j = 0; j < avCodecCtx->frame_size; j++)
{
samples[2 * j] = sin(t) * 10000;
for (int k = 1; k < avCodecCtx->channels; k++)
{
samples[2 * j + k] = samples[2 * j];
}
t += tincr;
}
//编码
ret = avcodec_encode_audio2(avCodecCtx, &avPacket, avFrame, &getPacket);
if (ret < 0) {
av_strerror(ret, errors, 200);
av_log(NULL, AV_LOG_WARNING, "avcodec_encode_audio2 error: ret=%d, msg=%s\n", ret, errors);
return ret;
}
if (getPacket)
{
fwrite(avPacket.data, 1, avPacket.size, outFile);
}
}
//释放资源
av_packet_unref(&avPacket);
av_frame_free(&avFrame);
avcodec_free_context(&avCodecCtx);
if (outFile) {
fclose(outFile);
}
return 0;
}
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)