ffmpeg音频解码重采样(立体声转成单声道)

#include 
#include 
extern "C" // 因为FFmpeg是纯C程序
{
#include 
#include 
#include 
#include 
#include 
#include    
#include       
#include          
#include       
#include 
#include 
};
using namespace std;
#define FRAME_SIZE 3200
#define SAMPLE_RATE 16000
int main()
{
    AVCodecContext	*pCodecCtx;
	AVCodec			*pCodec;
    AVPacket packet;
    char *input = "/workspace/src/ffmpegdemo/data/3.mp4";
    enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16;
    av_register_all();
    avformat_network_init();
    AVFormatContext* format = avformat_alloc_context();
    // 打开input文件
    if (avformat_open_input(&format, input, NULL, NULL) != 0) {
        return NULL;
    }
    if (avformat_find_stream_info(format, NULL) < 0) {
        return NULL;
    }
    // 找到input文件中的音频流
    int stream_index =- 1;
    for (int i=0; inb_streams; i++) {
        if (format->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
            stream_index = i;
            break;
        }
    }
    if (stream_index == -1) {
        return NULL;
    }
    AVStream* stream = format->streams[stream_index];
    pCodecCtx = format->streams[stream_index]->codec;
    // 找到解码器
    pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
    if(pCodec == NULL){
    	printf("Codec not found.\n");
    }
    if(avcodec_open2(pCodecCtx, pCodec,NULL)<0){
    	printf("Could not open codec.\n");
    }
    // 准备重采样
    struct SwrContext* swr = swr_alloc();
    av_opt_set_int(swr, "in_channel_count",  pCodecCtx->channels, 0);
    av_opt_set_int(swr, "out_channel_count", 1, 0);
    av_opt_set_int(swr, "in_channel_layout",  pCodecCtx->channel_layout, 0);
    av_opt_set_int(swr, "out_channel_layout", AV_CH_LAYOUT_MONO, 0);
    av_opt_set_int(swr, "in_sample_rate", pCodecCtx->sample_rate, 0);
    av_opt_set_int(swr, "out_sample_rate", SAMPLE_RATE, 0);
    av_opt_set_sample_fmt(swr, "in_sample_fmt",  pCodecCtx->sample_fmt, 0);
    av_opt_set_sample_fmt(swr, "out_sample_fmt", out_sample_fmt,  0);
    swr_init(swr);
    if (!swr_is_initialized(swr)) {
        fprintf(stderr, "Resampler has not been properly initialized\n");
        return NULL;
    }
    av_init_packet(&packet);
    // 初始化frame
    AVFrame* frame = av_frame_alloc();
    if (!frame) {
    	fprintf(stderr, "Error allocating the frame\n");
    	return NULL;
    }
    char *data = NULL;
    while (av_read_frame(format, &packet) >= 0) 
    {
        // 判断是否为音频
        if (packet.stream_index != stream_index)
        {
            continue;
        }
        int gotFrame;
        // 解码一帧音频
        if (avcodec_decode_audio4(pCodecCtx, frame, &gotFrame, &packet) < 0) {
            break;
        }
        if (!gotFrame) {
            continue;
        }
        uint8_t* buffer;
        av_samples_alloc((uint8_t**) &buffer, NULL, 1, frame->nb_samples,
        out_sample_fmt, 0);
        // 重采样
        int frame_count = swr_convert(swr, (uint8_t**) &buffer, frame->nb_samples, 
                                           (const uint8_t**) frame->data, frame->nb_samples);
        data = (char*) realloc(data, frame_count * sizeof(char));
        // 采样完的音频数据复制到data
        memcpy(data, buffer, frame_count * sizeof(char));
    }
    av_frame_free(&frame);
    swr_free(&swr);
    avcodec_close(pCodecCtx);
    avformat_free_context(format);
}

你可能感兴趣的:(ffmpeg)