I saw a post in the AVS Forums which caught my eye. Well, my iEye, to be precise. It quoted a mention on xlr8yourmac’s daily news from one Graham Jones of Toronto. He was looking for beta testers for his new EyeTV helper app. I wrote to him and told him about my situation.
In particular, my interest was in this feature: “Create aliases to Mpeg files with descriptive file names.”
My thinking was that maybe this could be used with Virtual DVHS. I did some testing and determined that I could not make aliases ending .m2t to actual mpg files in my eyetv library… but I can use softlinks (which is more of a unix, less of a mac, thing).
Contacted Graham with this news. Then I realized (by picking through the source) that unless Virtual DVHS were not open already, it wouldn’t see any new files added to its media folder. So I started hacking on it.
First I made a method that I called TStreamIsKnown, which when passed a ‘stream’ object (a NSMutableArray containing filename, size, last mod date) checks to see if we already know about this stream (eg is it already in our global availTStreams list, which is itself an NSMutableArray.)
Then I added a check to the existing findAllTStreams method, which is what actually looks through the ‘media library’ folder the user specifies, and populates that availTStreams list. (The list is then used to populate the NSTableView called ‘availableTransports.’) The check I made is a call to TStreamIsKnown before adding the stream in question to availTStreams. That way, if findAllTStreams is called again, it’ll skip any files it already knows about, and instead just add the new files it finds (at the bottom of the list. Sorting be darned.)
Next, I added an NSButton, labeled “Refresh”, right above the availableTransports NSTableView, and linked it to a new method refreshFileList, which in turn just calls [self findAllTStreams]; . Then someone suggested that I also add a new NSApplication delegation for applicationDidBecomeActive. So once again, I just linked that to the same method, [self findAllTStreams]; .
Then I just mucked around some more in the Interface Builder and added some hotkey equivalents to menu items like Preferences (cmd-,) and Hide Others (opt-cmd-H) which should’ve had them in the first place.
The last part of this project that I’m embarking on right now would seem (to me, anyway) to be one of the easiest things to do: making the space bar toggle play/pause, and the escape key hit ‘stop.’ This is important to me because when I connect my Mac mini to the DVI input on my TV, I switch to ‘input 5′ to see it. But as soon as I start sending it a transport stream via i.Link (using Virtual DVHS), it ‘takes over’ the screen, much like pressing play on your VCR would cut off whatever channel it was tuned to. Hitting the ‘stop’ button returns you to Input 5… but wait, that’s an issue, because we can’t SEE the stop button in order to click it. And that’s why some keys like play / pause and stop need keyboard equivalents.
But so far I’m having a lot of trouble with it. And once again I’m running into some grey areas of Apple’s HIG: should Full Keyboard Access (something I normally love) interfere with my ability to catch keyDown events? Look at QuickTime Player. It doesn’t appear (to me) to support Full Keyboard Access at all, and spacebar is start/stop in that application. Then look at EyeTV. Yes, it’s kind of a hack, but they just map space to the ‘play’ command in their Controls menu. Wondering if this is what I should do instead.
The advice I’ve gotten so far is that I should subclass either NSApplication (Apple says in their notes that doing this can be a big pain) or NSWindow, so I decided to try subclassing NSWindow. Then I added a call to make it ‘first responder’, which I guess ups its priority in the call chain to receive keyboard events..?
Right now I’m kind of bogged down trying to understand what to actually change in the Interface Builder side of things. I asked a few times in #macdev on freenode, but I’m not feeling like I’m getting very far. Either I’m really close to getting it or I’m going about it all the wrong way.