I'm using ASP.NET Core and ffmpeg to record a live video stream. When the page receives a get request, the stream should begin recording and saving to a folder using ffmpeg. I want to make it so that when visiting the stop endpoint, the ffmpeg process is closed cleanly.
Unfortunately I'm unable to send a 'q' to stdin after leaving the Get method. Using taskkill requires the use of /F making the ffmpeg process (which is not a window) force quit and not save the video properly, resulting in a corrupt file.
I tried using Process.Kill() but that results in a corrupt file as well. Also, I tried Process.CloseMainWindow() which worked, but only when the process is started as a window, and I'm unable to start the process as a window in the server I'm using.
I've include the code I have so far below, so hopefully someone could lead me in the right path.
using System;
...
using Microsoft.Extensions.Logging;
namespace MyApp.Controllers
{
[Route("api/[controller]")]
[Authorize]
public class RecordingController : Controller
{
private readonly ApplicationDbContext _context;
private readonly ILogger<HomeController> _logger;
public RecordingController(ApplicationDbContext context, ILogger<HomeController> logger)
{
_context = context;
_logger = logger;
}
[HttpGet]
public async Task<ActionResult> Get()
{
// Define the os process
var processStartInfo = new ProcessStartInfo()
{
// ffmpeg arguments
Arguments = "-f mjpeg -i \"https://urlofstream.com/video.gci\" -r 5 \"wwwroot/video.mp4\"",
FileName = "ffmpeg.exe",
UseShellExecute = true
};
var p1 = Process.Start(processStartInfo);
// p1.StandardInput.WriteLineAsync("q"); <-- This works here but not in the Stop method
return Ok(p1.Id);
}
// GET: api/Recording/stop
[HttpGet("stop/{pid}")]
public ActionResult Stop(int pid)
{
Process processes = Process.GetProcessById(pid);
processes.StandardInput.WriteLineAsync("q"); // Does not work, is not able to redirect input
return Ok();
}
}
}