音视频-ffmpeg录制PCM

主要步骤

  • 注册设备 avdevice_register_all();
  • 获取输入格式对象 av_find_input_format
  • 打开设备 avformat_open_input
  • 采集数据 av_read_frame
  • 释放资源 avformat_close_input

===>

注册设备

main.cpp

#include "mainwindow.h"
#include <QApplication>

extern "C" {
#include <libavdevice/avdevice.h>
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    // 初始化libavdevice 并注册所有输入和输出设备 , 只需要注册一次就可以了
    avdevice_register_all();
    return a.exec();
}

  • 获取输入格式对象 av_find_input_format
  • 打开设备 avformat_open_input
  • 采集数据 av_read_frame
  • 释放资源 avformat_close_input


#define FMT_NAME "avfoundation"
#define DEVICE_NAME ":0"
#define FILEPATH "/Users/lumi/Desktop/"
#define FILENAME "record_to_pcm.pcm"

void AudioThread::run()
{
    qDebug() << this << "开始执行----------";
  
    // 获取输入格式对象
    AVInputFormat *fmt = av_find_input_format(FMT_NAME);
    if (!fmt) {
        qDebug() << "获取输入格式对象失败" << FMT_NAME;
        return;
    }
    qDebug() << "fmt : " << fmt;

    // 格式上下文(将来可以利用上下文操作设备)
    AVFormatContext *ctx = nullptr;
    // 打开设备
    int ret = avformat_open_input(&ctx, DEVICE_NAME, fmt, nullptr);
    if (ret < 0) {
        char errbuf[1024];
        av_strerror(ret, errbuf, sizeof (errbuf));
        qDebug() << "打开设备失败" << errbuf;
        return;
    }

    qDebug() << "ret : " << ret;


    // 打印一下录音设备的参数信息
    showSpec(ctx);

    // 文件名
    QString filename = FILEPATH;

//    filename += QDateTime::currentDateTime().toString("MM_dd_HH_mm_ss");
//    filename += ".pcm";

    filename += FILENAME;
    QFile file(filename);

    // 打开文件
    // WriteOnly:只写模式。如果文件不存在,就创建文件;如果文件存在,就会清空文件内容
    if (!file.open(QFile::WriteOnly)) {
        qDebug() << "文件打开失败" << filename;

        // 关闭设备
        avformat_close_input(&ctx);
        return;
    }

    // 数据包
    AVPacket pkt;
    while (!isInterruptionRequested()) {
        // 不断采集数据
        ret = av_read_frame(ctx, &pkt);

        if (ret == 0) { // 读取成功
            // 将数据写入文件
            file.write((const char *) pkt.data, pkt.size);
        } else if (ret == AVERROR(EAGAIN)) { // 资源临时不可用
            continue;
        } else { // 其他错误
            char errbuf[1024];
            av_strerror(ret, errbuf, sizeof (errbuf));
            qDebug() << "av_read_frame error" << errbuf << ret;
            break;
        }
    }

    // 释放资源
    // 关闭文件
    file.close();

    // 关闭设备
    avformat_close_input(&ctx);
    qDebug() << this << "正常结束----------";
}

demo: https://github.com/itmatter/Audio_Vedio_Tutorial/tree/main/1_record_to_pcm

使用ffmpeg 播放 PCM文件

liguangdeMBP:Desktop lumi$ ffplay -ar 44100 -ac 2 -f f32le record_to_pcm.pcm

ffplay version 4.3.2 Copyright (c) 2003-2021 the FFmpeg developers
  built with Apple clang version 12.0.0 (clang-1200.0.32.29)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3.2_3 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
[f32le @ 0x7fab1900ae00] Estimating duration from bitrate, this may be inaccurate
Input #0, f32le, from 'record_to_pcm.pcm':
  Duration: 00:00:04.06, bitrate: 2822 kb/s
    Stream #0:0: Audio: pcm_f32le, 44100 Hz, 2 channels, flt, 2822 kb/s

代码录制的时候并没有设定具体的采样格式, 采样率, 声道数. 这些都是默认的. 怎么获取这些默认的值. 参考 音视频-ffmpeg命令行简单使用 通过指定设备录音ffmpeg -f avfoundation -i :0 out.wav可以看到

Input #0, avfoundation, from ':0':
  Duration: N/A, start: 120742.093946, bitrate: 2822 kb/s
    Stream #0:0: Audio: pcm_f32le, 44100 Hz, stereo, flt, 2822 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_f32le (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help

默认的输入参数就是:
采样格式 : pcm_s16le
采样率 : 44100
声道数 : 2 channels,

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容