2 This file is part of the HandBrake source code.
\r
3 Homepage: <http://handbrake.fr>.
\r
4 It may be used under the terms of the GNU General Public License. */
\r
6 namespace Handbrake.Parsing
\r
9 using System.Collections.Generic;
\r
10 using System.Drawing;
\r
11 using System.Globalization;
\r
13 using System.Text.RegularExpressions;
\r
16 /// An object that represents a single Title of a DVD
\r
21 /// The Culture Info
\r
23 private static readonly CultureInfo Culture = new CultureInfo("en-US", false);
\r
26 /// A collection of Audio Tracks
\r
28 private readonly List<AudioTrack> audioTracks;
\r
31 /// A Collection of Chapters
\r
33 private readonly List<Chapter> chapters;
\r
36 /// A Collection of Subtitles
\r
38 private readonly List<Subtitle> subtitles;
\r
41 /// A collection of angles
\r
43 private List<string> angles = new List<string>();
\r
46 /// The source aspect ratio
\r
48 private float aspectRatio;
\r
51 /// The source framerate
\r
56 /// Source autocrop values
\r
58 private int[] autoCrop;
\r
63 private string source;
\r
66 /// The duration of the source
\r
68 private TimeSpan duration;
\r
71 /// The source resolution
\r
73 private Size resolution;
\r
76 /// The Title number
\r
78 private int titleNumber;
\r
81 /// The par values for this title.
\r
83 private Size parVal;
\r
86 /// Initializes a new instance of the <see cref="Title"/> class.
\r
87 /// The constructor for this object
\r
91 audioTracks = new List<AudioTrack>();
\r
92 chapters = new List<Chapter>();
\r
93 subtitles = new List<Subtitle>();
\r
97 /// Gets a Collection of chapters in this Title
\r
99 public List<Chapter> Chapters
\r
101 get { return chapters; }
\r
105 /// Gets a Collection of audio tracks associated with this Title
\r
107 public List<AudioTrack> AudioTracks
\r
109 get { return audioTracks; }
\r
113 /// Gets aCollection of subtitles associated with this Title
\r
115 public List<Subtitle> Subtitles
\r
117 get { return subtitles; }
\r
121 /// The track number of this Title
\r
123 public int TitleNumber
\r
125 get { return titleNumber; }
\r
129 /// Gets the Source Name
\r
131 public string SourceName
\r
133 get { return source; }
\r
137 /// Gets the length in time of this Title
\r
139 public TimeSpan Duration
\r
141 get { return duration; }
\r
145 /// Gets the resolution (width/height) of this Title
\r
147 public Size Resolution
\r
149 get { return resolution; }
\r
153 /// Gets the aspect ratio of this Title
\r
155 public float AspectRatio
\r
157 get { return aspectRatio; }
\r
165 get { return parVal; }
\r
169 /// Gets the automatically detected crop region for this Title.
\r
170 /// This is an int array with 4 items in it as so:
\r
176 public int[] AutoCropDimensions
\r
178 get { return autoCrop; }
\r
182 /// Gets a Collection of Angles in this Title
\r
184 public List<string> Angles
\r
186 get { return angles; }
\r
191 /// Gets the FPS of the source.
\r
195 get { return fps; }
\r
199 /// Override of the ToString method to provide an easy way to use this object in the UI
\r
201 /// <returns>A string representing this track in the format: {title #} (00:00:00)</returns>
\r
202 public override string ToString()
\r
204 return string.Format("{0} ({1:00}:{2:00}:{3:00})", titleNumber, duration.Hours, duration.Minutes, duration.Seconds);
\r
208 /// Parse the Title Information
\r
210 /// <param name="output">A stingreader of output data</param>
\r
211 /// <returns>A Title</returns>
\r
212 public static Title Parse(StringReader output)
\r
214 var thisTitle = new Title();
\r
216 Match m = Regex.Match(output.ReadLine(), @"^\+ title ([0-9]*):");
\r
217 // Match track number for this title
\r
219 thisTitle.titleNumber = int.Parse(m.Groups[1].Value.Trim());
\r
221 // If we are scanning a groupd of files, we'll want to get the source name.
\r
222 string path = output.ReadLine();
\r
223 m = Regex.Match(path, @"^ \+ stream:");
\r
225 thisTitle.source = path.Replace("+ stream:", string.Empty).Trim();
\r
227 if (!Properties.Settings.Default.noDvdNav)
\r
229 // Get the Angles for the title.
\r
230 m = Regex.Match(output.ReadLine(), @" \+ angle\(s\) ([0-9])");
\r
233 string angleList = m.Value.Replace("+ angle(s) ", string.Empty).Trim();
\r
235 int.TryParse(angleList, out angleCount);
\r
237 for (int i = 1; i <= angleCount; i++)
\r
238 thisTitle.angles.Add(i.ToString());
\r
242 // Get duration for this title
\r
243 m = Regex.Match(output.ReadLine(), @"^ \+ duration: ([0-9]{2}:[0-9]{2}:[0-9]{2})");
\r
245 thisTitle.duration = TimeSpan.Parse(m.Groups[1].Value);
\r
247 // Get resolution, aspect ratio and FPS for this title
\r
248 m = Regex.Match(output.ReadLine(), @"^ \+ size: ([0-9]*)x([0-9]*), pixel aspect: ([0-9]*)/([0-9]*), display aspect: ([0-9]*\.[0-9]*), ([0-9]*\.[0-9]*) fps");
\r
251 thisTitle.resolution = new Size(int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value));
\r
252 thisTitle.parVal = new Size(int.Parse(m.Groups[3].Value), int.Parse(m.Groups[4].Value));
\r
253 thisTitle.aspectRatio = float.Parse(m.Groups[5].Value, Culture);
\r
254 thisTitle.fps = float.Parse(m.Groups[6].Value, Culture);
\r
257 // Get autocrop region for this title
\r
258 m = Regex.Match(output.ReadLine(), @"^ \+ autocrop: ([0-9]*)/([0-9]*)/([0-9]*)/([0-9]*)");
\r
260 thisTitle.autoCrop = new[]
\r
262 int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value),
\r
263 int.Parse(m.Groups[3].Value), int.Parse(m.Groups[4].Value)
\r
266 thisTitle.chapters.AddRange(Chapter.ParseList(output));
\r
268 thisTitle.audioTracks.AddRange(AudioTrack.ParseList(output));
\r
270 thisTitle.subtitles.AddRange(Subtitle.ParseList(output));
\r
276 /// Return a list of parsed titles
\r
278 /// <param name="output">The Output</param>
\r
279 /// <returns>A List of titles</returns>
\r
280 public static Title[] ParseList(string output)
\r
282 var titles = new List<Title>();
\r
283 var sr = new StringReader(output);
\r
285 while (sr.Peek() == '+' || sr.Peek() == ' ')
\r
287 // If the the character is a space, then chances are the line
\r
288 if (sr.Peek() == ' ') // If the character is a space, then chances are it's the combing detected line.
\r
289 sr.ReadLine(); // Skip over it
\r
291 titles.Add(Parse(sr));
\r
294 return titles.ToArray();
\r