2 // FilterMPlayerVideo.cs
4 // Copyright (C) 2006 Alexander Macdonald <alex@alexmac.cc>
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.
29 using System
.Diagnostics
;
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"));
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
83 if (rounded_aspect
== 1.778f
)
85 else if (rounded_aspect
== 1.6f
)
87 else if (rounded_aspect
== 1.333f
)
89 else if (rounded_aspect
== 1.25f
)
91 else if (rounded_aspect
== 0.0f
)
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;
110 } catch (System
.ComponentModel
.Win32Exception
) {
111 Log
.Warn ("Error: mplayer not found or unable to run");
116 StreamReader pout
= pc
.StandardOutput
;
120 while ((str
= pout
.ReadLine ()) != null) {
121 if (!str
.StartsWith ("ID_"))
124 string[] tokens
= str
.Split ('=');
126 if (tokens
.Length
!= 2)
129 if (str
.StartsWith ("ID_CLIP_INFO_NAME"))
130 name
= tokens
[1].ToLower ();
131 else if (str
.StartsWith ("ID_CLIP_INFO_VALUE")) {
138 AddProperty (Beagle
.Property
.New ("dc:title", tokens
[1]));
142 AddProperty (Beagle
.Property
.NewUnsearched ("dc:language", tokens
[1]));
146 AddProperty (Beagle
.Property
.NewUnsearched ("dc:copyright", tokens
[1]));
150 AddProperty (Beagle
.Property
.New ("dc:description", tokens
[1]));
154 AddProperty (Beagle
.Property
.NewUnsearched ("fixme:info:" + name
, tokens
[1]));
158 switch (tokens
[0]) {
160 case "ID_VIDEO_WIDTH":
161 width
= Convert
.ToInt32 (tokens
[1]);
164 case "ID_VIDEO_HEIGHT":
165 height
= Convert
.ToInt32 (tokens
[1]);
168 case "ID_VIDEO_ASPECT":
169 aspect
= Convert
.ToSingle (tokens
[1]);
173 fps
= Convert
.ToSingle (tokens
[1]);
176 case "ID_VIDEO_FORMAT":
177 AddProperty (Beagle
.Property
.NewKeyword ("fixme:video:codec", tokens
[1]));
181 length_seconds
= (int) Convert
.ToSingle (tokens
[1]);
185 audio_channels
= Convert
.ToInt32 (tokens
[1]);
188 case "ID_AUDIO_CODEC":
189 AddProperty (Beagle
.Property
.NewKeyword ("fixme:audio:codec", tokens
[1]));
193 AddProperty (Beagle
.Property
.NewUnsearched ("fixme:video:container", tokens
[1]));
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
;
211 AddProperty (Beagle
.Property
.NewUnsearched ("fixme:video:aspect", aspect
));
213 AddProperty (Beagle
.Property
.NewUnsearched ("fixme:video:aspect", AspectString (aspect
)));
216 AddProperty (Beagle
.Property
.NewUnsearched ("fixme:video:width", width
));
219 AddProperty (Beagle
.Property
.NewUnsearched ("fixme:video:height", height
));
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
) {
230 AddProperty (Beagle
.Property
.NewUnsearched ("fixme:audio:channel_setup", "none"));
233 AddProperty (Beagle
.Property
.NewUnsearched ("fixme:audio:channel_setup", "mono"));
236 AddProperty (Beagle
.Property
.NewUnsearched ("fixme:audio:channel_setup", "stereo"));
239 AddProperty (Beagle
.Property
.NewUnsearched ("fixme:audio:channel_setup", "4.1"));
242 AddProperty (Beagle
.Property
.NewUnsearched ("fixme:audio:channel_setup", "5.1"));
245 AddProperty (Beagle
.Property
.NewUnsearched ("fixme:audio:channel_setup", "6.1"));
248 AddProperty (Beagle
.Property
.NewUnsearched ("fixme:audio:channel_setup", "7.1"));
252 AddProperty (Beagle
.Property
.NewUnsearched ("fixme:audio:channels", audio_channels
));