OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / win / C# / Parsing / Title.cs
1 /*  Title.cs $\r
2         \r
3            This file is part of the HandBrake source code.\r
4            Homepage: <http://handbrake.fr>.\r
5            It may be used under the terms of the GNU General Public License. */\r
6 \r
7 using System;\r
8 using System.Collections.Generic;\r
9 using System.Drawing;\r
10 using System.Globalization;\r
11 using System.IO;\r
12 using System.Text.RegularExpressions;\r
13 \r
14 namespace Handbrake.Parsing\r
15 {\r
16     /// <summary>\r
17     /// An object that represents a single Title of a DVD\r
18     /// </summary>\r
19     public class Title\r
20     {\r
21         private static readonly CultureInfo Culture = new CultureInfo("en-US", false);\r
22         private readonly List<AudioTrack> m_audioTracks;\r
23         private readonly List<Chapter> m_chapters;\r
24         private readonly List<Subtitle> m_subtitles;\r
25         private List<String> m_angles = new List<string>();\r
26         private float m_aspectRatio;\r
27         private float m_fps;\r
28         private int[] m_autoCrop;\r
29         private string source;\r
30         private TimeSpan m_duration;\r
31         private Size m_resolution;\r
32         private int m_titleNumber;\r
33         private Size m_parVal;\r
34         \r
35         /// <summary>\r
36         /// The constructor for this object\r
37         /// </summary>\r
38         public Title()\r
39         {\r
40             m_audioTracks = new List<AudioTrack>();\r
41             m_chapters = new List<Chapter>();\r
42             m_subtitles = new List<Subtitle>();\r
43         }\r
44 \r
45         /// <summary>\r
46         /// Collection of chapters in this Title\r
47         /// </summary>\r
48         public List<Chapter> Chapters\r
49         {\r
50             get { return m_chapters; }\r
51         }\r
52 \r
53         /// <summary>\r
54         /// Collection of audio tracks associated with this Title\r
55         /// </summary>\r
56         public List<AudioTrack> AudioTracks\r
57         {\r
58             get { return m_audioTracks; }\r
59         }\r
60 \r
61         /// <summary>\r
62         /// Collection of subtitles associated with this Title\r
63         /// </summary>\r
64         public List<Subtitle> Subtitles\r
65         {\r
66             get { return m_subtitles; }\r
67         }\r
68 \r
69         /// <summary>\r
70         /// The track number of this Title\r
71         /// </summary>\r
72         public int TitleNumber\r
73         {\r
74             get { return m_titleNumber; }\r
75         }\r
76 \r
77         /// <summary>\r
78         /// Source Name\r
79         /// </summary>\r
80         public string SourceName\r
81         {\r
82             get { return source;  }\r
83         }\r
84 \r
85         /// <summary>\r
86         /// The length in time of this Title\r
87         /// </summary>\r
88         public TimeSpan Duration\r
89         {\r
90             get { return m_duration; }\r
91         }\r
92 \r
93         /// <summary>\r
94         /// The resolution (width/height) of this Title\r
95         /// </summary>\r
96         public Size Resolution\r
97         {\r
98             get { return m_resolution; }\r
99         }\r
100 \r
101         /// <summary>\r
102         /// The aspect ratio of this Title\r
103         /// </summary>\r
104         public float AspectRatio\r
105         {\r
106             get { return m_aspectRatio; }\r
107         }\r
108 \r
109         /// <summary>\r
110         /// Par Value\r
111         /// </summary>\r
112         public Size ParVal\r
113         {\r
114             get { return m_parVal; }\r
115         }\r
116 \r
117         /// <summary>\r
118         /// The automatically detected crop region for this Title.\r
119         /// This is an int array with 4 items in it as so:\r
120         /// 0: \r
121         /// 1: \r
122         /// 2: \r
123         /// 3: \r
124         /// </summary>\r
125         public int[] AutoCropDimensions\r
126         {\r
127             get { return m_autoCrop; }\r
128         }\r
129 \r
130         /// <summary>\r
131         /// Collection of Angles in this Title\r
132         /// </summary>\r
133         public List<string> Angles\r
134         {\r
135             get { return m_angles; }\r
136         }\r
137 \r
138         /// <summary>\r
139         /// Collection of Angles in this Title\r
140         /// </summary>\r
141         public float Fps\r
142         {\r
143             get { return m_fps; }\r
144         }\r
145   \r
146         /// <summary>\r
147         /// Override of the ToString method to provide an easy way to use this object in the UI\r
148         /// </summary>\r
149         /// <returns>A string representing this track in the format: {title #} (00:00:00)</returns>\r
150         public override string ToString()\r
151         {\r
152             return string.Format("{0} ({1:00}:{2:00}:{3:00})", m_titleNumber, m_duration.Hours,\r
153                                  m_duration.Minutes, m_duration.Seconds);\r
154         }\r
155 \r
156         /// <summary>\r
157         /// Parse the Title Information\r
158         /// </summary>\r
159         /// <param name="output"></param>\r
160         /// <returns></returns>\r
161         public static Title Parse(StringReader output)\r
162         {\r
163             var thisTitle = new Title();\r
164 \r
165             Match m = Regex.Match(output.ReadLine(), @"^\+ title ([0-9]*):");\r
166             // Match track number for this title\r
167             if (m.Success)\r
168                 thisTitle.m_titleNumber = int.Parse(m.Groups[1].Value.Trim());\r
169 \r
170             // If we are scanning a groupd of files, we'll want to get the source name.\r
171             string path = output.ReadLine();\r
172             m = Regex.Match(path, @"^  \+ stream:");\r
173             if (m.Success)\r
174                 thisTitle.source = path.Replace("+ stream:", "").Trim();\r
175  \r
176             if (!Properties.Settings.Default.noDvdNav)\r
177             {\r
178                 // Get the Angles for the title.\r
179                 m = Regex.Match(output.ReadLine(), @"  \+ angle\(s\) ([0-9])");\r
180                 if (m.Success)\r
181                 {\r
182                     String angleList = m.Value.Replace("+ angle(s) ", "").Trim();\r
183                     int angleCount;\r
184                     int.TryParse(angleList, out angleCount);\r
185 \r
186                     for (int i = 1; i <= angleCount; i++)\r
187                         thisTitle.m_angles.Add(i.ToString());\r
188                 }\r
189             }\r
190 \r
191             // Get duration for this title\r
192             m = Regex.Match(output.ReadLine(), @"^  \+ duration: ([0-9]{2}:[0-9]{2}:[0-9]{2})");\r
193             if (m.Success)\r
194                 thisTitle.m_duration = TimeSpan.Parse(m.Groups[1].Value);\r
195 \r
196             // Get resolution, aspect ratio and FPS for this title\r
197             m = Regex.Match(output.ReadLine(),\r
198                             @"^  \+ size: ([0-9]*)x([0-9]*), pixel aspect: ([0-9]*)/([0-9]*), display aspect: ([0-9]*\.[0-9]*), ([0-9]*\.[0-9]*) fps");\r
199             //size: 720x576, pixel aspect: 16/15, display aspect: 1.33, 25.000 fps\r
200 \r
201             if (m.Success)\r
202             {\r
203                 thisTitle.m_resolution = new Size(int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value));\r
204                 thisTitle.m_parVal = new Size(int.Parse(m.Groups[3].Value), int.Parse(m.Groups[4].Value));\r
205                 thisTitle.m_aspectRatio = float.Parse(m.Groups[5].Value, Culture);\r
206                 thisTitle.m_fps = float.Parse(m.Groups[6].Value, Culture);\r
207             }\r
208 \r
209             // Get autocrop region for this title\r
210             m = Regex.Match(output.ReadLine(), @"^  \+ autocrop: ([0-9]*)/([0-9]*)/([0-9]*)/([0-9]*)");\r
211             if (m.Success)\r
212                 thisTitle.m_autoCrop = new int[]\r
213                                            {\r
214                                                int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value),\r
215                                                int.Parse(m.Groups[3].Value), int.Parse(m.Groups[4].Value)\r
216                                            };\r
217 \r
218             thisTitle.m_chapters.AddRange(Chapter.ParseList(output));\r
219 \r
220             thisTitle.m_audioTracks.AddRange(AudioTrack.ParseList(output));\r
221 \r
222             thisTitle.m_subtitles.AddRange(Subtitle.ParseList(output));\r
223 \r
224             return thisTitle;\r
225         }\r
226 \r
227         /// <summary>\r
228         /// Return a list of parsed titles\r
229         /// </summary>\r
230         /// <param name="output"></param>\r
231         /// <returns></returns>\r
232         public static Title[] ParseList(string output)\r
233         {\r
234             var titles = new List<Title>();\r
235             var sr = new StringReader(output);\r
236 \r
237             while (sr.Peek() == '+' || sr.Peek() == ' ')\r
238             {\r
239                 // If the the character is a space, then chances are the line\r
240                 if (sr.Peek() == ' ') // If the character is a space, then chances are it's the combing detected line.\r
241                     sr.ReadLine(); // Skip over it\r
242                 else\r
243                     titles.Add(Parse(sr));\r
244             }\r
245 \r
246             return titles.ToArray();\r
247         }\r
248     }\r
249 }