C利用ffmpeg的image2pipe参数实现USB摄系头本地预览同时推流

科技玩点原始事 2024-02-20 21:16:03

本地USB摄像头在使用中时,不支持另一个程序的并发访问,也就是说USB摄像头只能令第一个连接的程序“独享”。

一、需求

在开发一个软件时,希望实现预览USB摄像头的同时,实现摄像头的推流。

推流要用的ffmpeg,经过资料查找,ffmpeg支持通过管道传输给ffplay实现本地预览,代码如下:

ffmpeg -f v4l2 -video_size 640x480 -i /dev/video0 -f alsa -i hw:0 -c:v libx264 -preset ultrafast -tune zerolatency -b:v 1000k -minrate 500k -maxrate 2000k -bufsize 2000k -c:a aac -strict experimental -f flv rtmp://server/live/stream | ffplay -

用这个方法弹出的界面不美观,而且对系统资源占用非常高,不建议使用。

二、解决方法

经过查询ffmpeg源码,发现有个image2pipe参数,可以完美实现这个需求,具体实现步骤如下:

1、项目中安装AForge用于对摄像头操作编辑

2、设计界面如下

3、窗体载入代码​

// 获取摄像头设备//获取内置、外接摄像头,非网络摄像头videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);if (videoDevices.Count != 0){ foreach (FilterInfo device in videoDevices) { cbo_camera.Items.Add(device.Name); }}else{ cbo_camera.Items.Add("没有找到摄像头");}cbo_camera.SelectedIndex = 0;

4、选择摄像头​

private void cbo_camera_SelectedIndexChanged(object sender, EventArgs e){ if (videoDevices.Count != 0) { //获取每个摄像头支持的分辨率 videoDevice = new VideoCaptureDevice(videoDevices[cbo_camera.SelectedIndex].MonikerString); GetDeviceResolution(videoDevice); }}

5、获取分辨率​

/// <summary>/// 获取每个摄像头支持的分辨率/// </summary>/// <param name="videoCaptureDevice"></param>private void GetDeviceResolution(VideoCaptureDevice videoCaptureDevice){ cbo_rate.Items.Clear(); videoCapabilities = videoCaptureDevice.VideoCapabilities; foreach (VideoCapabilities capabilty in videoCapabilities) { cbo_rate.Items.Add($"{capabilty.FrameSize.Width} x {capabilty.FrameSize.Height}"); } cbo_rate.SelectedIndex = 0;}

6、摄像头有新帧进入的处理​

currentFrame = image;pictureBox1.Image = currentFrame;PushToRtmpServer(currentFrame);Console.WriteLine("NewFrame");

7、为AForge控件添加事件

​PushToRtmpServer代码

private void PushToRtmpServer(Bitmap frame){ // 将摄像头视频推流到 RTMP 服务器 if (ffmpegProcess == null || ffmpegProcess.HasExited) { var outputSettings = $"rtmp://192.168.0.66/live/livestream?KeyCode=123"; var ffmpegArgs = $"-y -f image2pipe -pix_fmt bgr24 -s {frame.Width}x{frame.Height}" + $" -r 25 -i - -c:v libx264 -preset fast -tune zerolatency -f flv {outputSettings}"; var processStartInfo = new ProcessStartInfo("ffmpeg.exe") { RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true, Arguments = ffmpegArgs, WindowStyle = ProcessWindowStyle.Hidden }; ffmpegProcess = Process.Start(processStartInfo); } using (var ms = new MemoryStream()) { this.Invoke((EventHandler)delegate { frame.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); ms.Seek(0, SeekOrigin.Begin); ffmpegProcess.StandardInput.BaseStream.Write(ms.ToArray(), 0, ms.ToArray().Length); }); }}

运行结果:

代码下载: https://download.csdn.net/download/dgnankai/87767380

0 阅读:4

科技玩点原始事

简介:感谢大家的关注