av_write_header - 样本格式错误

问题描述

我正在用 libav/ffmpeg 编写程序来下载网络广播流并使用 alsa 在声卡上播放。

我已经设法下载流并提取数据包和帧。

我在使用 av_write_header() 函数时遇到问题(根据此 https://www.ffmpeg.org/doxygen/3.2/group__lavf__encoding.html#details)我必须调用函数。它崩溃并给我以下错误

[alsa @ 0x55d7ba32e580] 不支持示例格式 0x15001

Number 0x15001 是十进制的 86017,这是该流使用的 MP3 格式 (AV_CODEC_ID_MP3) 的枚举 AVCodecID 中的索引。示例格式的索引为 3。我不明白为什么 libav 解析标头错误

这是我负责配置输出的部分代码

    avdevice_register_all();

    AVOutputFormat *output = av_guess_format("alsa",NULL,NULL);

    AVFormatContext *outputFormatContext = avformat_alloc_context();
    outputFormatContext->oformat = output;
    outputFormatContext->flags = AVFMT_NOFILE;

    AVStream *stream = avformat_new_stream(outputFormatContext,NULL);

    AVCodecParameters *oCodecParameters = avcodec_parameters_alloc();

    ret = avcodec_parameters_copy(oCodecParameters,iCodecParameters);
    if(ret < 0){
        printf("avformat_parameters_copy\n");
        exit(0);
    }

    stream->codecpar = oCodecParameters;

    if(avformat_write_header(outputFormatContext,NULL)<0){
        dumpParameters(stream->codecpar);
        printf("avformat_write_header\n");
        exit(0);
    }

完整代码在这里https://github.com/szymonbarszcz99/C-internet-radio

解决方法

看来在libav中我们不能做简单的复制。相反,我必须手动为其提供请求的参数。将 avcodec_parameters_copy() 更改为此

    AVCodecParameters *oCodecParameters = avcodec_parameters_alloc();
    oCodecParameters->format = 8;
    oCodecParameters->codec_type = 1;
    oCodecParameters->sample_rate = 44100;
    oCodecParameters->channels = 2;

    stream->codecpar = oCodecParameters;

解决了这个问题