public IActionResult ProduceMovieWithSubitles([FromBody] Subtitles subtitles) { var file = _mediaService.AddSubTitles(subtitles, GetCancellation()); return(Ok(new FileResponse { File = file })); }
public int AddSubTitles(Subtitles subtitles, CancellationToken cancellationToken = default) { int random = new Random().Next(); var randomNewFile = random + ".mp4"; string randomFile = Path.Combine(_options.MediaStoragePath, randomNewFile); #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed Task.Run(async() => { var info = new ProcessStartInfo(); var perc = 0; var prevPerc = 0; var curDir = Directory.GetCurrentDirectory(); var srtFile = $"{_options.MediaStoragePath}/{new Random().Next()}.srt"; await File.WriteAllLinesAsync(srtFile, subtitles.Lines, cancellationToken); info.FileName = "ffmpeg"; info.Arguments = $" -i {Path.Combine(_options.MediaStoragePath, subtitles.Id)} -vf subtitles={srtFile} {randomFile} -y -progress pipe:1"; info.UseShellExecute = false; info.RedirectStandardInput = true; info.RedirectStandardOutput = true; info.RedirectStandardError = true; /* * * frame=12444 fps= 14 q=29.0 size= 35328kB time=00:00:41.33 bitrate=7002.1kbits/s speed=0.469x * fps=14.11 * stream_0_0_q=29.0 * bitrate=7002.1kbits/s * total_size=36175920 * out_time_us=41331519 * out_time_ms=41331519 * out_time=00:00:41.331519 * dup_frames=0 * drop_frames=0 * speed=0.469x * progress=continue */ using var proc = Process.Start(info); proc.EnableRaisingEvents = true; proc.Start(); proc.BeginOutputReadLine(); proc.BeginErrorReadLine(); proc.ErrorDataReceived += (s, e) => { if (e == null || string.IsNullOrEmpty(e.Data)) { return; } var stringD = e.Data; if (stringD.Contains("Duration:", StringComparison.OrdinalIgnoreCase)) { //Duration: 00:00:06.34, start: 0.000000, bitrate: 21303 kb/s var inv = System.Globalization.NumberFormatInfo.InvariantInfo; var parseit = stringD.TrimStart(' ')[10..]; var lines = parseit.Split(','); var time = lines[0]; var timeparts = time.Split(':').Select(s => float.Parse(s, inv)).ToArray(); var secs = Math.Floor(timeparts[2]); var ms = Math.Floor((timeparts[2] - secs) * 1000); var ts = new TimeSpan(0, (int)timeparts[0], (int)timeparts[1], (int)secs, (int)ms); duration = ts.TotalMilliseconds; _logger.LogInformation("Found duration {0}", duration); }