(Back)port some changes from beagle-lucene-1-9-lockfile-branch: allow ext: queries...
[beagle.git] / Filters / FilterMPlayerVideo.cs
blob90f2491a0b31228dd960639105b1c4f9bcd39e46
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;
30 using System.Globalization;
32 using Beagle.Util;
33 using Beagle.Daemon;
35 namespace Beagle.Filters {
37 public class FilterMPlayerVideo : Beagle.Daemon.Filter {
39 private int width = -1;
40 private int height = -1;
41 private float aspect = 0.0f;
42 private float fps = 0.0f;
43 private int length_seconds = -1;
44 private int audio_channels = 0;
46 private static string[] mime_types = {
47 "application/x-matroska",
48 "video/dl",
49 "video/dv",
50 "video/fli",
51 "video/gl",
52 "video/mpeg",
53 "video/mp4",
54 "video/quicktime",
55 "video/mp4v-es",
56 "video/parityfec",
57 "video/pointer",
58 "video/vnd.fvt",
59 "video/vnd.motorola.video",
60 "video/vnd.motorola.videop",
61 "video/vnd.mpegurl",
62 "video/vnd.mts",
63 "video/vnd.nokia.interleaved-multimedia",
64 "video/vnd.vivo",
65 "video/x-la-asf",
66 "video/x-mng",
67 "video/x-ms-asf",
68 "video/x-ms-wm",
69 "video/x-ms-wmv",
70 "video/x-ms-vmx",
71 "video/x-msvideo",
72 "video/x-ogm+ogg",
73 "video/x-sgi-movie"
76 public FilterMPlayerVideo ()
78 foreach (string s in mime_types) {
79 FilterFlavor flavor = FilterFlavor.NewFromMimeType (s);
80 flavor.Priority = -1; // Prefer Totem over this one
82 AddSupportedFlavor (flavor);
85 PreLoad = false;
88 private string AspectString(float aspect) {
89 // work out what the human form of the aspect ratio is (e.g 16x9)
90 float rounded_aspect = (float) Math.Round (aspect, 3);
92 // FIXME: comparing floats is a bit dodgy, but i round the input
93 // so it might be ok
94 if (rounded_aspect == 1.778f)
95 return "16x9";
96 else if (rounded_aspect == 1.6f)
97 return "16x10";
98 else if (rounded_aspect == 1.333f)
99 return "4x3";
100 else if (rounded_aspect == 1.25f)
101 return "5x4";
102 else if (rounded_aspect == 0.0f)
103 return "unknown";
104 else
105 return "other";
108 protected override void DoPullProperties ()
110 SafeProcess pc = new SafeProcess ();
111 pc.Arguments = new string [] { "mplayer", "-vo", "null", "-ao", "null", "-frames", "0", "-identify", FileInfo.FullName };
112 pc.RedirectStandardOutput = true;
113 pc.RedirectStandardError = true;
115 try {
116 pc.Start ();
117 } catch (SafeProcessException e) {
118 Log.Warn (e.Message);
119 Error ();
120 return;
123 StreamReader pout = new StreamReader (pc.StandardOutput);
124 string str;
125 string name = "";
127 while ((str = pout.ReadLine ()) != null) {
128 if (!str.StartsWith ("ID_"))
129 continue;
131 string[] tokens = str.Split ('=');
133 if (tokens.Length != 2)
134 continue;
136 if (str.StartsWith ("ID_CLIP_INFO_NAME"))
137 name = tokens [1].ToLower ();
138 else if (str.StartsWith ("ID_CLIP_INFO_VALUE")) {
139 switch (name) {
141 case "":
142 break;
144 case "name":
145 AddProperty (Beagle.Property.New ("dc:title", tokens [1]));
146 break;
148 case "language":
149 AddProperty (Beagle.Property.NewUnsearched ("dc:language", tokens [1]));
150 break;
152 case "copyright":
153 AddProperty (Beagle.Property.NewUnsearched ("dc:copyright", tokens [1]));
154 break;
156 case "comments":
157 AddProperty (Beagle.Property.New ("dc:description", tokens [1]));
158 break;
160 default:
161 AddProperty (Beagle.Property.NewUnsearched ("fixme:info:" + name, tokens [1]));
162 break;
164 } else {
165 switch (tokens [0]) {
167 case "ID_VIDEO_WIDTH":
168 width = Convert.ToInt32 (tokens [1]);
169 break;
171 case "ID_VIDEO_HEIGHT":
172 height = Convert.ToInt32 (tokens [1]);
173 break;
175 case "ID_VIDEO_ASPECT":
176 aspect = Convert.ToSingle (tokens [1], CultureInfo.InvariantCulture);
177 break;
179 case "ID_VIDEO_FPS":
180 fps = Convert.ToSingle (tokens [1], CultureInfo.InvariantCulture);
181 break;
183 case "ID_VIDEO_FORMAT":
184 AddProperty (Beagle.Property.NewKeyword ("fixme:video:codec", tokens [1]));
185 break;
187 case "ID_LENGTH":
188 length_seconds = (int) Convert.ToSingle (tokens [1], CultureInfo.InvariantCulture);
189 break;
191 case "ID_AUDIO_NCH":
192 audio_channels = Convert.ToInt32 (tokens [1]);
193 break;
195 case "ID_AUDIO_CODEC":
196 AddProperty (Beagle.Property.NewKeyword ("fixme:audio:codec", tokens [1]));
197 break;
199 case "ID_DEMUXER":
200 AddProperty (Beagle.Property.NewUnsearched ("fixme:video:container", tokens [1]));
201 break;
206 pout.Close ();
207 pc.Close ();
209 // If an aspect ratio wasn't set in the file then work out the
210 // pixel aspect ratio
211 if (aspect <= 0.0f) {
212 if (width > 0 && height > 0)
213 aspect = (float) width / (float) height;
216 if (aspect > 0.0f)
217 AddProperty (Beagle.Property.NewUnsearched ("fixme:video:aspect", aspect));
219 AddProperty (Beagle.Property.NewUnsearched ("fixme:video:aspect", AspectString (aspect)));
221 if (width > 0)
222 AddProperty (Beagle.Property.NewUnsearched ("fixme:video:width", width));
224 if (height > 0)
225 AddProperty (Beagle.Property.NewUnsearched ("fixme:video:height", height));
227 if (fps > 0.0f)
228 AddProperty (Beagle.Property.NewUnsearched ("fixme:video:fps", fps));
230 if (length_seconds > 0)
231 AddProperty (Beagle.Property.NewUnsearched ("dc:extent", length_seconds));
233 switch (audio_channels) {
235 case 0:
236 AddProperty (Beagle.Property.NewUnsearched ("fixme:audio:channel_setup", "none"));
237 break;
238 case 1:
239 AddProperty (Beagle.Property.NewUnsearched ("fixme:audio:channel_setup", "mono"));
240 break;
241 case 2:
242 AddProperty (Beagle.Property.NewUnsearched ("fixme:audio:channel_setup", "stereo"));
243 break;
244 case 5:
245 AddProperty (Beagle.Property.NewUnsearched ("fixme:audio:channel_setup", "4.1"));
246 break;
247 case 6:
248 AddProperty (Beagle.Property.NewUnsearched ("fixme:audio:channel_setup", "5.1"));
249 break;
250 case 7:
251 AddProperty (Beagle.Property.NewUnsearched ("fixme:audio:channel_setup", "6.1"));
252 break;
253 case 8:
254 AddProperty (Beagle.Property.NewUnsearched ("fixme:audio:channel_setup", "7.1"));
255 break;
258 AddProperty (Beagle.Property.NewUnsearched ("fixme:audio:channels", audio_channels));
260 Finished ();