从音频那篇文章中可以知道,使用avfoundation 可以录制语音,但是事实上也是可以录制视频的,这篇文章会介绍一下如何操控录制视频
1.命令行录制
1.1查看avfoundation支持的设备
✘ songlin@feng-sl ~/audio/YUV master ± ffmpeg -f avfoundation -list_devices true -i ''
ffmpeg version 4.3.2 Copyright (c) 2000-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_4 --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
[AVFoundation indev @ 0x7f928cc04400] AVFoundation video devices:
[AVFoundation indev @ 0x7f928cc04400] [0] FaceTime HD Camera
[AVFoundation indev @ 0x7f928cc04400] [1] Capture screen 0
[AVFoundation indev @ 0x7f928cc04400] [2] Capture screen 1
[AVFoundation indev @ 0x7f928cc04400] AVFoundation audio devices:
[AVFoundation indev @ 0x7f928cc04400] [0] Built-in Microphone
从上面输出信息中可以看到0号设备就是Mac自带的摄像头
1.2 查看avfoundation支持的参数
✘ songlin@feng-sl ~/audio/YUV master ± ffmpeg -h demuxer=avfoundation
ffmpeg version 4.3.2 Copyright (c) 2000-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_4 --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
Demuxer avfoundation [AVFoundation input device]:
AVFoundation indev AVOptions:
-list_devices <boolean> .D........ list available devices (default false)
-video_device_index <int> .D........ select video device by index for devices with same name (starts at 0) (from -1 to INT_MAX) (default -1)
-audio_device_index <int> .D........ select audio device by index for devices with same name (starts at 0) (from -1 to INT_MAX) (default -1)
-pixel_format <pix_fmt> .D........ set pixel format (default yuv420p)
-framerate <video_rate> .D........ set frame rate (default "ntsc")
-video_size <image_size> .D........ set video size
-capture_cursor <boolean> .D........ capture the screen cursor (default false)
-capture_mouse_clicks <boolean> .D........ capture the screen mouse clicks (default false)
-capture_raw_data <boolean> .D........ capture the raw data from device connection (default false)
-drop_late_frames <boolean> .D........ drop frames that are available later than expected (default true)
- video_size: 分辨率
- pixel_format:像素格式(默认是yuv420p)
- framerate:幁率(每秒采集多少幁画面),默认是ntsc,也就是3000/1001,约等于29.970030
- list_devices:true表示列出avfoundation支持的所有设备
1.3.开始录制
ffmpeg -f avfoundation -i 0 out.yuv
- 使用0号设备视频
ffmpeg -f avfoundation -i 0 out.yuv
ffmpeg version 4.3.2 Copyright (c) 2000-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_4 --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
[avfoundation @ 0x7f98a080be00] Selected framerate (29.970030) is not supported by the device.
[avfoundation @ 0x7f98a080be00] Supported modes:
[avfoundation @ 0x7f98a080be00] 1280x720@[1.000000 30.000000]fps
Last message repeated 2 times
[avfoundation @ 0x7f98a080be00] 640x480@[1.000000 30.000000]fps
Last message repeated 2 times
[avfoundation @ 0x7f98a080be00] 320x240@[1.000000 30.000000]fps
Last message repeated 2 times
0: Input/output error
- 错误信息:
- framerate (29.970030) is not supported by the device.并且告诉我们支持30fps的幁率
ffmpeg -f avfoundation -framerate 30 -i 0 video.yuv
✘ songlin@feng-sl ~/audio/YUV master ± ffmpeg -f avfoundation -framerate 30 -i 0 video.yuv
ffmpeg version 4.3.2 Copyright (c) 2000-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_4 --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
[avfoundation @ 0x7ffbd9009a00] Selected pixel format (yuv420p) is not supported by the input device.
[avfoundation @ 0x7ffbd9009a00] Supported pixel formats:
[avfoundation @ 0x7ffbd9009a00] uyvy422
[avfoundation @ 0x7ffbd9009a00] yuyv422
[avfoundation @ 0x7ffbd9009a00] nv12
[avfoundation @ 0x7ffbd9009a00] 0rgb
[avfoundation @ 0x7ffbd9009a00] bgr0
[avfoundation @ 0x7ffbd9009a00] Overriding selected pixel format to use uyvy422 instead.
Input #0, avfoundation, from '0':
Duration: N/A, start: 98687.534833, bitrate: N/A
Stream #0:0: Video: rawvideo (UYVY / 0x59565955), uyvy422, 320x240, 29.97 tbr, 1000k tbn, 1000k tbc
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> rawvideo (native))
Press [q] to stop, [?] for help
Output #0, rawvideo, to 'video.yuv':
Metadata:
encoder : Lavf58.45.100
Stream #0:0: Video: rawvideo (UYVY / 0x59565955), uyvy422, 320x240, q=2-31, 36827 kb/s, 29.97 fps, 29.97 tbn, 29.97 tbc
Metadata:
encoder : Lavc58.91.100 rawvideo
frame= 415 fps= 32 q=-0.0 size= 62208kB time=00:00:13.84 bitrate=36802.3kbits/s speed=1.05x
- 错误信息:
- Selected pixel format (yuv420p) is not supported by the input devic
- Supported pixel formats:uyvy422、yuyv422、nv12、0rgb、bgr0
- Overriding selected pixel format to use uyvy422 instead
可以看出虽然报错,但是系统会帮我转换为可以录制的pixel format 执行下去,并且从输出信息里面还可以获取到的信息像素格式:uyvy422--------分辨率:20x240
1.4.播放视频
ffplay -video_size 320x240 -pixel_format uyvy422 -framerate 30 video.yuv
2.编程录制
添加依赖库
extern "C" {
#include <libavdevice/avdevice.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
#include <libavutil/imgutils.h>
#include <libavcodec/avcodec.h>
}
定义宏
#define FMT_NAME "avfoundation"
#define DEVICE_NAME "0"
#define FILENAME "/Users/songlin/audion/code_out.yuv
#define ERROR_BUF(ret) \
char errbuf[1024]; \
av_strerror(ret, errbuf, sizeof (errbuf));
Info.plist 权限申请
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSCameraUsageDescription</key>
<string>使用摄像头采集您的帅气样子</string>
</dict>
</plist>
注册设备
如果没有注册设备,会爆出找不到avfoundation这个错误
// 初始化libavdevice并注册所有输入和输出设备
avdevice_register_all();
获取输入格式对象
// 获取输入格式对象
AVInputFormat *fmt = av_find_input_format(FMT_NAME);
if (!fmt) {
qDebug() << "av_find_input_format error" << FMT_NAME;
return;
}
打开输入设备
// 格式上下文
AVFormatContext *ctx = nullptr;
// 传递给输入设备的参数
AVDictionary *options = nullptr;
av_dict_set(&options, "video_size", "640x480", 0);
av_dict_set(&options, "pixel_format", "yuyv422", 0);
av_dict_set(&options, "framerate", "30", 0);
// 打开输入设备
int ret = avformat_open_input(&ctx, DEVICE_NAME, fmt, &options);
if (ret < 0) {
ERROR_BUF(ret);
qDebug() << "avformat_open_input error" << errbuf;
return;
}
打开输出文件
// 打开文件
QFile file(FILENAME);
if (!file.open(QFile::WriteOnly)) {
qDebug() << "file open error" << FILENAME;
// 关闭输入设备
avformat_close_input(&ctx);
return;
}
采集视频数据
// 计算每一帧的大小
AVCodecParameters *params = ctx->streams[0]->codecpar;
int imageSize = av_image_get_buffer_size(
(AVPixelFormat) params->format,
params->width, params->height,
1);
// 数据包
AVPacket *pkt = av_packet_alloc();
while (!isInterruptionRequested()) {
// 不断采集数据
ret = av_read_frame(ctx, pkt);
if (ret == 0) { // 读取成功
// 将数据写入文件
file.write((const char *) pkt->data, imageSize);
/*
这里要使用imageSize,而不是pkt->size。
pkt->size有可能比imageSize大(比如在Mac平台),
使用pkt->size会导致写入一些多余数据到YUV文件中,
进而导致YUV内容无法正常播放
*/
// 释放资源
av_packet_unref(pkt);
} else if (ret == AVERROR(EAGAIN)) { // 资源临时不可用
continue;
} else { // 其他错误
ERROR_BUF(ret);
qDebug() << "av_read_frame error" << errbuf;
break;
}
}
释放资源
// 释放资源
av_packet_free(&pkt);
// 关闭文件
file.close();
// 关闭设备
avformat_close_input(&ctx);
测试录制视频
ffplay -video_size 640x480 -pixel_format yuyv422 -framerate 30 code_out.yuv
网友评论