FFmpeg实践记录六:【实战】音频采集
2021-05-11 本文已影响0人
MxlZlh
请注意以下命令/事例均基于Mac环境
FFmpeg采集音频
-
通过命令方式
//采集
ffmpeg -f avfoundation -i :0 out.wav
//播放
ffplay out.wav
-
通过API方式
![](https://img.haomeiwen.com/i3029567/b034920bcdc4e1e5.png)
![](https://img.haomeiwen.com/i3029567/4e6c1df6bd9c891c.png)
![](https://img.haomeiwen.com/i3029567/3aa88dcb5c86e664.png)
重要api讲解
av_read_frame //可以读取音频/视频数据
av_init_packet
av_packet_unref
av_packet_alloc //此方法先分配空间再调用av_init_packet
av_packet_free //此方法先调用av_packet_unref解引用再释放空间
事例
.h文件
#include <stdio.h>
#include "libavutil/avutil.h"
#include "libavdevice/avdevice.h"
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
void rec_audio(void);
.m文件
#include "testc.h"
void rec_audio() {
int ret = 0;
char errors[1024] = {0, };
AVFormatContext *fmt_ctx = NULL;
AVDictionary *options = NULL;
int count = 0;
AVPacket pkt;
//[[video device]:[audio device]]
char *devicename = ":0";
av_log_set_level(AV_LOG_DEBUG);
//注册设备
avdevice_register_all();
//设置采集方式
AVInputFormat *iformat = av_find_input_format("avfoundation");
//打开音频设备
if ((ret = avformat_open_input(&fmt_ctx, devicename, iformat, &options)) < 0) {
av_strerror(ret, errors, 1024);
fprintf(stderr, "Failed to open audio device, [%d]%s\n", ret, errors);
return;
}
//写入文件 w:写入 b:二进制 +:文件不存在就自动创建
char *out = "/Users/mac/Downloads/my_av_base.pcm";
FILE *outfile = fopen(out, "wb+");
av_init_packet(&pkt);
//读取音频数据
while ((ret = av_read_frame(fmt_ctx, &pkt)) == 0 && count++ < 500) {
//写入文件
fwrite(pkt.data, pkt.size, 1, outfile);
fflush(outfile);
av_log(NULL, AV_LOG_INFO, "pkt size is %d(%p), count=%d \n",pkt.size, pkt.data, count);
//释放资源
av_packet_unref(&pkt);
}
//关闭文件
fclose(outfile);
//关闭设备
avformat_close_input(&fmt_ctx);
av_log(NULL, AV_LOG_DEBUG, "finish!\n");
}
ViewController.swift
import Cocoa
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.setFrameSize(NSSize(width: 700, height: 300))
let btn = NSButton.init(title: "button", target: self, action: #selector(myfunc))
btn.frame = NSRect(x: 50, y: 60, width: 90, height: 30);
self.view.addSubview(btn)
}
@objc func myfunc() {
rec_audio()
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
播放
ffplay -ar 44100 -ac 2 -f f32le my_av_base.pcm