OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / win / C# / Parsing / Title.cs
1 /*  Title.cs $\r
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
5 \r
6 namespace Handbrake.Parsing\r
7 {\r
8     using System;\r
9     using System.Collections.Generic;\r
10     using System.Drawing;\r
11     using System.Globalization;\r
12     using System.IO;\r
13     using System.Text.RegularExpressions;\r
14 \r
15     /// <summary>\r
16     /// An object that represents a single Title of a DVD\r
17     /// </summary>\r
18     public class Title\r
19     {\r
20         /// <summary>\r
21         /// The Culture Info\r
22         /// </summary>\r
23         private static readonly CultureInfo Culture = new CultureInfo("en-US", false);\r
24 \r
25         /// <summary>\r
26         /// A collection of Audio Tracks\r
27         /// </summary>\r
28         private readonly List<AudioTrack> audioTracks;\r
29 \r
30         /// <summary>\r
31         /// A Collection of Chapters\r
32         /// </summary>\r
33         private readonly List<Chapter> chapters;\r
34 \r
35         /// <summary>\r
36         /// A Collection of Subtitles\r
37         /// </summary>\r
38         private readonly List<Subtitle> subtitles;\r
39 \r
40         /// <summary>\r
41         /// A collection of angles \r
42         /// </summary>\r
43         private List<string> angles = new List<string>();\r
44 \r
45         /// <summary>\r
46         /// The source aspect ratio\r
47         /// </summary>\r
48         private float aspectRatio;\r
49 \r
50         /// <summary>\r
51         /// The source framerate\r
52         /// </summary>\r
53         private float fps;\r
54 \r
55         /// <summary>\r
56         /// Source autocrop values\r
57         /// </summary>\r
58         private int[] autoCrop;\r
59 \r
60         /// <summary>\r
61         /// Source name\r
62         /// </summary>\r
63         private string source;\r
64 \r
65         /// <summary>\r
66         /// The duration of the source\r
67         /// </summary>\r
68         private TimeSpan duration;\r
69 \r
70         /// <summary>\r
71         /// The source resolution\r
72         /// </summary>\r
73         private Size resolution;\r
74 \r
75         /// <summary>\r
76         /// The Title number\r
77         /// </summary>\r
78         private int titleNumber;\r
79 \r
80         /// <summary>\r
81         /// The par values for this title.\r
82         /// </summary>\r
83         private Size parVal;\r
84 \r
85         /// <summary>\r
86         /// Initializes a new instance of the <see cref="Title"/> class. \r
87         /// The constructor for this object\r
88         /// </summary>\r
89         public Title()\r
90         {\r
91             audioTracks = new List<AudioTrack>();\r
92             chapters = new List<Chapter>();\r
93             subtitles = new List<Subtitle>();\r
94         }\r
95 \r
96         /// <summary>\r
97         /// Gets a Collection of chapters in this Title\r
98         /// </summary>\r
99         public List<Chapter> Chapters\r
100         {\r
101             get { return chapters; }\r
102         }\r
103 \r
104         /// <summary>\r
105         /// Gets a Collection of audio tracks associated with this Title\r
106         /// </summary>\r
107         public List<AudioTrack> AudioTracks\r
108         {\r
109             get { return audioTracks; }\r
110         }\r
111 \r
112         /// <summary>\r
113         /// Gets aCollection of subtitles associated with this Title\r
114         /// </summary>\r
115         public List<Subtitle> Subtitles\r
116         {\r
117             get { return subtitles; }\r
118         }\r
119 \r
120         /// <summary>\r
121         /// The track number of this Title\r
122         /// </summary>\r
123         public int TitleNumber\r
124         {\r
125             get { return titleNumber; }\r
126         }\r
127 \r
128         /// <summary>\r
129         /// Gets the Source Name\r
130         /// </summary>\r
131         public string SourceName\r
132         {\r
133             get { return source; }\r
134         }\r
135 \r
136         /// <summary>\r
137         /// Gets the length in time of this Title\r
138         /// </summary>\r
139         public TimeSpan Duration\r
140         {\r
141             get { return duration; }\r
142         }\r
143 \r
144         /// <summary>\r
145         /// Gets the resolution (width/height) of this Title\r
146         /// </summary>\r
147         public Size Resolution\r
148         {\r
149             get { return resolution; }\r
150         }\r
151 \r
152         /// <summary>\r
153         /// Gets the aspect ratio of this Title\r
154         /// </summary>\r
155         public float AspectRatio\r
156         {\r
157             get { return aspectRatio; }\r
158         }\r
159 \r
160         /// <summary>\r
161         /// Gets Par Value\r
162         /// </summary>\r
163         public Size ParVal\r
164         {\r
165             get { return parVal; }\r
166         }\r
167 \r
168         /// <summary>\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
171         /// 0: \r
172         /// 1: \r
173         /// 2: \r
174         /// 3: \r
175         /// </summary>\r
176         public int[] AutoCropDimensions\r
177         {\r
178             get { return autoCrop; }\r
179         }\r
180 \r
181         /// <summary>\r
182         /// Gets a Collection of Angles in this Title\r
183         /// </summary>\r
184         public List<string> Angles\r
185         {\r
186             get { return angles; }\r
187         }\r
188 \r
189 \r
190         /// <summary>\r
191         /// Gets the FPS of the source.\r
192         /// </summary>\r
193         public float Fps\r
194         {\r
195             get { return fps; }\r
196         }\r
197 \r
198         /// <summary>\r
199         /// Override of the ToString method to provide an easy way to use this object in the UI\r
200         /// </summary>\r
201         /// <returns>A string representing this track in the format: {title #} (00:00:00)</returns>\r
202         public override string ToString()\r
203         {\r
204             return string.Format("{0} ({1:00}:{2:00}:{3:00})", titleNumber, duration.Hours, duration.Minutes, duration.Seconds);\r
205         }\r
206 \r
207         /// <summary>\r
208         /// Parse the Title Information\r
209         /// </summary>\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
213         {\r
214             var thisTitle = new Title();\r
215 \r
216             Match m = Regex.Match(output.ReadLine(), @"^\+ title ([0-9]*):");\r
217             // Match track number for this title\r
218             if (m.Success)\r
219                 thisTitle.titleNumber = int.Parse(m.Groups[1].Value.Trim());\r
220 \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
224             if (m.Success)\r
225                 thisTitle.source = path.Replace("+ stream:", string.Empty).Trim();\r
226 \r
227             if (!Properties.Settings.Default.noDvdNav)\r
228             {\r
229                 // Get the Angles for the title.\r
230                 m = Regex.Match(output.ReadLine(), @"  \+ angle\(s\) ([0-9])");\r
231                 if (m.Success)\r
232                 {\r
233                     string angleList = m.Value.Replace("+ angle(s) ", string.Empty).Trim();\r
234                     int angleCount;\r
235                     int.TryParse(angleList, out angleCount);\r
236 \r
237                     for (int i = 1; i <= angleCount; i++)\r
238                         thisTitle.angles.Add(i.ToString());\r
239                 }\r
240             }\r
241 \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
244             if (m.Success)\r
245                 thisTitle.duration = TimeSpan.Parse(m.Groups[1].Value);\r
246 \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
249             if (m.Success)\r
250             {\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
255             }\r
256 \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
259             if (m.Success)\r
260                 thisTitle.autoCrop = new[]\r
261                                            {\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
264                                            };\r
265 \r
266             thisTitle.chapters.AddRange(Chapter.ParseList(output));\r
267 \r
268             thisTitle.audioTracks.AddRange(AudioTrack.ParseList(output));\r
269 \r
270             thisTitle.subtitles.AddRange(Subtitle.ParseList(output));\r
271 \r
272             return thisTitle;\r
273         }\r
274 \r
275         /// <summary>\r
276         /// Return a list of parsed titles\r
277         /// </summary>\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
281         {\r
282             var titles = new List<Title>();\r
283             var sr = new StringReader(output);\r
284 \r
285             while (sr.Peek() == '+' || sr.Peek() == ' ')\r
286             {\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
290                 else\r
291                     titles.Add(Parse(sr));\r
292             }\r
293 \r
294             return titles.ToArray();\r
295         }\r
296     }\r
297 }