converting a bunch of files to wmv in an automated fashion

Previous steps for movie creation

The steps I had been using to get my videos into a downloadable compressed format:

  1. Use WinDV to get the files off the camcorder (automatically splitting them into multiple files based on scenes) – why not just use Windows Movie Maker? I like WinDV’s easier approach to getting the DV-AVI files sitting on disk with timestamps in the filenames – that makes it easier to tell which scenes are from previous recording sessions and which are from the “current” one
  2. Load one or more of the clips into Windows Movie Maker – if you’re not sure what WMM can do, check out this review or this “how to videoblog” site – make sure to also browse around http://windowsmoviemakers.net/ as well.
  3. Maybe add some cute transitions between the clips if more than 1 (usually the Fade transition – I think it looks nice)
  4. Save Movie File (Control+P)
  5. Keep the default of My Computer for the movie location
  6. Choose an appropriate name and location for the target folder to write the .wmv file to
  7. Use the (default) “Best quality for playback on my computer (recommended)” setting for the encoding settings

Now, there’s a few things worth noting here:

  • This encoding setting indeed makes a pretty large file. While it (in my experience) is still around half the size of mpeg4 (using Nero’s encoder, which I can believe is suboptimal), it’s still pretty large for those trying to download it over dialup. This is an intentional choice on my part – my target user that will be downloading and viewing the video has broadband, and as such I don’t mind it taking them 5-10 minutes to download the video(s) and then having a much better quality video to view
  • yes, this is a setting that really isn’t targeted for distribution over a network, but again, I’m fine with that and keeping the quality is more important than saving size.
  • The “Setting details” listed doesn’t really break out the actual nitty-gritty details
  • Some people have the main target of their video work be collections of scenes like DVD’s – however, I’m not really one of them. Since I use Gallery2 for hosting my still images anyway, I’m just going to put the wmv files up in gallery (in folders as the method of collecting and sorting the scenes) and if people want to download all N scenes in a folder and watch them back-to-back, that’s simple enough to do.

Goal of automated wmv creation

Since I have a decent backlog of DV-AVI files off my camcorder, though, I don’t really want to manually create all these files through Windows Movie Maker one by one. I just want some method of doing the “convert this .avi to the .wmv with the ‘Best quality for playback on my computer’ settings” work automatically.

The first hurdle is to find the right tool for doing such an automated conversion. After some quick searches, Windows Media Encoder seems to be (appropriately) the right tool for the job, specifically a little command-line vbscript interface it comes with called wmcmd.vbs which exists just for enabling this kind of automated encoding. As a bonus, it can actually take directories for the input and output specifications and it’ll loop over the containing files for you. Very nice!As a matter of course (and as another thing to potentially play with later on), I also installed the Windows Media Format 9.5 SDK.

Now we just need the right encoder settings to pass to wmcmd.vbs and we’ll be all set! Unfortunately, though, WMM didn’t really give us nitty-gritty encoder setting details. Let’s get back to that. IMHO, this is a place where Windows Movie Maker could have done a little extra work and really helped people out here. One thing you notice from the wmcmd.vbs file is that it has the ability to save (via the -saveprofile argument) the current encoder settings to a encoder settings file (*.prx). The encoder UI also has this option. Unfortunately, though, Windows Movie Maker doesn’t have (that I could find, at least) the ability to say “hey, save these encoder settings as a profile so I can reuse it in later automated encoding”. That would have been great.

When you (or at least, I, on my particular computer and with the input being the DV-AVI files I get off my camcorder) have the “Best quality for playback on my computer” setting, the “Setting details” are:

So, great, it’s 1.7 Mbps, 720×480 (matching the DV-AVI input), and 30fps. Looking at the huge number of options for wmcmd.vbs, we’re going to need more information than this.

The search for the right encoding bit rates

I look at the built-in profiles to see if it happens to match one of them. First I check the WMEncEng.WMEncoder object (the ProfileCollection off of it, specifically) and it has these entries (on my machine):

Windows Media Video 8 for Color Pocket PCs (225 Kbps)
Windows Media Video 8 for Color Pocket PCs (150 Kbps)
Windows Media Video 8 for Dial-up Modems or Single-channel ISDN (28.8 to 56 Kbps)
Windows Media Video 8 for LAN, Cable Modem, or xDSL (100 to 768 Kbps)
Windows Media Video 8 for Dial-up Modems or LAN (28.8 to 100 Kbps)
Windows Media Video 8 for Dial-up Modems (28.8 Kbps)
Windows Media Video 8 for Dial-up Modems (56 Kbps)
Windows Media Video 8 for Local Area Network (100 Kbps)
Windows Media Video 8 for Local Area Network (256 Kbps)
Windows Media Video 8 for Local Area Network (384 Kbps)
Windows Media Video 8 for Local Area Network (768 Kbps)
Windows Media Video 8 for Broadband (NTSC, 700 Kbps)
Windows Media Video 8 for Broadband (NTSC, 1400 Kbps)
Windows Media Video 8 for Broadband (PAL, 384 Kbps)
Windows Media Video 8 for Broadband (PAL, 700 Kbps)
Windows Media Audio 8 for Dial-up Modem (Mono, 28.8 Kbps)
Windows Media Audio 8 for Dial-up Modem (FM Radio Stereo, 28.8 Kbps)
Windows Media Audio 8 for Dial-up Modem (32 Kbps)
Windows Media Audio 8 for Dial-up Modem (Near CD quality, 48 Kbps)
Windows Media Audio 8 for Dial-up Modem (CD quality, 64 Kbps)
Windows Media Audio 8 for ISDN (Better than CD quality, 96 Kbps)
Windows Media Audio 8 for ISDN (Better than CD quality, 128 Kbps)
Windows Media Video 8 for Dial-up Modem (No audio, 28.8 Kbps)
Windows Media Video 8 for Dial-up Modem (No audio, 56 Kbps)
Windows Media 8 Fair Quality based VBR for Broadband
Windows Media 8 High Quality based VBR for Broadband.
Windows Media 8 Best Quality based VBR for Broadband.
Screen Video High (CBR)
Screen Video/Audio High (CBR)
Screen Video (CBR)
Screen Video/Audio
Screen Video Medium (CBR)
Screen Video/Audio Medium (CBR)

That’s a worrisome list mainly from the perspective that everything says “Windows Media [Audio,Video] 8” when I know the actual codecs being used are version 9 (and for audio, version 9.1). This is easiest to prove by just using wmcmd.vbs on a file (default settings) and le
tting it tell you the codecs being used:

Audio :
Codec: Windows Media Audio 9.1
Video :
Codec: Windows Media Video 9

So, we’ll consider this list bogus, at least for now.

Since we know the encoder profiles are named *.prx, another easy check is to scan our hard drive for *.prx files and see what turns up. With the above installed, there are 3 main sources that turn up:

  • %ProgramFiles%Windows Media ComponentsEncoderProfiles
  • %ProgramFiles%Windows Media ComponentsEncoderSettings
  • (from Windows Media Format SDK) C:WMSDKWMFSDK95LocalizedProfiles

Doing a quick scan, nothing seems to match the right bitrate (although I’m admittedly looking for 1.7 Mbps, I’m also checking for 720×480, which is somewhat silly since that’s dictated by my input source).

How about the settings available using the actual Windows Media Encoder (wmenc.exe)? When I selected “File download (computer playback)” as the distribution method, I got a list of 7 options in the resulting Video encoding drop-down. Unfortunately, of those 1 was larger than the input (1280×720), and the rest were smaller. Since I’m actually trying to preserve the input resolution of 720×480, none of these are the option I’m looking for.

So I check the .wmv file generated by WMM to see what the actual video and audio bitrates are (via loading the output .wmv as an input video clip).

Now this is interesting – the actual output is 1660 kbps (just a reminder, in this case, k is 1000 and not 1024), and the display of 1.7 Mbps appears to be just a rounding of 1660 kbps. That rate is a composite rate, and the actual video bit rate is 1500 kbps and the audio is 160 kbps, and those 2 combine to make up the 1660 kbps of the final output.

Getting the other encoder settings right

Now we know the video and audio bit rates, but there’s still some questions left:

  • Is it 1-pass or 2-pass encoding?
  • Is it a constant bit rate (CBR) or variable bit rate (VBR)?
  • Does the encoding need to de-interlace the input?

The rest was trial-and-error, but I came up with choices of:

  • Accept the default 1-pass CBR encoding
  • De-interlace (the -v_preproc 1) because otherwise there was jagged lines in the output.  The root cause for this may be unrelated, but de-interlacing fixed the symptom, so I went with that.

The final output

After all that work, all we really end up with is the right command-line to run in order to convert an input directory of .avi files into an output directory of .wmv files with the right (desired) settings.  Note that we could use -saveprofile to save this to an actual *.prx profile kind of file, but there’s relatively little gain to that (at least for my current usage) as the command-line parameters I’m using are pretty straightforward.

C:Program FilesWindows Media ComponentsEncoder>cscript wmcmd.vbs -v_preproc 1 -v_bitrate 1500000 -a_setting 160_44_2 -input c:videocapture -output c:videowmv

does not implement interface member 'System.Collections.IEnumerable.GetEnumerator()'

What if you were coding along in C#, creating a class that’s going to implement IEnumerable<T>, and got this error?

‘FooCollection’ does not implement interface member ‘System.Collections.IEnumerable.GetEnumerator()’. ‘FooCollection.GetEnumerator()’is either static, not public, or has the wrong return type.

This comes because of the (IMHO, horrible) decision that System.Collections.Generic.IEnumerable<T> should inherit from System.Collections.IEnumerablebecause it can, apparently

Why is this such a bad decision?  Because it instantly places a “support non-generic consumers with additional code” burden on developers that may be implementing classes that will never be used by non-generic consumers.  “Because it can” is a horrible decision because it’s requiring developers (who have better things to do, like write methods that will actually be called) to write this (likely useless, as the developer didn’t code it in the first place, hence why they’re seeing this error) method.

The reason it was deemed an “acceptable” burden is because the implementation is a one-liner to have the non-generic implemented by just calling the generic one (this implementation assuming the generic one is implicitly implemented):

IEnumerable.GetEnumerator() { return GetEnumerator(); }

WordPress time zone settings and you

I had WordPress set to the “display -4 off from GMT” and it was causing problems in a couple of areas:

1) I’m in an area that uses (unfortunately) Daylight Saving Time so being a fixed number of hours off from GMT wasn’t really working too well anyway.
2) It horked up Semagic’s editing of existing posts. This isn’t really Semagic’s fault per se (MetaWeblog contributes to this), but it does contribute to the problem. Semagic happily uses the local timezone when it creates a post.

<methodcall><methodname>metaWeblog.newPost</methodname>
<datetime .iso8601>20051227T16:04:53</datetime></methodcall>

IMHO, it shouldn’t – really, nothing should ever send a non-GMT datetime over the wire – always send it GMT – if the other side needs to do timezone conversion, so be it. In this age of SOA, it’s just silly to think that the client and server are generally in the same time zone, and synchronizing on “GMT over the wire” makes life easier for all involved (much like how we standardize on network byte order, for instance).

In any case, I’ve locked down both sides of this to GMT to make life easier on me (again, really both should be GMT-only over the wire). 🙂

locking Semagic down to GMT was equally simple, thankfully, since it has a setting for that:

[Edit 2005-12-29]: It’s been fixed in Semagic build 1.5.6.5 and is now GMT over the wire 🙂

Visual Studio vs. Eclipse

Jon Skeet has posted a comparison of Visual Studio and Eclipse. Although I work in Visual Studio, that post really doesn’t do a full comparison with Eclipse. The things I’d add?

The refactoring and code assist support is far more extensive than Visual Studio (in my experience with both) – the refactoring options are like TiVo – you don’t really realize how much it helps you until you have it for awhile and then it gets taken away.

the .NET framework library really needs a BigInteger

This via the C# irc channel on freenode.

14:37 [ dman] what can i use to do huge calculations
14:37 [ dman] like _huge_
14:37 [ dman] bigger than a unsigned long huge
14:50 [ Flav] on integers?
14:50 [ Flav] or floating point?
15:00 [ dman] Flav integer calculations
15:00 [ dman] im thiking maybe an array of integers
15:00 [ tobehz] BigInteger
15:01 [ dman] BigInteger?
15:07 [ Flav] are you willing to use the J# download? 🙂
15:08 [ Flav] http://msdn.microsoft.com/msdnmag/issues/05/12/NETMatters/default.aspx
15:08 [ Flav] or, the one from codeproject (i haven’t) http://www.codeproject.com/csharp/biginteger.asp

laying the mark(up)down

So apparently there’s this syntax that I noticed used in a blog’s comments area. It seems pretty wiki-ish to me (which is a good thing, I like wiki’s), but as a tiny hint of NIH combined with a “why not just use one of the existing Wiki syntaxes?” thing going on, IMHO. 🙂

Anyone used it and wiki and liked it or not? I’m curious what others that have used both extensively think.

Simple Semagic macro for adding tag tags

After installing the SimpleTags plugin into my WordPress, and after configuring my new Semagic 1.5.6.3 install to post to my WordPress blog, I added a simple macro into Semagic to surround the selected text (via the [lj0] parameter) with the <tag> tag to make adding Technorati tags simpler.

Now I just need to fill in some of the Auto-replace entries with useful things.

Why such a weak showing for C# on Eclipse?

Every few months I do another google for Eclipse C# and it continually surprises me that Improve C# Plugin for Eclipse is what keeps showing up first, despite it being pretty old and not really (at least from what I can tell) sufficient for doing C# work at the same level of support as Eclipse has natively for Java.

I remember in the buzz days about Eclipse 3.0 (EclipseCon, for instance) how there was going to be a rock-solid C# plugin that was going to make VS no longer the best tool for the job of coding in C# – the idea was that Eclipse would be just as good (basically) at C# as Java and once developers switched their IDE to eclipse (after all, why bother with VS, even Express editions, if Eclipse is all that and more for free?), switching to Java instead of C# (to gain platform independence, or access to a larger library of, well, libraries) was very trivial.

So how come it hasn’t happened?

One conspiracy-theory-ish view of things would be to say that Eclipse in reality doesn’t want solid C# support. They want something that makes things sorta-kinda usable, but they’re actually better off if it’s a constant second-class citizen, even though the similarities are so huge that it’s pretty obvious this status would be an intentional choice. They want people to get into the uncomfortable position of working on C# in Eclipse and knowing they could get a better experience switching one of those pieces: either to Java on Eclipse or to C# on Visual Studio. With the recent Visual Studio Express Editions, it’s less of an obvious choice as the cost is “free” either way, but it’s still relatively obvious that Eclipse is an incredible Java IDE (much more extensive refactoring support than even Visual Studio 2005, unfortunately) and with the growing popularity of Eclipse, and the potential perception of the express editions as crippled, Java on Eclipse is the choice many/most(/all?) of the people put into that position will make.

What do you think? Too conspiracy theory? Think it’s just that there’s no real market for it or no one finds it interesting enough to work on an open-source C# plugin for eclipse?