ffmpeg录制音频 命令行与C++实现

关于音视频,看了很多的博客,发现都很难正确的打开设备与录制。然后就自己瞎搞,突然发现能正确的录制与打开了,故此记录一下。
一、官方wiki

https://trac.ffmpeg.org/wiki/Capture/ALSA
提取一句关于音频录制的命令:

ffmpeg -f alsa -channels 1 -sample_rate 44100 -i hw:0 -t 30 out.wav

linux选择alsa的设备,mac上是avfoundation,sample_rate指的是采样率,channels是通道数,视系统而定,笔者这里选择单通道会报错,错误如下:

[alsa @ 0x55b0f9f49780] cannot set channel count to 1 (Invalid argument)
hw:0: Input/output error

然后我修改成了双通道就ok了。这里还有一个坑就是插上耳机的时候,打开系统设置可以查看到相关的状态
ffmpeg录制音频 命令行与C++实现_第1张图片
主机分了两对插口MIC和SPK,一个是前置,一个是后置。MIC是麦克风,SPK是声音。坑就是无论-i 后面带的参数是什么,设备都无法正常打开,拔掉MIC的插口,设备就可以正常使用了,但是没麦接收音频录制下来,当然是什么都没有。这里卡了很久。所以就去官方wiki上查看相关参数,使用F6选择声卡,然而也并没有什么用。
ffmpeg录制音频 命令行与C++实现_第2张图片
报错信息是:
[alsa @ 0x55e15eb4b780] cannot open audio device hw:0 (Device or resource busy) hw:0: Input/output error
提示设备忙碌,麦克风被占用,但是拔了插都不行,重启也不行。最后发现正是因为打开了系统设置这个界面在占用中…,真的是吃了没文化的亏啊…
二、验证
使用ffplay out.wav播放一下视频验证就好了。
三、使用ffmpeg的库录制音频
1、安装apt install ffmpeg
至于其他的依赖库,缺什么补什么就好了
2、代码实现
头文件

//
// Created by 黑桃k on 2021/3/8.
//

#ifndef LEANCPP_AV_H
#define LEANCPP_AV_H
extern "C" {
#include "libavcodec/avcodec.h"
#include "libavdevice/avdevice.h"
#include "libavutil/common.h"
#include "libavutil/frame.h"
#include "libavformat/avformat.h"

};
#endif //LEANCPP_AV_H

主函数文件

#include 
#include "av.h"
using namespace std;

int main() {
    // register device
    avdevice_register_all();
    // set logger level
    av_log_set_level(AV_LOG_DEBUG);
    // get input device format
    AVInputFormat *format = av_find_input_format("alsa");
    // init context
    AVFormatContext *fmt_ctx = nullptr;
    std::string deviceName = "hw:0";
    AVDictionary *options = nullptr;
    // open audio device
    int ret = avformat_open_input(&fmt_ctx, deviceName.c_str(), format, &options);
    if (ret < 0) {
        std::cout << "Failed to open audio device!" << std::endl;
    }
    AVPacket ptk;
    av_init_packet(&ptk);
    string filepath = "test.pcm";
    FILE *out = fopen(filepath.c_str(), "wb");
    int count = 0;
    while (!ret && count++ < 1000) {
        ret = av_read_frame(fmt_ctx, &ptk);
        // write file
        fwrite(ptk.data,ptk.size,1,out);
        std::cout << "ptk.size:" << ptk.size << std::endl;
        std::cout << "count:" << count << std::endl;
        // release ptk
        av_packet_unref(&ptk);
    }
    fflush(out);
    fclose(out);
    // close device
    avformat_close_input(&fmt_ctx);

    std::cout << "Hello, World!" << std::endl;
    return 0;
}

CMakeList.txt

cmake_minimum_required(VERSION 3.17)
project(leanCpp)
set(CMAKE_CXX_STANDARD 14)
include_directories(include)
add_executable(leanCpp main.cpp include/av.h)
target_link_libraries(leanCpp avutil avdevice avformat avcodec)

测试:ffplay -ar 44100 -ac 2 -f s16le test.pcm
这里还是有坑的,代码默认的格式,笔者也不是很清楚,属于刚入坑的新手,后续阅读源码在更新吧。使用ffmpeg -formats | grep PCM 查看系统支持的pcm格式,然后试了s16le,发现可以正常播放了。
嗯嗯…记录一下这个坑,欢迎小白报团…

你可能感兴趣的:(音视频,c++,ffmpeg)