OSDN Git Service

CLI: update the built in presets
[handbrake-jp/handbrake-jp-git.git] / win / C# / HandBrake.ApplicationServices / 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.ApplicationServices.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.ApplicationServices.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 or sets a Collection of chapters in this Title\r
41         /// </summary>\r
42         public List<Chapter> Chapters { get; set; }\r
43 \r
44         /// <summary>\r
45         /// Gets or sets a Collection of audio tracks associated with this Title\r
46         /// </summary>\r
47         public List<AudioTrack> AudioTracks { get; set; }\r
48 \r
49         /// <summary>\r
50         /// Gets or sets a Collection of subtitles associated with this Title\r
51         /// </summary>\r
52         public List<Subtitle> Subtitles { get; set; }\r
53 \r
54         /// <summary>\r
55         /// Gets or sets The track number of this Title\r
56         /// </summary>\r
57         public int TitleNumber { get; set; }\r
58 \r
59         /// <summary>\r
60         /// Gets or sets the length in time of this Title\r
61         /// </summary>\r
62         public TimeSpan Duration { get; set; }\r
63 \r
64         /// <summary>\r
65         /// Gets or sets the resolution (width/height) of this Title\r
66         /// </summary>\r
67         public Size Resolution { get; set; }\r
68 \r
69         /// <summary>\r
70         /// Gets or sets the aspect ratio of this Title\r
71         /// </summary>\r
72         public double AspectRatio { get; set; }\r
73 \r
74         /// <summary>\r
75         /// Gets or sets AngleCount.\r
76         /// </summary>\r
77         public int AngleCount { get; set; }\r
78 \r
79         /// <summary>\r
80         /// Gets or sets Par Value\r
81         /// </summary>\r
82         public Size ParVal { get; set; }\r
83 \r
84         /// <summary>\r
85         /// Gets or sets 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; set; }\r
93 \r
94         /// <summary>\r
95         /// Gets or sets the FPS of the source.\r
96         /// </summary>\r
97         public double Fps { get; set; }\r
98 \r
99         /// <summary>\r
100         /// Gets or sets a value indicating whether this is a MainTitle.\r
101         /// </summary>\r
102         public bool MainTitle { get; set; }\r
103 \r
104         /// <summary>\r
105         /// Gets or sets the Source Name\r
106         /// </summary>\r
107         public string SourceName { get; set; }\r
108 \r
109         #endregion\r
110 \r
111         /// <summary>\r
112         /// Parse the Title Information\r
113         /// </summary>\r
114         /// <param name="output">A stingreader of output data</param>\r
115         /// <returns>A Title</returns>\r
116         public static Title Parse(StringReader output)\r
117         {\r
118             var thisTitle = new Title();\r
119             string nextLine = output.ReadLine();\r
120 \r
121             // Get the Title Number\r
122             Match m = Regex.Match(nextLine, @"^\+ title ([0-9]*):");\r
123             if (m.Success)\r
124                 thisTitle.TitleNumber = int.Parse(m.Groups[1].Value.Trim());\r
125             nextLine = output.ReadLine();\r
126 \r
127             // Detect if this is the main feature\r
128             m = Regex.Match(nextLine, @"  \+ Main Feature");\r
129             if (m.Success)\r
130             {\r
131                 thisTitle.MainTitle = true;\r
132                 nextLine = output.ReadLine();\r
133             }\r
134 \r
135             // Get the stream name for file import\r
136             m = Regex.Match(nextLine, @"^  \+ stream:");\r
137             if (m.Success)\r
138             {\r
139                 thisTitle.SourceName = nextLine.Replace("+ stream:", string.Empty).Trim();\r
140                 nextLine = output.ReadLine();\r
141             }\r
142 \r
143             // Jump over the VTS and blocks line\r
144             m = Regex.Match(nextLine, @"^  \+ vts:");\r
145             if (nextLine.Contains("blocks") || nextLine.Contains("+ vts "))\r
146             {\r
147                 nextLine = output.ReadLine();\r
148             }\r
149        \r
150             // Multi-Angle Support if LibDvdNav is enabled\r
151             if (!Init.DisableDvdNav)\r
152             {\r
153                 m = Regex.Match(nextLine, @"  \+ angle\(s\) ([0-9])");\r
154                 if (m.Success)\r
155                 {\r
156                     string angleList = m.Value.Replace("+ angle(s) ", string.Empty).Trim();\r
157                     int angleCount;\r
158                     int.TryParse(angleList, out angleCount);\r
159 \r
160                     thisTitle.AngleCount = angleCount;\r
161                     nextLine = output.ReadLine();\r
162                 }\r
163             }\r
164 \r
165             // Get duration for this title\r
166             m = Regex.Match(nextLine, @"^  \+ duration: ([0-9]{2}:[0-9]{2}:[0-9]{2})");\r
167             if (m.Success)\r
168                 thisTitle.Duration = TimeSpan.Parse(m.Groups[1].Value);\r
169 \r
170             // Get resolution, aspect ratio and FPS for this title\r
171             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
172             if (m.Success)\r
173             {\r
174                 thisTitle.Resolution = new Size(int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value));\r
175                 thisTitle.ParVal = new Size(int.Parse(m.Groups[3].Value), int.Parse(m.Groups[4].Value));\r
176                 thisTitle.AspectRatio = float.Parse(m.Groups[5].Value, Culture);\r
177                 thisTitle.Fps = float.Parse(m.Groups[6].Value, Culture);\r
178             }\r
179 \r
180             // Get autocrop region for this title\r
181             m = Regex.Match(output.ReadLine(), @"^  \+ autocrop: ([0-9]*)/([0-9]*)/([0-9]*)/([0-9]*)");\r
182             if (m.Success)\r
183             {\r
184                 thisTitle.AutoCropDimensions = new Cropping\r
185                     {\r
186                         Top = int.Parse(m.Groups[1].Value),\r
187                         Bottom = int.Parse(m.Groups[2].Value),\r
188                         Left = int.Parse(m.Groups[3].Value),\r
189                         Right = int.Parse(m.Groups[4].Value)\r
190                     };\r
191             }\r
192 \r
193             thisTitle.Chapters.AddRange(Chapter.ParseList(output));\r
194 \r
195             thisTitle.AudioTracks.AddRange(AudioTrack.ParseList(output));\r
196 \r
197             thisTitle.Subtitles.AddRange(Subtitle.ParseList(output));\r
198 \r
199             return thisTitle;\r
200         }\r
201 \r
202         /// <summary>\r
203         /// Return a list of parsed titles\r
204         /// </summary>\r
205         /// <param name="output">The Output</param>\r
206         /// <returns>A List of titles</returns>\r
207         public static Title[] ParseList(string output)\r
208         {\r
209             var titles = new List<Title>();\r
210             var sr = new StringReader(output);\r
211 \r
212             while (sr.Peek() == '+' || sr.Peek() == ' ')\r
213             {\r
214                 // If the the character is a space, then chances are the line\r
215                 if (sr.Peek() == ' ') // If the character is a space, then chances are it's the combing detected line.\r
216                     sr.ReadLine(); // Skip over it\r
217                 else\r
218                     titles.Add(Parse(sr));\r
219             }\r
220 \r
221             return titles.ToArray();\r
222         }\r
223 \r
224         /// <summary>\r
225         /// Override of the ToString method to provide an easy way to use this object in the UI\r
226         /// </summary>\r
227         /// <returns>A string representing this track in the format: {title #} (00:00:00)</returns>\r
228         public override string ToString()\r
229         {\r
230             return string.Format("{0} ({1:00}:{2:00}:{3:00})", TitleNumber, Duration.Hours, Duration.Minutes, Duration.Seconds);\r
231         }\r
232     }\r
233 }