示例#1
0
        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");
        }
示例#2
0
        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);
            }
        }
示例#3
0
        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();
            }
        }
示例#4
0
        public static bool IsAvconvAvailable()
        {
            var output = UtilsCommon.StartProcessAndGetOutput("avconv", "-version");

            if (output == null)
            {
                return(false);
            }
            return(output.StartsWith("avconv version"));
        }
示例#5
0
        public static bool IsFfmpegAvailable()
        {
            var output = UtilsCommon.StartProcessAndGetOutput("ffmpeg", "-version");

            Console.WriteLine(output);
            if (output == null)
            {
                return(false);
            }
            return(output.StartsWith("ffmpeg version"));
        }
示例#6
0
        /// <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);
        }
示例#7
0
        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);
            }
        }
示例#8
0
        /// <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);
        }