Forgot to bump FSQ version. Weekend syndrome.
[beagle.git] / Filters / FilterMPlayerVideo.cs
blob1b2605196aa25ba024f58c9f7fcc6606c70a6a0a
1 //
2 // FilterMPlayerVideo.cs
3 //
4 // Copyright (C) 2006 Alexander Macdonald <alex@alexmac.cc>
5 //
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a
9 // copy of this software and associated documentation files (the "Software"),
10 // to deal in the Software without restriction, including without limitation
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 // and/or sell copies of the Software, and to permit persons to whom the
13 // Software is furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 // DEALINGS IN THE SOFTWARE.
27 using System;
28 using System.IO;
29 using System.Diagnostics;
31 using Beagle.Util;
32 using Beagle.Daemon;
34 namespace Beagle.Filters {
36 public class FilterMPlayerVideo : Beagle.Daemon.Filter {
38 private int width = -1;
39 private int height = -1;
40 private float aspect = 0.0f;
41 private float fps = 0.0f;
42 private int length_seconds = -1;
43 private int audio_channels = 0;
45 public FilterMPlayerVideo ()
47 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/dl"));
48 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/dv"));
49 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/fli"));
50 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/gl"));
51 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/mpeg"));
52 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/mp4"));
53 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/quicktime"));
54 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/mp4v-es"));
55 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/parityfec"));
56 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/pointer"));
57 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/vnd.fvt"));
58 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/vnd.motorola.video"));
59 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/vnd.motorola.videop"));
60 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/vnd.mpegurl"));
61 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/vnd.mts"));
62 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/vnd.nokia.interleaved-multimedia"));
63 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/vnd.vivo"));
64 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/x-la-asf"));
65 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/x-mng"));
66 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/x-ms-asf"));
67 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/x-ms-wm"));
68 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/x-ms-wmv"));
69 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/x-ms-wmx"));
70 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/x-ms-wvx"));
71 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/x-msvideo"));
72 AddSupportedFlavor (FilterFlavor.NewFromMimeType ("video/x-sgi-movie"));
74 PreLoad = false;
77 private string AspectString(float aspect) {
78 // work out what the human form of the aspect ratio is (e.g 16x9)
79 float rounded_aspect = (float) Math.Round (aspect, 3);
81 // FIXME: comparing floats is a bit dodgy, but i round the input
82 // so it might be ok
83 if (rounded_aspect == 1.778f)
84 return "16x9";
85 else if (rounded_aspect == 1.6f)
86 return "16x10";
87 else if (rounded_aspect == 1.333f)
88 return "4x3";
89 else if (rounded_aspect == 1.25f)
90 return "5x4";
91 else if (rounded_aspect == 0.0f)
92 return "unknown";
93 else
94 return "other";
97 protected override void DoPullProperties ()
99 // create new external process
100 Process pc = new Process ();
101 pc.StartInfo.FileName = "mplayer";
102 pc.StartInfo.Arguments = " -vo null -ao null -frames 0 -identify \"" + FileInfo.FullName+"\"";
103 pc.StartInfo.RedirectStandardInput = false;
104 pc.StartInfo.RedirectStandardOutput = true;
105 pc.StartInfo.RedirectStandardError = true;
106 pc.StartInfo.UseShellExecute = false;
108 try {
109 pc.Start ();
110 } catch (System.ComponentModel.Win32Exception) {
111 Log.Warn ("Error: mplayer not found or unable to run");
112 Error ();
113 return;
116 StreamReader pout = pc.StandardOutput;
117 string str;
118 string name = "";
120 while ((str = pout.ReadLine ()) != null) {
121 if (!str.StartsWith ("ID_"))
122 continue;
124 string[] tokens = str.Split ('=');
126 if (tokens.Length != 2)
127 continue;
129 if (str.StartsWith ("ID_CLIP_INFO_NAME"))
130 name = tokens [1].ToLower ();
131 else if (str.StartsWith ("ID_CLIP_INFO_VALUE")) {
132 switch (name) {
134 case "":
135 break;
137 case "name":
138 AddProperty (Beagle.Property.New ("dc:title", tokens [1]));
139 break;
141 case "language":
142 AddProperty (Beagle.Property.NewUnsearched ("dc:language", tokens [1]));
143 break;
145 case "copyright":
146 AddProperty (Beagle.Property.NewUnsearched ("dc:copyright", tokens [1]));
147 break;
149 case "comments":
150 AddProperty (Beagle.Property.New ("dc:description", tokens [1]));
151 break;
153 default:
154 AddProperty (Beagle.Property.NewUnsearched ("fixme:info:" + name, tokens [1]));
155 break;
157 } else {
158 switch (tokens [0]) {
160 case "ID_VIDEO_WIDTH":
161 width = Convert.ToInt32 (tokens [1]);
162 break;
164 case "ID_VIDEO_HEIGHT":
165 height = Convert.ToInt32 (tokens [1]);
166 break;
168 case "ID_VIDEO_ASPECT":
169 aspect = Convert.ToSingle (tokens [1]);
170 break;
172 case "ID_VIDEO_FPS":
173 fps = Convert.ToSingle (tokens [1]);
174 break;
176 case "ID_VIDEO_FORMAT":
177 AddProperty (Beagle.Property.NewKeyword ("fixme:video:codec", tokens [1]));
178 break;
180 case "ID_LENGTH":
181 length_seconds = (int) Convert.ToSingle (tokens [1]);
182 break;
184 case "ID_AUDIO_NCH":
185 audio_channels = Convert.ToInt32 (tokens [1]);
186 break;
188 case "ID_AUDIO_CODEC":
189 AddProperty (Beagle.Property.NewKeyword ("fixme:audio:codec", tokens [1]));
190 break;
192 case "ID_DEMUXER":
193 AddProperty (Beagle.Property.NewUnsearched ("fixme:video:container", tokens [1]));
194 break;
199 pout.Close ();
200 pc.WaitForExit ();
201 pc.Close ();
203 // If an aspect ratio wasn't set in the file then work out the
204 // pixel aspect ratio
205 if (aspect <= 0.0f) {
206 if (width > 0 && height > 0)
207 aspect = (float) width / (float) height;
210 if (aspect > 0.0f)
211 AddProperty (Beagle.Property.NewUnsearched ("fixme:video:aspect", aspect));
213 AddProperty (Beagle.Property.NewUnsearched ("fixme:video:aspect", AspectString (aspect)));
215 if (width > 0)
216 AddProperty (Beagle.Property.NewUnsearched ("fixme:video:width", width));
218 if (height > 0)
219 AddProperty (Beagle.Property.NewUnsearched ("fixme:video:height", height));
221 if (fps > 0.0f)
222 AddProperty (Beagle.Property.NewUnsearched ("fixme:video:fps", fps));
224 if (length_seconds > 0)
225 AddProperty (Beagle.Property.NewUnsearched ("dc:extent", length_seconds));
227 switch (audio_channels) {
229 case 0:
230 AddProperty (Beagle.Property.NewUnsearched ("fixme:audio:channel_setup", "none"));
231 break;
232 case 1:
233 AddProperty (Beagle.Property.NewUnsearched ("fixme:audio:channel_setup", "mono"));
234 break;
235 case 2:
236 AddProperty (Beagle.Property.NewUnsearched ("fixme:audio:channel_setup", "stereo"));
237 break;
238 case 5:
239 AddProperty (Beagle.Property.NewUnsearched ("fixme:audio:channel_setup", "4.1"));
240 break;
241 case 6:
242 AddProperty (Beagle.Property.NewUnsearched ("fixme:audio:channel_setup", "5.1"));
243 break;
244 case 7:
245 AddProperty (Beagle.Property.NewUnsearched ("fixme:audio:channel_setup", "6.1"));
246 break;
247 case 8:
248 AddProperty (Beagle.Property.NewUnsearched ("fixme:audio:channel_setup", "7.1"));
249 break;
252 AddProperty (Beagle.Property.NewUnsearched ("fixme:audio:channels", audio_channels));
254 Finished ();