Hello!
I am attempting to stream video from a file(mp4) using C# with OpenCvSharp and pipe it to FFmpeg, which should act as an RTSP server.
My goal is to make the stream accessible via VLC ( as I am using universel driver 1) or Milestone XProtect using their Universal Driver.
Windows 11
FFmpeg version: ffmpeg version N-119444-g2b6303762f-20250506 Copyright (c) 2000-2025 the FFmpeg developers
built with gcc 14.2.0 (crosstool-NG 1.27.0.18_7458341)
OpenCvSharp4 (NuGet)
.NET 9
VLC version: [insert VLC version]
The idea is that I should be able to use rtsp://0.0.0.0:8554/stream as the localhost stream, however it does not work in VLC, which means it does not work in milestone. Have anyone had success with this?
What I have done so far is this:
using OpenCvSharp;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
class Program
{
static void Main()
{
Console.WriteLine("Enter the path to the video file:");
string videoPath = Console.ReadLine();
if (string.IsNullOrEmpty(videoPath))
{
Console.WriteLine("Error: No video path provided.");
return;
}
var cap = new VideoCapture(videoPath);
if (!cap.IsOpened())
{
Console.WriteLine("Error: Could not open the video file!");
return;
}
int frameWidth = cap.FrameWidth;
int frameHeight = cap.FrameHeight;
double fps = cap.Fps;
Console.WriteLine($"Resolution: {frameWidth}x{frameHeight}, FPS: {fps}");
// Start ffmpeg as a local RTSP server
Process ffmpeg = new Process();
ffmpeg.StartInfo.FileName = "ffmpeg";
ffmpeg.StartInfo.Arguments = $"-f rawvideo -pixel_format bgr24 -video_size {frameWidth}x{frameHeight} -framerate {fps} -i - " +
$"-c:v libx264 -preset ultrafast -tune zerolatency -f rtsp -rtsp_flags listen -rtsp_transport tcp rtsp://0.0.0.0:8554/stream";
ffmpeg.StartInfo.RedirectStandardInput = true;
ffmpeg.StartInfo.RedirectStandardError = true;
ffmpeg.StartInfo.UseShellExecute = false;
ffmpeg.StartInfo.CreateNoWindow = true;
ffmpeg.Start();
// Read and stream frames
Mat frame = new Mat();
int frameSize = frameWidth * frameHeight * 3; // BGR24
byte[] buffer = new byte[frameSize];
try
{
while (true)
{
cap.Read(frame);
if (frame.Empty())
break;
Marshal.Copy(frame.Data, buffer, 0, buffer.Length);
ffmpeg.StandardInput.BaseStream.Write(buffer, 0, buffer.Length);
ffmpeg.StandardInput.BaseStream.Flush();
Console.WriteLine($"Streaming Frame: {frame.Width}x{frame.Height}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Exception occurred while streaming: {ex.Message}");
}
finally
{
cap.Release();
ffmpeg.StandardInput.Close();
string ffmpegError = ffmpeg.StandardError.ReadToEnd();
if (!string.IsNullOrWhiteSpace(ffmpegError))
{
Console.WriteLine("FFmpeg error output:");
Console.WriteLine(ffmpegError);
}
ffmpeg.WaitForExit();
ffmpeg.Close();
Console.WriteLine("Streaming finished.");
}
}
}