Quart: A Raspberry Pi Prototype
Recently I have been spending my nights obsessed with this latest prototype based on everyone's favorite low-cost, low-power, educational computing platform, Raspberry Pi. I have to say, this platform and its community have cleared away any fear that the tech industry would someday yield nothing but and endless supply of lowest-common-denominator targeted "gadgets", leaving no refuge for thought. Nay, this is in fact a golden age for the curious and inventive. So now with my jaded husk removed and my enthusiasm refreshed it's time to document all the things, because I've been having too much fun to stop.
Motivation
The prototype I'm now affectionately referring to as "Quart" started with my dissatisfaction with using my XBox 360 as the media solution for our bedroom. The Windows Media Center Extender has been worthy of its tenure in our home, but every time I wanted to play a game, I'd be missing out on important visual details (truer every year), due to the extremely dated, stereo, standard definition tube in that room. Call me cheap, I just can't justify another LCD for a room where it would be so casually used. I moved the 360 downstairs in time to play Halo 4.
Enter XBMC as the obvious front runner. I really have only one overarching SAF feature requirement for this particular terminal, and that is to watch TV upstairs. TV, in this scenario is primarily qualified as recorded shows. I don't witness a lot of channel surfing and god knows I hate doing it. Nevertheless I seem to get both features with MediaPortal on my server and the latest Frodo release of XBMC. Let me say right now, from the perspective of an MCE stalwart, XBMC's is not a great TV experience right now. It's a brand new feature so I'm sure it will be improving. However this is a decision that reflects where the cable TV sits on my own list of priories, when laid next to other virtues; flexibility, internet streaming options, active support and great new features like mobile DLNA and Airplay streaming.
So what else was the hardware going to be? I had looked at some passively cooled Atom/Ion devices in the past, but this decision did not take long. The RPi runs at a positively green 3.5 Watts under load and is completely silent. Maybe not the most powerful system, but this room needed a light terminal. Now, with an open source 10 foot interface, open source operating system and open hardware platform, I could look at the whole picture with an ideal in mind.
The Ideal
Having used the XBox as an extender, It's easy to see that the gamepad as a 10-foot control peripheral works in this scenario. I simply don't need another remote for this room. Ultimately no remote, however ergonomically designed, works as well in the dark as a gamepad, and a UI built to support it. This may be a polarizing point, and I'm willing to concede that it requires two whole hands, and that in a living room it would never fly. I can't imagine flipping on my TV and expecting a visitor to find the game or start the movie this way, but this is the bedroom. It needs to be easy to use for us, but the muscle memory is an inexpensive one-time cost.
Also, my wife and I are on the cusp of generations X and Y. Are there games in our room? Yes, there are games in our room. Naturally this is not a beefy device, but it's more than capable of being a great platform on which to curate some of my favorites of old and serve them up in a pleasing way for myself, my wife and for posterity. So here then is the short list of targeted features/qualities.
1. Plays recorded cable programming from TV server
2. Plays my old games from dusty platforms
3. All functionality must be gamepad accessible. I'll be able to SSH into it for maintenance, but I don't intend to attach a keyboard or anything else.
4. Sturdy enclosure, well integrated with gamepad/s. Should be pleasing to the eye, though it will be in a cabinet.
5. Fast boots/game loads
Incidentally, similar forays by Steam and OUYA lend credence to the concept of a light-weight Linux-based network appliance as a 10-foot entertainment hub.
Current progress to these ends discussed in the next post.
Update: HTPC IR…
In my last post I talked about some of the remaining issues to solve in my attempt to migrate to a new, inexpensive remote for my HTPC. I tend to err on the side of over-engineering solutions to problems like these and well...this time is no exception. My solution consists of a virtual HID shim/miniport driver with an interface to user mode software. I wrapped this in a managed "VirtualKeyboard" class so I can call it from a service which listens for my remote commands to come in on the eHome Remote Receiver.
The benefits of this approach are twofold over sending out any kind of windows message, which is what every boxed solution I found does. First, I can code the entire solution into the service layer. Placing this functionality in a service run automatically as LocalSystem allows it to behave like a first-class input device. Always available and decoupled from UI. Yes you can inherit NativeWindow, pump and send Windows messages in a service, but I couldn't figure out any way to send a key-press there. Even if I could do it that way I don't think I'd want to.
The second benefit is proper integration with Media Center, and anything else that may require a true device identity. In order to support Media Center's 10-key SMS style text entry feature, it needs to be able to distinguish buttons pressed by a remote, which is modeled as a keyboard device in Windows, and a true keyboard. Key-presses originating from Windows messages are always handled as keyboard input. The distinction between keyboard and remote is made in the registry ("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center\Remote Controls"). The names of the values defined in this key map to hardware ID's to be handled as remotes.
I can see this component being useful with a number of software suites and other automation scenarios. IR Server Suite, EventGhost and AutoHotkey come to mind. As it is, the service I wrote is special-cased for my remote, but if you have need for such a beast, drop me a line. I can likely adapt it to other needs.
HTPC IR solutions and remaining issues
I knew this was coming. My HTPC gets a much needed upgrade and now I can't help but be plagued by every remaining problem with my setup. This week's PITA is our weathered, overused eHome remote. It has been with us since 2005, allowing us a one remote experience, with its programmable TV power, receiver volume and mute buttons and tight Media Center integration. I extended its life a few times, when a few oft-used buttons have stopped responding, by taking it apart and giving it the cotton swab and rubbing alcohol treatment. Look at this thing though. It's starting to affect my credibility as an HTPC enthusiast. Time to put it out to pasture.
So just run to Microcenter and pick up a Logitech Harmony right? Well...I have reservations, not the least of which is the perfectly functional eHome Remote Receiver already in my possession. The greatest problem I see is the expense, coupled with the already tech-fixated 18 month old boy hobbling around my living room. No, I think what I'd rather do is use the PC itself to convert signals from the non-universal remote that came with one of my Hauppauge tuners, and has since been collecting dust in the closet. It has plenty of the right buttons I need, and will be no significant loss should I find it's trampled-lifeless husk in the middle of the living room floor some evening. I may use an IR blaster to control my receiver, but I think I won't need to with the sound codec on this new motherboard.
So far I have done some research into the software that's out there to capture the signals from the new remote and send out the right commands. There are some good libraries out there, and with the eHome Receiver being an HID device, I should have an easy time of writing a little special-cased code if I need to in order to get the job done. I settled on IR Server Suite, which is actually part of the Media Portal project. IRSS has a translator app that can capture incoming IR messages and respond in different ways (Windows messages, key-presses, blasting another IR message, etc). This got me the majority of the functionality I needed, but I have two remaining gotchas:
1. I can't find a key code for the alphanumeric keys on the eHome remote. Sending a keypad number will not suffice for Media Center's text input functionality. I think these keys may map to HID's Phone Key usages, but I still need to test that theory.
2. Since, the translator application's functional paths inside a GUI application, rather than the IR service, I don't have any IR functionality on the welcome screen.
See Followup
Transcode to MP4
A few weeks ago, I talked about playing with WPF and DirectShow with WPF MediaKit. I wanted to finish a video transcoder project I had laying around for some time. Originally, it was a very simple WinForms app that guides the process of building a graph in DirectShow to extract the audio and video streams from some video file source, send them through some other compressor (or not), and place them in an MP4 container. The goal was to allow my wife to convert the files from her camera, so she could post them on YouTube (She didn't want to use GraphEdit, imagine that). At the time, HandBrake didn't exist, or wasn't available on Windows and there were plenty of paid options, but I figured I could mock up a solution at a similar cost. That was true, until I moved it to WPF and added a video preview, but whatever, it was fun. This is the result:
Transcode to MP4 - Version 1.0.0.0
Source
Required:
Haali Media Splitter: Actually, only the MP4 Multiplexer is required, but the splitter is a handy file source, supporting many formats.
Recomended:
FFDShow Tryouts: This adds a ton of functionality and customization, through the filter settings dialogs. See Issues and Solutions below.
MONOGRAM AAC Encoder: This is my own build of this filter. I found this and a number of other GPL and LGPL based DirectShow filters at RadScorpion's blog. I wanted to use this filter, but it doesn't register as an Audio Compressor in DirectShow, which this Transcoder requires. If you would like the source for my changes, please don't hesitate to ask.
There are a number of other filter options you can experiment with, and of course your mileage may vary. Also, this program will attempt to allow you to make any decision you want about what codecs you would like to use. That doesn't mean that the MP4 Multiplexer or your video player of choice will appreciate the decision you made, and this program does not protect you from this.
Options:
The Show Preview option can be found in the render options menu. Some filters don't work so nicely with the Pin Tee Filter, which is used to show a video preview during the encoding process. Turning off the Show Preview option lets this program build a graph without including the Pin Tee and Video Renderer. Media Center filters will require the Show Preview setting to be off.
The Use Clock option is the same as the one found in GraphEdit. It will generally allow the graph to progress at or below the speed of playback. You should always try leaving this option off for the sake of speed, but some filters don't appreciate being rushed.
Clicking on the gear icon next to the selected decoder filter will pop the filter's configuration dialog (if it has one). These are implemented by the filter's vendor.
Issues and Solutions:
I found out while testing this with the filters Media Center uses with WTV and DVR-MS files that some files aren't so happy working outside the bounds of their original intent. I did have success transcoding these formats, however, by turning off the Show Preview option.
In testing with FFDShow Tryouts, files with MPEG audio streams tended to halt or crash the program. This was corrected by going into the FFDShow Audio Decoder Configuration in the start menu, and under Codecs, I switched the MP1,MP2 decoder from libmad to libavcodec.
Why not just use HandBrake now?
By all means, you should if it suits your needs. HandBrake offers tons of options, is relatively user friendly and doesn't require all this mucking about with DirectShow filters. If it were out when I wrote the first pass of this, I would have had no motivation to write it. However this is an extremely open-ended tool, so if you need to transcode something that handbrake doesn't support, but for which there are DirectShow filters available, you can use this as an alternative to GraphEdit. Media Center files are a good example of this.
Please leave me a feedback if you are experiencing issues using this tool, you have feature requests, or other questions.
Wake on Lan with IronPython
Since introducing a custom built Media Center PC to my living room configuration back in 2005, the machine filling the role has also become a local storage server of sorts. The music functions and storage requirements alone make it an appealing location for centralized storage. Of course it's not always on, nor would we really want it to be, so we would need an easy way to wake it up from workstations, phones, and laptops on the LAN.
Enter Wake-on-Lan. It wasn't difficult to figure this out. In fact my Xbox, which we were using as an extender in the bedroom, was already using it. With that already working, there was no configuration to be done on the Media Center PC itself (I'll cover it anyway). Writing a WOL.exe to form the "Magic Packet" and send it was easy, setting up shortcuts on my wife's and my own systems with the right command arguments to include the port and the Media Center's MAC address was even easier.
In my last post I discussed Windows scripting, and it seemed like something like this was a good candidate for an example. Plus, back when I wrote that WOL.exe, it seemed a little heavy handed, but I still loved the simplicity of the code itself and wanted to share it.
As I said, I didn't have to mess with this, but you will need to make sure that your host's network adapter is ready to receive a Wake-on-Lan. Go to device manager, open up your favorite network adapter, and make sure the setting to the right is enabled.
While you're at it, get the MAC address of the adapter. You can do an "ipconfig /all" in the command prompt and it will be listed as "Physical Address". Write this down for later.
Some systems will require that you modify settings in the BIOS to support Wake-on-Lan. I'm not going to cover it, since BIOS menus vary, but this was another thing that I happily didn't need to do.
The Script
Pull out the MAC address you recorded from the host machine and place each hex digit in the byte array, WAKE_MAC_ADDRESS.
import clr clr.AddReference('System') clr.AddReference('System.Core') from System import * from System.Net.Sockets import * from System.Net import * from System.Linq import * WAKE_MAC_ADDRESS = Array[Byte]([0x0A,0x0D,0x0D,0x04,0x0E,0x55]) PORT = 40000 #fill the first 6 bytes of the packet with 0xFF magicPacket = Enumerable.Repeat[Byte](0xff, 6); #repeat the MAC address 16 times for i in range(16): magicPacket = Enumerable.Concat(magicPacket, WAKE_MAC_ADDRESS) #send a UDP boradcast of the magic packet socket = Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp) broadcastEndpoint = IPEndPoint(IPAddress.Broadcast, PORT) socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, True) socket.SendTo(Enumerable.ToArray(magicPacket), broadcastEndpoint) socket.Close()
Shortcut
What I did at this point was to make a shortcut called "Wake Emcee" (Emcee being the name of my Media Center PC), and pointed it to ScriptShell using the -a option so it silently executes the script and exits. Shell32.dll has the perfect icon for this. It will be the default location searched, if you click "Change Icon...".