基于vs2017 vc++  ffmpeg4.0.2下测试

ffmpeg 环境配置请百度(vs2017 ffmpeg )图像和声音请安装dshow便于查找

部分方法在https://blog.csdn.net/Java_lilin/article/details/85118365中查找

 头文件参考上篇教程

static int test2() {
    
    AVFormatContext *formatCtx = avformat_alloc_context();
    AVInputFormat *ifmt = av_find_input_format(\"dshow\");//设备类型
    AVDictionary* options = NULL;
    //av_dict_set(&options, \"video_size\",\"1920*1080\",0);//大小  默认全部
    av_dict_set(&options, \" rate\", \"15\", 0);//帧lu

    if (avformat_open_input(&formatCtx, \"audio=virtual-audio-capturer\", ifmt, &options) != 0) {
    /*不通过dshow的设备查找
    wchar_t wt[] = L\"audio=内置麦克风 (Conexant SmartAudio HD)\";
    char * psDevName = dup_wchar_to_utf8(wt);
    if (avformat_open_input(&formatCtx, psDevName, ifmt, &options) != 0) {
    */

        printf(\"open input device fail\\n\");
        return -1;
    }
    av_dict_free(&options);

    if (avformat_find_stream_info(formatCtx, NULL) < 0) {
        printf(\"avformat_find_stream_info faill\\n\");
        return -1;
    }
    if (formatCtx->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
        printf(\"no find stream info\\n\");
        return -1;
    }
    //查找解密器
    AVCodec *codec = avcodec_find_decoder(formatCtx->streams[0]->codecpar->codec_id);
    if (codec == NULL) {
        printf(\"codec not found\\n\");
        return -1;
    }
    AVCodecContext *ctx = avcodec_alloc_context3(codec);
    avcodec_parameters_to_context(ctx, formatCtx->streams[0]->codecpar);
    if (avcodec_open2(ctx, codec, NULL) < 0) {
        printf(\"codec not open\\n\");
        return -1;
    }
     
    AV * = alloc_audio_ ((AVSampleFormat)formatCtx->streams[0]->codecpar->format, formatCtx->streams[0]->codecpar->channel_layout, formatCtx->streams[0]->codecpar->channels, formatCtx->streams[0]->codecpar->sample_rate,   formatCtx->streams[0]->codecpar-> _size);
    //目标
    ctx->channel_layout = av_get_default_channel_layout(ctx->channels); 
    SwrContext *swr = swr_alloc();
    av_opt_set_int(swr, \"in_channel_count\", ctx->channels, 0);
    av_opt_set_int(swr, \"in_channel_layout\", ctx->channel_layout, 0);
    av_opt_set_int(swr, \"in_sample_rate\", ctx->sample_rate, 0);
    av_opt_set_sample_fmt(swr, \"in_sample_fmt\", ctx->sample_fmt, 0);
    int desc_channel_layout = 3;
    int desc_channel_count = 2;
    int desc_sample_rate = 44100;
    AVSampleFormat desc_fmt = AV_SAMPLE_FMT_S16;
    av_opt_set_int(swr, \"out_channel_count\", desc_channel_count, 0);
    av_opt_set_int(swr, \"out_channel_layout\", desc_channel_layout, 0);
    av_opt_set_int(swr, \"out_sample_rate\", desc_sample_rate, 0);
    av_opt_set_sample_fmt(swr, \"out_sample_fmt\", desc_fmt, 0);

    printf(\"\\n声道%d,采样率%d格式%d----》声道%d,采样率%d格式%d\\n\",  ctx->channels,ctx->sample_rate,
        ctx->sample_fmt, desc_channel_count, desc_sample_rate, desc_fmt);
    int DES_NB_SAMPLES = 1024;
    AV *out = alloc_audio_ (desc_fmt, desc_channel_layout, desc_channel_count, desc_sample_rate, DES_NB_SAMPLES);
    AV *new = alloc_audio_ (desc_fmt, desc_channel_layout, desc_channel_count, desc_sample_rate, 0);
    AV *new 2= alloc_audio_ (desc_fmt, desc_channel_layout, desc_channel_count, desc_sample_rate, 0);

    AVAudioFifo *fifo = av_audio_fifo_alloc(desc_fmt, desc_channel_count,10240);
    
    FILE *file = NULL;
    fopen_s(&file, \"C:\\\\Users\\\\lilin\\\\Desktop\\\\1.pcm\",\"wb\");//ffplay -ar 44100 -channels 2 -f s16le -i 1.pcm或用Audacity 播放

    int fnum = 500;
    while (fnum--) {
        int size = av_audio_fifo_size(fifo);
        if (size >= DES_NB_SAMPLES) {//超过
            printf(\"\\n第一次超过\\n\");
            size = DES_NB_SAMPLES;
            av_audio_fifo_read(fifo, (void**)out ->data, size);
            //完整
            
            //写文件
            fwrite(out ->data[0],size,desc_channel_count*av_get_bytes_per_sample(desc_fmt),file); 
            continue;
        }

        AVPacket packet = { 0 };
        av_init_packet(&packet);
        if (av_read_ (formatCtx, &packet) >= 0) {
            avcodec_send_packet(ctx, &packet);
            if (avcodec_receive_ (ctx, ) < 0) {
                printf(\"audio decode error\\n\");
            }
            else {
                printf(\"采集到音频\"); // 
                swr_convert_ (swr,new , );
                av_audio_fifo_write(fifo, (void**)new ->data, new ->nb_samples);

                int64_t dealy = swr_get_delay(swr, desc_sample_rate); 
                if(dealy>0){
                    swr_convert_ (swr, new 2,NULL);
                    av_audio_fifo_write(fifo, (void**)new 2->data, new 2->nb_samples);
                }
                //这里可以判断下fifo里的数量是否够1024
                int size = av_audio_fifo_size(fifo);
                if (size < DES_NB_SAMPLES) {
                    //数据不够
                    av_packet_unref(&packet);
                    continue;
                }
                size = DES_NB_SAMPLES;//够了
                av_audio_fifo_read(fifo, (void**)out ->data,size);//固定大小的
                 
                //写文件
                fwrite(out ->data[0], size, desc_channel_count*av_get_bytes_per_sample(desc_fmt), file);

            }

        }
        av_packet_unref(&packet);
    }

    av_ _free(& );
    av_ _free(&new );
    av_ _free(&new 2);
    av_ _free(&out );
    av_audio_fifo_free(fifo);
    avcodec_free_context(&ctx);
    avformat_close_input(&formatCtx);

    fclose(file);
    return 0;
}

 

 

int main(){

    printf(\"ok:%d\\n\", avcodec_version());
    avdevice_register_all(); 

   test2();

}

收藏 打印