public static double GetMaxVolume(String audioFile, StreamInfo audioStreamInfo) { if (audioStreamInfo.StreamTypeValue != StreamInfo.StreamType.ST_AUDIO) { throw new Exception("Tried to get volume of non-audio-stream"); } String arguments = String.Format("-i \"{0}\" -map 0:{1} -af volumedetect -vn -f null /dev/null", audioFile, audioStreamInfo.StreamIndex); String stderr = UtilsCommon.StartProcessAndGetOutput(InstanceSettings.systemSettings.formatConvertCommand, arguments, true); String[] lines = stderr.Split('\n'); for (int i = lines.Length - 1; i >= 0; i--) { String line = lines[i]; if (line.Contains("max_volume")) { Match match = Regex.Match(line.Trim(), @"\[Parsed_volumedetect_0 @ (.*?)\] max_volume: (?<volume>[-.,0-9]+) dB$", RegexOptions.IgnoreCase | RegexOptions.Compiled); if (!match.Success) { throw new Exception("Output of \"" + InstanceSettings.systemSettings.formatConvertCommand + "\" with filter \"volumedetect\" could not be parsed"); } return(Double.Parse(match.Groups["volume"].ToString(), CultureInfo.InvariantCulture)); } } throw new Exception("Output of \"" + InstanceSettings.systemSettings.formatConvertCommand + "\" with filter \"volumedetect\" could not be parsed"); }
public static void ExtractAudio(Settings settings, String path, List <Tuple <CardInfo, String> > allEntries, InfoProgress progress) { foreach (var entry in allEntries) { progress.ProcessedSteps(1); if (progress.Cancelled) { return; } CardInfo cardInfo = entry.Item1; if (!cardInfo.HasAudio()) { continue; } String outputAudioFilename = entry.Item2; String outputAudioFilepath = path + Path.DirectorySeparatorChar + outputAudioFilename; UtilsInputFiles.FileDesc audioFileDesc = cardInfo.episodeInfo.AudioFileDesc; var audioStreamInfo = cardInfo.episodeInfo.AudioStreamInfo; String arguments = String.Format("-v quiet -y -i \"{0}\" -map 0:{1} -ss \"{2}\" -to \"{3}\" -vn -c:a libvorbis \"{4}\"", audioFileDesc.filename, // input file audioStreamInfo.StreamIndex, // audio stream index UtilsCommon.ToTimeArg(cardInfo.audioStartTimestamp), // start time UtilsCommon.ToTimeArg(cardInfo.audioEndTimestamp), // end time outputAudioFilepath // output file ); UtilsCommon.StartProcessAndGetOutput(InstanceSettings.systemSettings.formatConvertCommand, arguments); } }
public static void ExtractStream(String videoFilePath, StreamInfo streamInfo, String newSubtitleFilePath) { String argumentString = String.Format("-y -v quiet -i \"{0}\" -map 0:{1} \"{2}\"", videoFilePath, streamInfo.StreamIndex, newSubtitleFilePath); if (UtilsCommon.StartProcessAndGetOutput(InstanceSettings.systemSettings.formatConvertCommand, argumentString) == null) { throw new ApplicationException(); } }
public static bool IsAvconvAvailable() { var output = UtilsCommon.StartProcessAndGetOutput("avconv", "-version"); if (output == null) { return(false); } return(output.StartsWith("avconv version")); }
public static bool IsFfmpegAvailable() { var output = UtilsCommon.StartProcessAndGetOutput("ffmpeg", "-version"); Console.WriteLine(output); if (output == null) { return(false); } return(output.StartsWith("ffmpeg version")); }
/// <summary> /// Extracts an image from a video file at a given time and resizes it. Resizing preserves aspect ratio. /// </summary> public static bool GetImage(String videoFilename, double time, String outFilename, double scale = 1) { String argumentString = String.Format("-y -v quiet -an -ss {0} -i \"{1}\" -f image2 -vf \"scale=iw*{2}/3628800:ih*{2}/3628800\" -vframes 1 \"{3}\"", UtilsCommon.ToTimeArg(time), videoFilename, (int)(scale * 3628800), // int is needed because double will create values with comma (e.g "0,1"); 3628800=10! (has many divisors) outFilename); UtilsCommon.StartProcessAndGetOutput(InstanceSettings.systemSettings.formatConvertCommand, argumentString); return(true); }
public static void NormalizeAudio(String filename, StreamInfo audioStreamInfo) { if (!filename.EndsWith("ogg")) { throw new Exception("Only .ogg files are currently supported for normalizing!"); } double maxVolume = GetMaxVolume(filename, audioStreamInfo); double targetVolume = InstanceSettings.systemSettings.normalizeTargetVolume; String tmpFilename = InstanceSettings.temporaryFilesPath + Path.GetFileName(filename); String arguments = String.Format("-y -i \"{0}\" -af \"volume={1}dB\" -c:a libvorbis -vn \"{2}\"", filename, (-maxVolume + targetVolume).ToString(System.Globalization.CultureInfo.InvariantCulture), tmpFilename); UtilsCommon.StartProcessAndGetOutput(InstanceSettings.systemSettings.formatConvertCommand, arguments); // move new file to original position if (File.Exists(tmpFilename)) { File.Delete(filename); File.Move(tmpFilename, filename); } }
/// <summary> /// Uses ffprobe/avprobe to query all audio, video and subtitle streams in a container file. /// </summary> public static List <StreamInfo> ReadAllStreams(String filename) { // use ffprobe/avprobe(?) to get nice XML-description of contents String stdout = UtilsCommon.StartProcessAndGetOutput(InstanceSettings.systemSettings.formatProberCommand, @"-v quiet -print_format xml -show_streams """ + filename + @""""); if (stdout == null) { throw new IOException("Calling ffprobe/avprobe failed! Is it installed?"); } List <StreamInfo> allStreamInfos = new List <StreamInfo> (); StreamInfo lastStreamInfo = null; // use XmlReader to read all informations from "stream"-tags and "tag"-tags using (XmlReader reader = XmlReader.Create(new StringReader(stdout))) { while (reader.Read()) { if (reader.NodeType != XmlNodeType.Element) { continue; } // the "stream"-tag contains most of the information needed as attributes if (reader.Name == "stream") { // get stream type StreamType streamType; switch (reader["codec_type"]) { case "video": streamType = StreamType.ST_VIDEO; break; case "audio": streamType = StreamType.ST_AUDIO; break; case "subtitle": streamType = StreamType.ST_SUBTITLE; break; default: streamType = StreamType.ST_UNKNOWN; break; } // read all other information into dictionary var attributeDictionary = new Dictionary <String, String>(); for (int i = 0; i < reader.AttributeCount; i++) { reader.MoveToNextAttribute(); attributeDictionary.Add(reader.Name, reader.Value); } StreamInfo streamInfo = new StreamInfo(Int32.Parse(reader["index"]), streamType, reader["codec_name"], attributeDictionary); allStreamInfos.Add(streamInfo); lastStreamInfo = streamInfo; } // the "tag"-tag provides additonal information (mainly language) if (reader.Name == "tag") { if (lastStreamInfo == null) { continue; } switch (reader ["key"]) { case "language": lastStreamInfo.m_language = reader ["value"] ?? ""; break; default: break; } } } } return(allStreamInfos); }