FFmpeg实战:从设备采集音频

博客围绕FFmpeg音频编码解码展开,虽未给出具体内容,但可知重点在于利用FFmpeg进行音频的编码与解码操作,这在音视频处理领域有重要应用。
//
// Created by chaisy on 2020/11/14.
//

#include <libavutil/log.h>
#include <libavformat/avformat.h>
#include <libavdevice/avdevice.h>
#include <stdio.h>
#include <assert.h>

static void simple_capture_audio()
{
    /*
     * 输入设备列表
     * libavdevice/indev_list.c
     * static const AVInputFormat * const indev_list[] = {
     *      &ff_avfoundation_demuxer,
     *      &ff_lavfi_demuxer,
     *      NULL };
     *
     * 输出设备列表
     * libavdevice/outdev_list.c
     * static const AVOutputFormat * const outdev_list[] = {
     *      &ff_audiotoolbox_muxer,
     *      &ff_opengl_muxer,
     *      &ff_sdl2_muxer,
     *      NULL };
     *
     * 封装器列表
     * libavformat/muxer_list.c
     * static const AVOutputFormat * const muxer_list[] = {
     *      &ff_a64_muxer,
     *      &ff_ac3_muxer,
     *      &ff_adts_muxer,
     *      &ff_adx_muxer,
     *      ...,
     *      NULL };
     *
     * 解封装器列表
     * libavformat/demuxer_list.c
     * static const AVInputFormat * const demuxer_list[] = {
     *      &ff_aa_demuxer,
     *      &ff_aac_demuxer,
     *      &ff_aax_demuxer,
     *      &ff_ac3_demuxer,
     *      ...,
     *      NULL };
     *
     * avdevice_register_all函数就是将以上数据进行注册
     * */
    avdevice_register_all();

    // 从avdevice_register_all函数注册的输入设备和解封装器列表中进行搜索,并返回有参数short_name指定的数据
    // short_name参数的取值可以查阅上述indev_list和demuxer_list数组中每个成员的name属性的值
    AVInputFormat *input_format = av_find_input_format("avfoundation");
    if (!input_format) {
        av_log(NULL, AV_LOG_ERROR, "av_find_input_format failed.");
        return;
    }

    // 分配AVFormatContext
    AVFormatContext *format_context = avformat_alloc_context();
    if (!format_context) {
        av_log(NULL, AV_LOG_ERROR, "avformat_alloc_context failed.");
        return;
    }

    AVDictionary *options = NULL;

    // avformat_open_input会执行如下判断
    // if (format_context == NULL) format_context = avformat_alloc_context();
    // url 参数指定输入数据,可以是本地文件、rtmp流、rtsp流、rtp流等
    // fmt 参数是有效值,则直接使用该fmt进行输入数据的解析,否则会自动解析url参数指定的数据,来判断fmt应该是什么数据
    // options 参数可以设置采样率、采样大小、分辨率等信息
    //      具体内容可通过fmt结构中的priv_class字段中的options参数查看

    int ret = avformat_open_input(&format_context, ":0", input_format, NULL);
    if (ret) {
        av_log(NULL, AV_LOG_ERROR, "avformat_open_input failed, error:%s", av_err2str(ret));
        return;
    }

    AVPacket *pkt = av_packet_alloc();
    pkt->data = NULL;
    pkt->size = 0;

    FILE *output_fd = fopen("out.pcm", "wb+");
    assert(output_fd);

    while (1) {
        ret = av_read_frame(format_context, pkt);
        if (ret < 0) {
            if (ret == -35) {
                continue;
            }

            break;
        }
        fwrite(pkt->data, pkt->size, 1, output_fd);
        fflush(output_fd);
        av_packet_unref(pkt);
    }

    av_packet_free(&pkt);
    avformat_close_input(&format_context);
}

int main(int argc, char *argv[])
{
    simple_capture_audio();
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值