コード例 #1
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);
			}
		}
コード例 #2
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");
		}
コード例 #3
0
		public EpisodeInfo (int index,
				int number,
				UtilsInputFiles.FileDesc videoFileDesc,
				UtilsInputFiles.FileDesc audioFileDesc,
				UtilsInputFiles.FileDesc sub1FileDesc,
				UtilsInputFiles.FileDesc sub2FileDesc,
				StreamInfo videoStreamInfo,
				StreamInfo audioStreamInfo,
				StreamInfo sub1StreamInfo,
				StreamInfo sub2StreamInfo)
		{
			m_index = index;
			m_number = number;
			m_videoFileDesc = videoFileDesc;
			m_audioFileDesc = audioFileDesc;
			m_subsFileDesc[0] = sub1FileDesc;
			m_subsFileDesc[1] = sub2FileDesc;
			m_videoStreamInfo = videoStreamInfo;
			m_audioStreamInfo = audioStreamInfo;
			m_subStreamInfos[0] = sub1StreamInfo;
			m_subStreamInfos[1] = sub2StreamInfo;
		}
コード例 #4
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 + @"""");

			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;
		}