ffmpeg api 录音录像
时间: 2023-07-28 21:09:06 浏览: 102
使用FFmpeg API来录制音频和视频需要进行一些编程工作。以下是一个基本的示例来录制音频和视频:
```C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libavformat/avformat.h>
#include <libavdevice/avdevice.h>
int main() {
int ret;
// 注册所有的设备和格式
avdevice_register_all();
// 打开音频设备
AVFormatContext* audioFmtCtx = NULL;
ret = avformat_open_input(&audioFmtCtx, "default", av_find_input_format("alsa"), NULL);
if (ret < 0) {
fprintf(stderr, "无法打开音频设备: %s\n", av_err2str(ret));
return ret;
}
// 打开视频设备
AVFormatContext* videoFmtCtx = NULL;
ret = avformat_open_input(&videoFmtCtx, "/dev/video0", av_find_input_format("video4linux2"), NULL);
if (ret < 0) {
fprintf(stderr, "无法打开视频设备: %s\n", av_err2str(ret));
return ret;
}
// 创建输出文件上下文
AVFormatContext* outputFmtCtx = NULL;
ret = avformat_alloc_output_context2(&outputFmtCtx, NULL, NULL, "output.mp4");
if (!outputFmtCtx) {
fprintf(stderr, "无法创建输出文件上下文\n");
return AVERROR_UNKNOWN;
}
// 添加音频流
AVStream* audioStream = avformat_new_stream(outputFmtCtx, NULL);
if (!audioStream) {
fprintf(stderr, "无法创建音频流\n");
return AVERROR_UNKNOWN;
}
// 复制音频参数
avcodec_parameters_copy(audioStream->codecpar, audioFmtCtx->streams[0]->codecpar);
// 添加视频流
AVStream* videoStream = avformat_new_stream(outputFmtCtx, NULL);
if (!videoStream) {
fprintf(stderr, "无法创建视频流\n");
return AVERROR_UNKNOWN;
}
// 复制视频参数
avcodec_parameters_copy(videoStream->codecpar, videoFmtCtx->streams[0]->codecpar);
// 打开输出文件
ret = avio_open(&outputFmtCtx->pb, outputFmtCtx->filename, AVIO_FLAG_WRITE);
if (ret < 0) {
fprintf(stderr, "无法打开输出文件: %s\n", av_err2str(ret));
return ret;
}
// 写文件头
ret = avformat_write_header(outputFmtCtx, NULL);
if (ret < 0) {
fprintf(stderr, "无法写入文件头: %s\n", av_err2str(ret));
return ret;
}
// 录制音频和视频
AVPacket packet;
while (1) {
// 从音频设备读取音频
ret = av_read_frame(audioFmtCtx, &packet);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
if (ret < 0) {
fprintf(stderr, "无法从音频设备读取音频: %s\n", av_err2str(ret));
return ret;
}
// 写入音频包
packet.stream_index = audioStream->index;
ret = av_interleaved_write_frame(outputFmtCtx, &packet);
av_packet_unref(&packet);
if (ret < 0) {
fprintf(stderr, "无法写入音频包: %s\n", av_err2str(ret));
return ret;
}
}
while (1) {
// 从视频设备读取视频
ret = av_read_frame(videoFmtCtx, &packet);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
if (ret < 0) {
fprintf(stderr, "无法从视频设备读取视频: %s\n", av_err2str(ret));
return ret;
}
// 写入视频包
packet.stream_index = videoStream->index;
ret = av_interleaved_write_frame(outputFmtCtx, &packet);
av_packet_unref(&packet);
if (ret < 0) {
fprintf(stderr, "无法写入视频包: %s\n", av_err2str(ret));
return ret;
}
}
// 写文件尾
ret = av_write_trailer(outputFmtCtx);
if (ret < 0) {
fprintf(stderr, "无法写入文件尾: %s\n", av_err2str(ret));
return ret;
}
// 清理资源
avformat_close_input(&audioFmtCtx);
avformat_close_input(&videoFmtCtx);
avformat_free_context(audioFmtCtx);
avformat_free_context(videoFmtCtx);
avio_closep(&outputFmtCtx->pb);
avformat_free_context(outputFmtCtx);
return 0;
}
```
请注意,这只是一个简单的示例,您可能需要根据您的需求进行更多的自定义设置和错误处理。您还需要在编译时链接FFmpeg库并包含相关的头文件。有关更多详细信息和选项,请参考FFmpeg的文档和示例代码。
阅读全文