private MemoryStream GetThumbnailFromProcess(Process p, ref int width, ref int height) { Debug("Starting ffmpeg"); using (var thumb = new MemoryStream()) { var pump = new StreamPump(p.StandardOutput.BaseStream, thumb, null, 4096); if (!p.WaitForExit(20000)) { p.Kill(); throw new ArgumentException("ffmpeg timed out"); } if (p.ExitCode != 0) { throw new ArgumentException("ffmpeg does not understand the stream"); } Debug("Done ffmpeg"); if (!pump.Wait(2000)) { throw new ArgumentException("stream reading timed out"); } if (thumb.Length == 0) { throw new ArgumentException("ffmpeg did not produce a result"); } using (var img = Image.FromStream(thumb)) { using (var scaled = ThumbnailMaker.ResizeImage(img, ref width, ref height)) { var rv = new MemoryStream(); try { scaled.Save(rv, ImageFormat.Jpeg); return rv; } catch (Exception) { rv.Dispose(); throw; } } } } }
public static string GetSubtitleSubrip(FileInfo file) { if (FFmpeg.FFmpegExecutable == null) { throw new NotSupportedException(); } if (file == null) { throw new ArgumentNullException("file"); } try { using (var p = new Process()) { var sti = p.StartInfo; #if !DEBUG sti.CreateNoWindow = true; #endif sti.UseShellExecute = false; sti.FileName = FFmpeg.FFmpegExecutable; sti.Arguments = String.Format( "-i \"{0}\" -map s:0 -f srt pipe:", file.FullName); sti.LoadUserProfile = false; sti.RedirectStandardOutput = true; p.Start(); using (var reader = new StreamReader(new MemoryStream())) { using (var pump = new StreamPump( p.StandardOutput.BaseStream, reader.BaseStream, 40960)) { pump.Pump(null); if (!p.WaitForExit(10000)) { throw new NotSupportedException("ffmpeg timed out"); } if (!pump.Wait(2000)) { throw new NotSupportedException("ffmpeg pump timed out"); } reader.BaseStream.Seek(0, SeekOrigin.Begin); var rv = string.Empty; string line; while ((line = reader.ReadLine()) != null) { rv += regAssStrip.Replace(line.Trim(), string.Empty) + "\n"; } if (!string.IsNullOrWhiteSpace(rv)) { return(rv); } } } } } catch (Exception ex) { throw new NotSupportedException(ex.Message, ex); } throw new NotSupportedException( "File does not contain a valid subtitle"); }
public static MemoryStream ExtractThumbnail(string mkvFile, int index) { if (!string.IsNullOrEmpty(mkvDirectory)) { var tempFile = Path.GetTempFileName(); using (var p = new Process()) { var sti = p.StartInfo; sti.UseShellExecute = false; sti.FileName = mkvExtractExe; sti.Arguments = string.Format("attachments \"{0}\" {1}:{2}", mkvFile, index, tempFile); sti.LoadUserProfile = false; sti.RedirectStandardOutput = true; p.Start(); using (var reader = new StreamReader(StreamManager.GetStream())) { using (var pump = new StreamPump( p.StandardOutput.BaseStream, reader.BaseStream, 4096)) { pump.Pump(null); if (!p.WaitForExit(3000)) { throw new NotSupportedException("mkvtools timed out"); } if (!pump.Wait(1000)) { throw new NotSupportedException("mkvtools pump timed out"); } reader.BaseStream.Seek(0, SeekOrigin.Begin); var output = reader.ReadToEnd(); if (output.Contains("is written to")) { MemoryStream fileContents = new MemoryStream(); using (FileStream file = new FileStream(tempFile, FileMode.Open, FileAccess.Read)) { file.CopyTo(fileContents); } File.Delete(tempFile); return(fileContents); } } } } } return(null); }
private static MemoryStream GetThumbnailFromProcess(Process p, ref int width, ref int height) { var lastPosition = 0L; using (var thumb = StreamManager.GetStream()) { using (var pump = new StreamPump( p.StandardOutput.BaseStream, thumb, 4096)) { pump.Pump(null); while (!p.WaitForExit(20000)) { if (lastPosition != thumb.Position) { lastPosition = thumb.Position; continue; } p.Kill(); throw new ArgumentException("ffmpeg timed out"); } if (p.ExitCode != 0) { throw new ArgumentException("ffmpeg does not understand the stream"); } if (!pump.Wait(2000)) { throw new ArgumentException("stream reading timed out"); } if (thumb.Length == 0) { throw new ArgumentException("ffmpeg did not produce a result"); } using (var img = Image.FromStream(thumb)) { using (var scaled = ThumbnailMaker.ResizeImage(img, width, height, ThumbnailMakerBorder.Bordered)) { width = scaled.Width; height = scaled.Height; var rv = new MemoryStream(); try { scaled.Save(rv, ImageFormat.Jpeg); return rv; } catch (Exception) { rv.Dispose(); throw; } } } } } }
private static IDictionary <string, string> IdentifyInternalFromProcess( FileInfo file) { using (var p = new Process()) { var sti = p.StartInfo; //#if !DEBUG sti.CreateNoWindow = true; //#endif sti.UseShellExecute = false; sti.FileName = FFmpegExecutable; sti.Arguments = $"-i \"{file.FullName}\""; sti.LoadUserProfile = false; sti.RedirectStandardError = true; p.Start(); IDictionary <string, string> rv = new Dictionary <string, string>(); using (var reader = new StreamReader(StreamManager.GetStream())) { using (var pump = new StreamPump( p.StandardError.BaseStream, reader.BaseStream, 4096)) { pump.Pump(null); if (!p.WaitForExit(3000)) { throw new NotSupportedException("ffmpeg timed out"); } if (!pump.Wait(1000)) { throw new NotSupportedException("ffmpeg pump timed out"); } reader.BaseStream.Seek(0, SeekOrigin.Begin); var output = reader.ReadToEnd(); var match = regDuration.Match(output); if (match.Success) { int h, m, s; if (int.TryParse(match.Groups[1].Value, out h) && int.TryParse(match.Groups[2].Value, out m) && int.TryParse(match.Groups[3].Value, out s)) { int ms; if (match.Groups.Count < 5 || !int.TryParse(match.Groups[4].Value, out ms)) { ms = 0; } var ts = new TimeSpan(0, h, m, s, ms * 10); var tss = ts.TotalSeconds.ToString( CultureInfo.InvariantCulture); rv.Add("LENGTH", tss); } } match = regDimensions.Match(output); if (match.Success) { int w, h; if (int.TryParse(match.Groups[1].Value, out w) && int.TryParse(match.Groups[2].Value, out h)) { rv.Add("VIDEO_WIDTH", w.ToString()); rv.Add("VIDEO_HEIGHT", h.ToString()); } } } } if (rv.Count == 0) { throw new NotSupportedException("File not supported"); } return(rv); } }
private static IDictionary<string, string> IdentifyFileInternalFFmpeg(FileInfo file) { if (FFmpeg.FFmpegExecutable == null) { throw new NotSupportedException(); } if (file == null) { throw new ArgumentNullException("file"); } IDictionary<string, string> rv; if (infoCache.TryGetValue(file, out rv)) { return rv; } try { using (var p = new Process()) { var sti = p.StartInfo; #if !DEBUG sti.CreateNoWindow = true; #endif sti.UseShellExecute = false; sti.FileName = FFmpeg.FFmpegExecutable; sti.Arguments = String.Format("-i \"{0}\"", file.FullName); sti.LoadUserProfile = false; sti.RedirectStandardError = true; p.Start(); rv = new Dictionary<string, string>(); using (var reader = new StreamReader(new MemoryStream())) { using (var pump = new StreamPump(p.StandardError.BaseStream, reader.BaseStream, null, 4096)) { if (!p.WaitForExit(2000)) { throw new NotSupportedException("ffmpeg timed out"); } if (!pump.Wait(1000)) { throw new NotSupportedException("ffmpeg pump timed out"); } reader.BaseStream.Seek(0, SeekOrigin.Begin); var output = reader.ReadToEnd(); var match = RegDuration.Match(output); if (match != null && match.Success) { int h, m, s, ms; if (int.TryParse(match.Groups[1].Value, out h) && int.TryParse(match.Groups[2].Value, out m) && int.TryParse(match.Groups[3].Value, out s)) { if (match.Groups.Count < 5 || !int.TryParse(match.Groups[4].Value, out ms)) { ms = 0; } var ts = new TimeSpan(0, h, m, s, ms * 10); var tss = ts.TotalSeconds.ToString(CultureInfo.InvariantCulture); rv.Add("LENGTH", tss); } } match = RegDimensions.Match(output); if (match != null && match.Success) { int w, h; if (int.TryParse(match.Groups[1].Value, out w) && int.TryParse(match.Groups[2].Value, out h)) { rv.Add("VIDEO_WIDTH", w.ToString()); rv.Add("VIDEO_HEIGHT", h.ToString()); } } } } if (rv.Count == 0) { throw new NotSupportedException("File not supported"); } return rv; } } catch (Exception ex) { throw new NotSupportedException(ex.Message, ex); } throw new NotSupportedException(); }
private static MemoryStream GetThumbnailInternal(Stream stream, ref int width, ref int height) { using (var p = new Process()) { var pos = 20L; try { var length = stream.Length; if (length < 10 * (1 << 20)) { pos = 5; } else { if (length > 100 * (1 << 20)) { pos = 60; } else { if (length > 50 * (1 << 20)) { pos = 60; } } } } catch (Exception) { // ignored } var sti = p.StartInfo; #if !DEBUG sti.CreateNoWindow = true; #endif sti.UseShellExecute = false; sti.FileName = FFmpeg.FFmpegExecutable; sti.Arguments = $"-v quiet -ss {pos} -i pipe: -an -frames:v 1 -f image2 pipe:"; sti.LoadUserProfile = false; sti.RedirectStandardInput = true; sti.RedirectStandardOutput = true; p.Start(); var sp = new StreamPump(stream, p.StandardInput.BaseStream, 4096); sp.Pump((pump, result) => { stream.Dispose(); }); return GetThumbnailFromProcess(p, ref width, ref height); } }
private void SendResponse() { var statusCode = response.Status; var responseBody = ProcessRanges(response, ref statusCode); var responseStream = new ConcatenatedStream(); try { var headerBlock = new StringBuilder(); headerBlock.AppendFormat( "HTTP/1.1 {0} {1}\r\n", (uint)statusCode, HttpPhrases.Phrases[statusCode] ); headerBlock.Append(response.Headers.HeaderBlock); headerBlock.Append(CRLF); var headerStream = new MemoryStream( Encoding.ASCII.GetBytes(headerBlock.ToString())); responseStream.AddStream(headerStream); if (method != "HEAD" && responseBody != null) { responseStream.AddStream(responseBody); responseBody = null; } InfoFormat("{0} - {1} response for {2}", this, (uint)statusCode, path); state = HttpStates.WRITING; var sp = new StreamPump(responseStream, stream, BUFFER_SIZE); sp.Pump((pump, result) => { pump.Input.Close(); pump.Input.Dispose(); if (result == StreamPumpResult.Delivered) { DebugFormat("{0} - Done writing response", this); string conn; if (headers.TryGetValue("connection", out conn) && conn.ToUpperInvariant() == "KEEP-ALIVE") { ReadNext(); return; } } else { DebugFormat("{0} - Client aborted connection", this); } Close(); }); } catch (Exception) { responseStream.Dispose(); throw; } finally { if (responseBody != null) { responseBody.Dispose(); } } }
public static string GetSubtitleSubrip(FileInfo file) { if (FFmpegExecutable == null) { throw new NotSupportedException(); } if (file == null) { throw new ArgumentNullException(nameof(file)); } try { using (var p = new Process()) { var sti = p.StartInfo; #if !DEBUG sti.CreateNoWindow = true; #endif sti.UseShellExecute = false; sti.FileName = FFmpegExecutable; sti.Arguments = $"-i \"{file.FullName}\" -map s:0 -f srt pipe:"; sti.LoadUserProfile = false; sti.RedirectStandardOutput = true; p.Start(); var lastPosition = 0L; using (var reader = new StreamReader(StreamManager.GetStream())) { using (var pump = new StreamPump( p.StandardOutput.BaseStream, reader.BaseStream, 100)) { pump.Pump(null); while (!p.WaitForExit(20000)) { if (lastPosition != reader.BaseStream.Position) { lastPosition = reader.BaseStream.Position; continue; } p.Kill(); throw new NotSupportedException("ffmpeg timed out"); } if (!pump.Wait(2000)) { throw new NotSupportedException("ffmpeg pump timed out"); } reader.BaseStream.Seek(0, SeekOrigin.Begin); var rv = string.Empty; string line; while ((line = reader.ReadLine()) != null) { rv += regAssStrip.Replace(line.Trim(), string.Empty) + "\n"; } if (!string.IsNullOrWhiteSpace(rv)) { return rv; } } } } } catch (Exception ex) { throw new NotSupportedException(ex.Message, ex); } throw new NotSupportedException( "File does not contain a valid subtitle"); }
public static int FindThumbnail(string mkvFile) { if (!string.IsNullOrEmpty(mkvDirectory)) { using (var p = new Process()) { var sti = p.StartInfo; sti.UseShellExecute = false; sti.FileName = mkvMergeExecutable; sti.Arguments = string.Format("--identify \"{0}\"", mkvFile); sti.LoadUserProfile = false; sti.RedirectStandardOutput = true; p.Start(); using (var reader = new StreamReader(StreamManager.GetStream())) { using (var pump = new StreamPump( p.StandardOutput.BaseStream, reader.BaseStream, 4096)) { pump.Pump(null); if (!p.WaitForExit(3000)) { throw new NotSupportedException("mkvtools timed out"); } if (!pump.Wait(1000)) { throw new NotSupportedException("mkvtools pump timed out"); } reader.BaseStream.Seek(0, SeekOrigin.Begin); var output = reader.ReadToEnd(); var outLines = output.Split('\n'); var idxOrder = 4; var matchedIndex = NoThumbnail; foreach (var line in outLines) { if (line.StartsWith("Attachment") && line.Contains("cover")) { // Get the attachment index and the type var idPos = line.IndexOf("ID"); int idx = int.Parse(line.Substring(idPos + 3, line.IndexOf(":", idPos) - idPos - 3)); var namePos = line.IndexOf("file name"); var newIndex = idxOrder; var coverName = line.Substring(namePos + 11, line.IndexOf("'", namePos + 11) - namePos - 11); switch (coverName) { case "cover_land.jpg": case "cover_land.png": newIndex = (int)AttachmentPriority.LargeLandscape; break; case "cover.jpg": case "cover.png": newIndex = (int)AttachmentPriority.LargePortrait; break; case "small_cover_land.jpg": case "small_cover_land.png": newIndex = (int)AttachmentPriority.SmallLandscape; break; case "small_cover.jpg": case "small_cover.png": newIndex = (int)AttachmentPriority.SmallPortrait; break; default: // Unknown attachment break; } if (newIndex < idxOrder) { matchedIndex = idx; idxOrder = newIndex; } } } return(matchedIndex); } } } } return(NoThumbnail); }
private static IDictionary <string, string> IdentifyFileInternalFFmpeg(FileInfo file) { if (FFmpeg.FFmpegExecutable == null) { throw new NotSupportedException(); } if (file == null) { throw new ArgumentNullException("file"); } IDictionary <string, string> rv; if (infoCache.TryGetValue(file, out rv)) { return(rv); } try { using (var p = new Process()) { var sti = p.StartInfo; #if !DEBUG sti.CreateNoWindow = true; #endif sti.UseShellExecute = false; sti.FileName = FFmpeg.FFmpegExecutable; sti.Arguments = String.Format("-i \"{0}\"", file.FullName); sti.LoadUserProfile = false; sti.RedirectStandardError = true; p.Start(); rv = new Dictionary <string, string>(); using (var reader = new StreamReader(new MemoryStream())) { using (var pump = new StreamPump(p.StandardError.BaseStream, reader.BaseStream, null, 4096)) { if (!p.WaitForExit(2000)) { throw new NotSupportedException("ffmpeg timed out"); } if (!pump.Wait(1000)) { throw new NotSupportedException("ffmpeg pump timed out"); } reader.BaseStream.Seek(0, SeekOrigin.Begin); var output = reader.ReadToEnd(); var match = RegDuration.Match(output); if (match != null && match.Success) { int h, m, s, ms; if (int.TryParse(match.Groups[1].Value, out h) && int.TryParse(match.Groups[2].Value, out m) && int.TryParse(match.Groups[3].Value, out s)) { if (match.Groups.Count < 5 || !int.TryParse(match.Groups[4].Value, out ms)) { ms = 0; } var ts = new TimeSpan(0, h, m, s, ms * 10); var tss = ts.TotalSeconds.ToString(CultureInfo.InvariantCulture); rv.Add("LENGTH", tss); } } match = RegDimensions.Match(output); if (match != null && match.Success) { int w, h; if (int.TryParse(match.Groups[1].Value, out w) && int.TryParse(match.Groups[2].Value, out h)) { rv.Add("VIDEO_WIDTH", w.ToString()); rv.Add("VIDEO_HEIGHT", h.ToString()); } } } } if (rv.Count == 0) { throw new NotSupportedException("File not supported"); } return(rv); } } catch (Exception ex) { throw new NotSupportedException(ex.Message, ex); } throw new NotSupportedException(); }