【LSP】JavaCV FFmpeg采集摄像头YUV数据

编程开发   © 文章版权由 admin 解释,禁止匿名转载

#楼主# 2020-10-11

其实在javacpp项目集中有提供FFmpeg的JNI封装,可以直接使用FFmpeg API的来处理音视频数据,下面是一个简单的案例,通过FFmpeg API采集摄像头的YUV数据。

javacpp-ffmpeg依赖:


org.bytedeco.javacpp-presets
ffmpeg
${ffmpeg.version}

1. 查找摄像头设备
要采集摄像头的YUV数据,首先得知道摄像头的设备名称,可以通过FFmpeg来查找摄像头设备。

ffmpeg.exe -list_devices true -f dshow -i dummy
在我的电脑上结果显示如下:


其中 “Integrated Camera” 就是摄像头的设备名称。

2. 利用FFmpeg解码
采集摄像头数据即将摄像头作为视频流输入,通过FFmpeg解码获取视频帧,然后将视频帧转为YUV格式,最后将数据写入文件即可。
下面是FFmpeg解码的流程:



3. 开发视频帧采集器
根据FFmpeg的解码流程,实现视频帧采集器大概需要经过以下几个步骤:

FFmpeg初始化

首先需要使用av_register_all()这个函数完成编码器和解码器的初始化,只有初始化了编码器和解码器才能正常使用;另外要采集的是设备,所以还需要调用avdevice_register_all()完成初始化。

分配AVFormatContext

接着需要分配一个AVFormatContext,可以通过avformat_alloc_context()来分配AVFormatContext。

pFormatCtx = avformat_alloc_context();
打开视频流

通过avformat_open_input()来打开视频流,这里需要注意的是input format要指定为dshow,可以通过av_find_input_format("dshow")获取AVInputFormat对象。

ret = avformat_open_input(pFormatCtx, String.format("video=%s", input), av_find_input_format("dshow"), (AVDictionary) null);
查找视频流

需要注意的是,查找视频流之前需要调用avformat_find_stream_info(),下面是查找视频流的代码:

ret = avformat_find_stream_info(pFormatCtx, (AVDictionary) null);
for (int i = 0; i < pFormatCtx.nb_streams(); i++) {
if (pFormatCtx.streams(i).codec().codec_type() == AVMEDIA_TYPE_VIDEO) {
videoIdx = i;
break;
}
}
打开解码器

可以通过视频流来查找解码器,然后打开解码器,对视频流进行解码,Java代码如下:

pCodecCtx = pFormatCtx.streams(videoIdx).codec();
pCodec = avcodec_find_decoder(pCodecCtx.codec_id());
if (pCodec == null) {
throw new FFmpegException("没有找到合适的解码器:" + pCodecCtx.codec_id());
}
// 打开解码器
ret = avcodec_open2(pCodecCtx, pCodec, (AVDictionary) null);
if (ret != 0) {
throw new FFmpegException(ret, "avcodec_open2 解码器打开失败");
}
采集视频帧

最后就是采集视频帧了,这里需要注意的是采集摄像头的视频流解码得到的不一定是YUV格式的视频帧,所以需要对视频帧进行转化一下(videoConverter.scale(pFrame))。

4. 将视频帧数据写入文件

5. 播放采集的YUV数据

成为第一个回答人

评论

登录后才可发表内容
  • 主题

    124

  • 帖子

    0

  • 关注者

    0

Copyright © 2019 凯特网.   Powered by HYBBS 2.3.4  

Runtime:0.0720s Mem:2040Kb