OSDN Git Service

LinGui: Improvements to audio panel
[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     using Handbrake.Model;\r
16 \r
17     /// <summary>\r
18     /// An object that represents a single Title of a DVD\r
19     /// </summary>\r
20     public class Title\r
21     {\r
22         /// <summary>\r
23         /// The Culture Info\r
24         /// </summary>\r
25         private static readonly CultureInfo Culture = new CultureInfo("en-US", false);\r
26 \r
27         /// <summary>\r
28         /// Initializes a new instance of the <see cref="Title"/> class. \r
29         /// </summary>\r
30         public Title()\r
31         {\r
32             AudioTracks = new List<AudioTrack>();\r
33             Chapters = new List<Chapter>();\r
34             Subtitles = new List<Subtitle>();\r
35         }\r
36 \r
37         #region Properties\r
38 \r
39         /// <summary>\r
40         /// Gets a Collection of chapters in this Title\r
41         /// </summary>\r
42         public List<Chapter> Chapters { get; private set; }\r
43 \r
44         /// <summary>\r
45         /// Gets a Collection of audio tracks associated with this Title\r
46         /// </summary>\r
47         public List<AudioTrack> AudioTracks { get; private set; }\r
48 \r
49         /// <summary>\r
50         /// Gets aCollection of subtitles associated with this Title\r
51         /// </summary>\r
52         public List<Subtitle> Subtitles { get; private set; }\r
53 \r
54         /// <summary>\r
55         /// Gets The track number of this Title\r
56         /// </summary>\r
57         public int TitleNumber { get; private set; }\r
58 \r
59         /// <summary>\r
60         /// Gets the length in time of this Title\r
61         /// </summary>\r
62         public TimeSpan Duration { get; private set; }\r
63 \r
64         /// <summary>\r
65         /// Gets the resolution (width/height) of this Title\r
66         /// </summary>\r
67         public Size Resolution { get; private set; }\r
68 \r
69         /// <summary>\r
70         /// Gets the aspect ratio of this Title\r
71         /// </summary>\r
72         public double AspectRatio { get; private set; }\r
73 \r
74         /// <summary>\r
75         /// Gets AngleCount.\r
76         /// </summary>\r
77         public int AngleCount { get; private set; }\r
78 \r
79         /// <summary>\r
80         /// Gets Par Value\r
81         /// </summary>\r
82         public Size ParVal { get; private set; }\r
83 \r
84         /// <summary>\r
85         /// Gets the automatically detected crop region for this Title.\r
86         /// This is an int array with 4 items in it as so:\r
87         /// 0: T\r
88         /// 1: B\r
89         /// 2: L\r
90         /// 3: R\r
91         /// </summary>\r
92         public Cropping AutoCropDimensions { get; private set; }\r
93 \r
94         /// <summary>\r
95         /// Gets the FPS of the source.\r
96         /// </summary>\r
97         public double Fps { get; private set; }\r
98 \r
99         /// <summary>\r
100         /// Gets a value indicating whether this is a MainTitle.\r
101         /// </summary>\r
102         public bool MainTitle { get; private set; }\r
103 \r
104         /// <summary>\r
105         /// Gets the Source Name\r
106         /// </summary>\r
107         public string SourceName { get; private set; }\r
108 \r
109         #endregion\r
110 \r
111         /// <summary>\r
112         /// Creates a Title\r
113         /// </summary>\r
114         /// <param name="angles">\r
115         /// The angles.\r
116         /// </param>\r
117         /// <param name="aspectRatio">\r
118         /// The aspect Ratio.\r
119         /// </param>\r
120         /// <param name="audioTracks">\r
121         /// The audio Tracks.\r
122         /// </param>\r
123         /// <param name="crop">\r
124         /// The crop.\r
125         /// </param>\r
126         /// <param name="chapters">\r
127         /// The chapters.\r
128         /// </param>\r
129         /// <param name="duration">\r
130         /// The duration.\r
131         /// </param>\r
132         /// <param name="fps">\r
133         /// The fps.\r
134         /// </param>\r
135         /// <param name="mainTitle">\r
136         /// The main Title.\r
137         /// </param>\r
138         /// <param name="parVal">\r
139         /// The par Val.\r
140         /// </param>\r
141         /// <param name="resolution">\r
142         /// The resolution.\r
143         /// </param>\r
144         /// <param name="sourceName">\r
145         /// The source Name.\r
146         /// </param>\r
147         /// <param name="subtitles">\r
148         /// The subtitles.\r
149         /// </param>\r
150         /// <param name="titleNumber">\r
151         /// The title Number.\r
152         /// </param>\r
153         /// <returns>\r
154         /// A Title Object\r
155         /// </returns>\r
156         public static Title CreateTitle(int angles, double aspectRatio, List<AudioTrack> audioTracks, Cropping crop, List<Chapter> chapters,\r
157                                  TimeSpan duration, float fps, bool mainTitle, Size parVal, Size resolution, string sourceName, List<Subtitle> subtitles,\r
158                                  int titleNumber)\r
159         {\r
160             Title title = new Title\r
161             {\r
162                 AngleCount = angles,\r
163                 AspectRatio = aspectRatio,\r
164                 AudioTracks = audioTracks,\r
165                 AutoCropDimensions = crop,\r
166                 Chapters = chapters,\r
167                 Duration = duration,\r
168                 Fps = fps,\r
169                 MainTitle = mainTitle,\r
170                 ParVal = parVal,\r
171                 Resolution = resolution,\r
172                 SourceName = sourceName,\r
173                 Subtitles = subtitles,\r
174                 TitleNumber = titleNumber\r
175             };\r
176 \r
177             return title;\r
178         }\r
179 \r
180         /// <summary>\r
181         /// Parse the Title Information\r
182         /// </summary>\r
183         /// <param name="output">A stingreader of output data</param>\r
184         /// <returns>A Title</returns>\r
185         public static Title Parse(StringReader output)\r
186         {\r
187             var thisTitle = new Title();\r
188 \r
189             Match m = Regex.Match(output.ReadLine(), @"^\+ title ([0-9]*):");\r
190             // Match track number for this title\r
191             if (m.Success)\r
192                 thisTitle.TitleNumber = int.Parse(m.Groups[1].Value.Trim());\r
193 \r
194             // If we are scanning a groupd of files, we'll want to get the source name.\r
195             string path = output.ReadLine();\r
196 \r
197             m = Regex.Match(path, @"  \+ Main Feature");\r
198             if (m.Success)\r
199             {\r
200                 thisTitle.MainTitle = true;\r
201                 path = output.ReadLine();\r
202             }\r
203 \r
204             m = Regex.Match(path, @"^  \+ stream:");\r
205             if (m.Success)\r
206                 thisTitle.SourceName = path.Replace("+ stream:", string.Empty).Trim();\r
207 \r
208             if (!Properties.Settings.Default.noDvdNav)\r
209             {\r
210                 // Get the Angles for the title.\r
211                 m = Regex.Match(output.ReadLine(), @"  \+ angle\(s\) ([0-9])");\r
212                 if (m.Success)\r
213                 {\r
214                     string angleList = m.Value.Replace("+ angle(s) ", string.Empty).Trim();\r
215                     int angleCount;\r
216                     int.TryParse(angleList, out angleCount);\r
217 \r
218                     thisTitle.AngleCount = angleCount;\r
219                 }\r
220             }\r
221 \r
222             // Get duration for this title\r
223             m = Regex.Match(output.ReadLine(), @"^  \+ duration: ([0-9]{2}:[0-9]{2}:[0-9]{2})");\r
224             if (m.Success)\r
225                 thisTitle.Duration = TimeSpan.Parse(m.Groups[1].Value);\r
226 \r
227             // Get resolution, aspect ratio and FPS for this title\r
228             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
229             if (m.Success)\r
230             {\r
231                 thisTitle.Resolution = new Size(int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value));\r
232                 thisTitle.ParVal = new Size(int.Parse(m.Groups[3].Value), int.Parse(m.Groups[4].Value));\r
233                 thisTitle.AspectRatio = float.Parse(m.Groups[5].Value, Culture);\r
234                 thisTitle.Fps = float.Parse(m.Groups[6].Value, Culture);\r
235             }\r
236 \r
237             // Get autocrop region for this title\r
238             m = Regex.Match(output.ReadLine(), @"^  \+ autocrop: ([0-9]*)/([0-9]*)/([0-9]*)/([0-9]*)");\r
239             if (m.Success)\r
240             {\r
241                 thisTitle.AutoCropDimensions = new Cropping\r
242                     {\r
243                         Top = int.Parse(m.Groups[1].Value),\r
244                         Bottom = int.Parse(m.Groups[2].Value),\r
245                         Left = int.Parse(m.Groups[3].Value),\r
246                         Right = int.Parse(m.Groups[4].Value)\r
247                     };\r
248             }\r
249 \r
250             thisTitle.Chapters.AddRange(Chapter.ParseList(output));\r
251 \r
252             thisTitle.AudioTracks.AddRange(AudioTrack.ParseList(output));\r
253 \r
254             thisTitle.Subtitles.AddRange(Subtitle.ParseList(output));\r
255 \r
256             return thisTitle;\r
257         }\r
258 \r
259         /// <summary>\r
260         /// Return a list of parsed titles\r
261         /// </summary>\r
262         /// <param name="output">The Output</param>\r
263         /// <returns>A List of titles</returns>\r
264         public static Title[] ParseList(string output)\r
265         {\r
266             var titles = new List<Title>();\r
267             var sr = new StringReader(output);\r
268 \r
269             while (sr.Peek() == '+' || sr.Peek() == ' ')\r
270             {\r
271                 // If the the character is a space, then chances are the line\r
272                 if (sr.Peek() == ' ') // If the character is a space, then chances are it's the combing detected line.\r
273                     sr.ReadLine(); // Skip over it\r
274                 else\r
275                     titles.Add(Parse(sr));\r
276             }\r
277 \r
278             return titles.ToArray();\r
279         }\r
280 \r
281         /// <summary>\r
282         /// Override of the ToString method to provide an easy way to use this object in the UI\r
283         /// </summary>\r
284         /// <returns>A string representing this track in the format: {title #} (00:00:00)</returns>\r
285         public override string ToString()\r
286         {\r
287             return string.Format("{0} ({1:00}:{2:00}:{3:00})", TitleNumber, Duration.Hours, Duration.Minutes, Duration.Seconds);\r
288         }\r
289 \r
290     }\r
291 }