Sunday, June 1. 2008WOVSuite 0.51What Is WOV1?WOV pronounced “wahhv”, stands for Wrapper Of Video, its a Mac OS X package format that contains both a non quicktime video source and a pre-parsed QuickTime reference movie and is QuickLook compatible. What’s WOV Got to Do With It2?If you have ever had a large Window Media File you want to open with WMVPlayer plugin for QuickTime, you may have noticed it’s really really slow. Same goes with Perian and MKV’s, though not nearly as bad. Since they are converting to a QuickTime movie format in memory its possible to save that file and have much quicker load times with subsequent opens. However you must be careful, because these plugins can (and have in the past) changed they way they work such that imported quicktime movies can be broken with updates, so it’s imperative that you don’t save self contained movies only reference movies external to the original file. So thats what WOV does, it keeps a reference movie which is really small and the original file combined into its package format, that makes it easy to organize these pairs, repair the reference movie if necessary in the future, and completely undo the WOV container and restore it to the original files (if you so desire). WOV WOV WOV3.So early on playing around with the idea of WOV, I soon realized it was a good format for simple non destructive QuickTime edits, so I chose one I though was particularly useful which is joining files. So there exists an option, when converting a batch of files in WOV Converter, to combine multiple files into a single WOV file. That resulting package contains a chapter-ized reference movie, the original files, and an M3U playlist of the original files. Thus when trying to open the WOV file in a non native QuickTime App it will try and open the M3U file, I choose M3U since it is so simple it’s likely to be supported in most apps (it is supported in VLC specifically). Tainted WOV4.There are decent possibilities for caveats with this format, which is why I am putting it out in this early beta and not integrating into NicePlayer right away. One of the obvious caveats is that the original type is masked, which makes it hard to tell if a non native quicktime app is going to be able to open a WOV file ahead of time. I’m not sure if that will be a big deal, but I need people to use WOVConverter & WOVOpener to get feedback to figure out stuff like that. It should be noted that there is also major issues with using WMVPlayer with WOVConverter. WMVPlayer version 2.2 must have the preference “Open Local Files Immediately” unchecked, or alternatively you must downgrade to version 2.1 to work properly with WOVConverter. The Book of WOV5.WOVSuite — entirely open source, licensed: MPL/LGPL/GPL has a few parts:
Fun FootnotesWednesday, March 8. 2006Class ClustersRecently ElsewhereCocoa collection subclassing | Jens/Log disagrees Faux Collection Class Subclassing | AgentM and both have some bits on class clusters. AgentM’s is a rant about not being able to easily subclass collections, which I am sympathetic too recalling the joy of programing in smalltalk with its rich collection hierarchy. Jen’s is basically a response saying Class Clusters can be frustrating but their okay, just drink the koolade AgemtM. If you explain Class Clusters to someone, they makes sense, but when you try to use Apple’s or don’t know they are there, frustrating things can happen, and I don’t think that it’s really the class clusters fault. Making a composite class by wrapping or forwarding messages isn’t that much of a hassle, subclassing anything requires some knowledge of the class and Apple does document approaches to subclass class clusters, so I’m on the koolade camp on AgentM’s rant. However, I believe there are some bugs in the implementation of a few of Apple’s class clusters that cause many to think that all Class Clusters are evil. FUDI think there’s a lot of fear, uncertainty, and doubt in regards to class clusters. There really shouldn’t be though, Apple has a nice page describing the benefits of Class Clusters — Cocoa Objects: Class Clusters See a class cluster really is really just a sneaky use of a Factory Method (GOF 107) to instantiate a subclass from an abstract superclass. It’s sneaky because its hides it all. alloc, rather than actually allocating, returns a Creator (probably a singleton) and init actually allocates your real product and returns it. As demonstrated here:
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
id obj =[NSArray alloc];
NSLog(NSStringFromClass([obj class]));
NSLog(NSStringFromClass([[obj init] class]));
[pool release];
return 0;
}
2006-03-17 22:55:15.100 TestDataTypes[6105] NSPlaceholderArray 2006-03-17 22:55:15.101 TestDataTypes[6105] NSCFArray This is all good, because the classes returned are all subclasses and being the good little object oriented programers we are, we never check what a class actually is. Instead, when need to runtime type check it’s only to determine if it’s a subclass or if it responds to a method or protocol and that should be just fine with class clusters. If only using standard best practices when runtime type checking would keep us safe, unfortunately a few of Apple’s class clusters, mainly collection classes, are implemented in such a way that they break expected inheritance and expected polymorphism by advertising the wrong public interface for the returned private subclass (I don’t know if this was the case for NeXT or not, but I suspect it wasn’t). I’ll continue with some examples of where this implementation goes wrong. Dumb Responses from Class Clusters with Multiple Public SuperclassesHere’s a Pop Quiz: What should this statement return?
[[NSArray array] isKindOfClass:[NSMutableArray class]];
Ideally it should return false because when we see the documentation on these public abstract classes, NSMutableArray inherits from NSArray.
However, actually this statement returns true because the private subclasses returned for both public abstract superclasses are the same class inherited from NSMutableArray known as NSCFArray.
Okay so the purpose of having the same class is for easy toll free bridging with Core Foundation, but you know, as long as the instance variables are the same, is Core Foundation really going to care about new methods or a different hierarchy in obj-c land? I’m thinking no in theory, but I’ve not tested and I’m much happier not digging into the C-ness of Obj-C and someone can prove me wrong or right if they wish. However, if you really really wanted to keep the same private class type between the two interfaces, you can always fake the expected hierarchy by making isKindOfClass: call isSubclassOfClass: on the appropriate abstract superclass’s metaclass, and really no one would be the wiser, Core Foundation or otherwise. That was problem #1, and so you might be thinking to yourself well I don’t test for inheritance with cocoa programing often, most of the time I’ll test for specific methods out of habit, because cocoa programers tend to use informal protocols rather than having deep hierarchies anyway, so it’s not that big of a deal. So our second pop quiz: What is the result of this statement?
[[NSArray array] respondsToSelector:@selector(addObject:)];
NSArray is not supposed to respond to addObject:. I know that, you know that, but a program is generally going to believe respondsToSelector: over what we think, and respondsToSelector: says true. Of course if you run this line:
[[NSArray array] addObject:@“test”];
you get an exception. Think about when you have a bunch of objects in a collection with various types, some may respond to addObject:, some don’t, and you want to use runtime checking to manipulate them appropriately. How are you suppose to take advantage of polymorphism of this method in this case without being able to trust respondsToSelector:. There are simple work arounds to these problems, because they are only a handful of classes, but this is clearly a poor implementation of a class cluster, and I haven’t tested every class but I think all Mutable-NonMutable class hierarchies in Foundation on OS X suffer from this bug (Although GNUStep is A-OK from looking at the source), and I don’t think there’s a reason not to fix it, being that they are class clusters, all apple needs to modify are the private subclasses and people aren’t going to be using those methods currently because they return the wrong values that aren’t useful when wrong. Demonstration of Problem and FixabilityI did write a few Unit Tests to clearly demonstrate this problem with NSArray. It also has a second target called ProperClassCluster that overrides some NSCFArray methods (using categories) to fix responses in inheritance & method testing. In that target I also swizzled the addObject: method to provide an example of returning the correct exception when calling a method that doesn’t exist on an NSArray. A real fix wouldn’t require these hacks, but this works for demonstration purposes. Download ProperClassCluster.zip (20k) Continue reading "Class Clusters"Tuesday, December 27. 2005
Can Apple do Better than Objective-C? Posted by Jay
at
00:26
Comments (0) Trackbacks () Defined tags for this entry: obj-c, programming
Can Apple do Better than Objective-C?Can Apple do Better than Objective-C? a language battle royale between C# and Objective-C. I can’t believe after Christmas I get back onto a computer and find out I missed this. I want to jump into the melee but have to go to bed to go to work. But man, this is what I was hoping would have happened at EAA (Rentzsch almost did it). I think a lot of people are in denial about Objective-C having major short comings. Objective-C is a ton better than C++, harder to compare to C# and Java just because of the static vs dynamic typing philosophies, but very clunky compared with Ruby, Python, and Smalltalk. Objective-C is a very good object oriented C and so if you want C there’s nothing better, but if you don’t care about C it can be an exhausting language because you will be falling back to C a lot (but a lot of that maybe more due to lack of libraries). Update: Eh, too many people post garbage, ended up with not very interesting comments. Continue reading "Can Apple do Better than Objective-C?"Friday, December 23. 2005
In Soviet Russia you don't second ... Posted by Jay
at
11:49
Comments (0) Trackbacks () Defined tags for this entry: cocoa, programming
In Soviet Russia you don't second guess Apple, Apple second guesses YOUFrom ridiculous_fish » Blog Archive » Array: “Don’t second guess Apple, because Apple has already second guessed YOU. In a good way, of course.” I find the quote highly amusing, and the content of this post on CFArrays illuminating (and I’m just being cheeky with my post title). Continue reading "In Soviet Russia you don't second guess Apple, Apple second guesses YOU"Tuesday, October 18. 2005
Cocoa Script Menu Revised 1.01 Posted by Jay
at
23:37
Comment (1) Trackbacks () Defined tags for this entry: cocoascriptmenu, niceplayer, object oriented design, open source, programming
Cocoa Script Menu Revised 1.01So I started making some default scripts and other script examples for NicePlayer. I then realized that I needed keyboard shortcuts on the CocoaScriptMenu. DVD Player’s script menu just uses numbers in order, I don’t like that, another solution I considered was to have some kind of separate config, either gui or text file. However, since renaming is required to order and change the menu text in CocoaScriptMenu, that could get a little complicated. Keyboard ShortcutsThe solution I settled on was to add the keyboard shortcut itself to the filename. I feel this implementation ended up working really well. The main worry I had was that user error could end up disrupting the host application’s keyboard shortcuts, but the script menu is loaded later than the other menus, so it’s menu shortcuts have the least precedence and thus show up blank if a user tries to duplicate a shortcut. To facilitate adding keyboard combos to file name, I came up with an ASCII representation for the modifiers that kinda look like the real symbols and all require shift to create them (so they won’t reduce the possible representable keyboard short cuts). The symbols are as follows ∗ – Command $ – Shift ^ – Control % – Option To create a short cut you add it between two curly braces in the file name before the file extension, ordering the modifiers before the key character, such as Hello World {∗^$H}.scpt for command-control-shift-H. However after implementing this, I realized most people are going to be using a filesystem that supports unicode, and this can look a lot prettier. So I added support for these shortcuts, not just in the ascii, but using this UTF8: ⌘ – Command (0×2318 PLACE OF INTEREST SIGN) ⇧ – Shift (0×21E7 UPWARDS WHITE ARROW) ⌃ – Control (0×2303 UP ARROWHEAD) ⌥ – Option (0×2325 OPTION KEY) And you can surround them by LEFT & RIGHT SQUARE BRACKET WITH QUILL (0×2045 & 0×2046) instead of curly brackets. Such as Hello World ⁅⌃⇧⌘H⁆.scpt While UTF8 looks a bit neater, for safety sake, all my default NicePlayer scripts will use the ASCII way. And the ASCII way is also easier to type, so I’m guessing it will end up being the preferred way, but it’s left up to the user. You can even add Function Key shortcuts by just typing out {F13} or {⌃⇧F2} or even {∗F16}. and this scheme should cover a great majority of the possible keys, getting all of them however would require more parsing, which I don’t really see the need at this point, but is possible in the future. The down side is that I added a new instance variable to the Command classes, so if you do any subclassing of these classes you’ll need to recompile those subclasses with this framework Versioning and Compatibility (not a big deal as CocoaScriptMenu is meant to be embedded not shared). Count of ScriptsI added a method to the menu generator to count the number of scripts, this can be used to determine whether or not scripts are currently installed.Panther CompatibilityI did a little bit of hacking to give developers basic usage of the framework under 10.3.9, but I haven’t done any testing with other 10.3ness such as compiling under GCC 3 or actually compiling on 10.3. That said with these compatibility additions there’s a little more work needed when adding support for new filetypes or being more specific with filetypes, as I pretty much just fake the UTI stuff when it runs in Panther and thus more faking or a better solution is required, but if you don’t care about 10.3 then you can continue to not worry about it.PSMarsEdit rocks, I wrote this post in it and didn’t have to worry about the UTF8 characters, they were safely converted to html Entities. Continue reading "Cocoa Script Menu Revised 1.01" Sunday, September 25. 2005
My Sunday Project - Reusable Cocoa ... Posted by Jay
at
00:25
Comments (8) Trackbacks () Defined tags for this entry: cocoascriptmenu, niceplayer, object oriented design, open source, programming
My Sunday Project - Reusable Cocoa Script MenuThe Sunday ProjectSo last sunday I started on something new, really it’s a feature for NicePlayer, but also a feature in a lot of other existing apps out there, and could be useful in a lot of cocoa programs that don’t have this feature yet, so I wrote my implementation as an embedable framework, and am releasing under the MPL/LGPL/GPL (my latest preferred OSI approved license for those who notice what license I release under). So here’s a riddle, what do iTunes, DVD Player, Xcode, FlySketch, NetNewsWire, MarsEdit and BBEdit all have in common? Give up? They all have one of these (more or less):
Their own script menu. Uses in NicePlayerHaving a script menu in NicePlayer has been something in the back of my mind for a while. There are some features requests, while really simple, are very specific to individual user needs and we can’t justify adding a feature. Sometimes there are features requests that just don’t fit into Robert’s or my idea of NicePlayer, and we barely have enough time to add the features we want to add, so in the next release users can add their own menu commands in this script menu. One of the features introduced in 0.92 of NicePlayer was an option to remove the fixed aspect ratio. Maybe you want to distort the movie, maybe the aspect ratio is just slightly off, this feature works in those cases, and only adds one more menu to the window and is inline with adding basic window options in the Window menu that we did before. However this isn’t useful when someone has a lot of media that is consistently using non-square pixels. In the case of standard media formats, the proper behavior of NicePlayer should be to automatically adjust (this feature has been added for the DV codec when using the CoreVideo plugin in the next version of NicePlayer 0.93). However there are people out there for some reason, how have media that is encoded with non-square pixels for no standard reason, and there isn’t a way to detect the correct aspect ratio. It turns out writing an AppleScript with the current NicePlayer dictionary to set a Window to a different aspect ratio is pretty trivial, so this is one of the scripts we’ll likely include in the next release (since its one the scripts i’ve been using to test anyway). I think the main benefit of having the script menu, will be nicer integration with other apps. Whether having it integrate with a cataloging app, Toast, or just organizing with the finder, there seem to be many potential uses in this respect. CocoaScriptMenu.Framework in Your Own ProgramThe framework is called CocoaScriptMenu.Framework and available on my software page. It’s not my favorite name of the software I’ve written, but I think it’ll help in being google-able for those wanting it’s feature. I’m releasing it as version 1.0, and as I said before under the MPL/LGPL/GPL license. The basic way to use it is to:
And that will give you a typical script menu once you compile and run your app. FeaturesI wrote typical, as not all script menus are the same. I tried to add what I felt were the best features of all the script menus, while being able to behave, depending on how you use it, like 80% of the script menus I’ve seen with out any extra customization. Some of the features are
Extending w/o ModifyingThe singleton [CSMScriptMenu sharedMenuGenerator] has 4 optional delegate methods that allow you to keep the core functionality but make some slightly different script menus without having to modify the source (although modification is certainly an option. (warning most of this is untested as I use only the default implementation of each of these in NicePlayer) -(NSMenuItem*)showScriptFolderMenuItem; -(NSArray*)argumentsForShellScripts; -(id)scriptMenuItemOrItems; -(NSArray*)scriptLocations; Extending by ModifyingSo in version 1.0 the script running implementations are very basic. They are setup as a Class Cluster, with the CSMCommand class providing the public interface and several subclasses that implement script running for various types of scripts or executables. Diagram of class hierarchy: alloc on CSMCommand returns a singleton instance of CSMPlaceholderCommand. CSMPlaceholderCommand’s initWithScriptPath: works as parameterized factory method and depending on the path passed in returns the correct concrete implementation allocated and initialized. So to extend the implementation of script execution for an existing file type, you would just modify one of the subclasses. To add a new filetype you would modify the initWithScriptPath: factory method and add a new subclass. initWithScriptPath: uses Apple’s Uniform Type Identifiers to determine which concrete class to instantiate, so order does matter, make sure you add the more specific type checks in the beginning of the method and the more general towards the end. There are a lot of ways that I can think of that the concrete script execution classes could be improved, however for NicePlayer these all work well, thus I figured for version 1.0 it was better to stick with the basic implementation and release it now, rather than try and over engineer. So I’ll wait and see if people need more or not, not to mention they have the option of contributing code. Updated at Cocoa Script Menu Revised 1.01 Continue reading "My Sunday Project - Reusable Cocoa Script Menu"Thursday, March 10. 2005iTunes Music Library.xmlSo someone asked me a question, and I’ve had this question before, so I decided to answer it in my blog. Tom asks: One thing that’s been confusing me for awhile is locating the XML file for the iTunes library. The iTunes library can be in an arbitrary location, so relying on it being in ~/Music/iTunes/ is bound to fail for anyone who relocates their library. It’s a pretty good question, when I originally looked into locating the iTunes Music Library.xml file (for the Music Recommendation System), I also was under the impression that the file could be in arbitrary places just like Tom. However, I soon discoved that there are only specific places that file can exist. It had only seemed like this wasn’t the case because the default location for iTunes Music Folder is the same as where your library files need to be. So if you look for the library file at ~/Music/iTunes/iTunes Music Library.xml, you’ll be okay even if the Music Folder is set to be somewhere else.
So that’s easy enough, but wait, you may now be wondering did If I really mean “places” when I wrote “specific places” and indeed there is another place your library could be located, ~/Documents/iTunes/iTunes Music Library.xml. iTunes checks in precedence for the iTunes folder, first ~/Music, if it doesn’t find it there it checks in /Documents. If all you have is the iTunes folder /Documents it will use the library there and save and update it, if you have both, it will use ~/Music. If you have neither it create a folder in ~/Music. Another thing you should do to make sure that you find the iTunes Music Library.xml file, is because some people tend to movie things around with aliases, you need to resolve aliases in that path, you can do that with this code from Apple. So that’s basically all you have to do to find the iTunes Music Library.xml file. And if for some reason you program still can’t find the xml file you can pop up an open dialog box. There are some other notes about the xml file worth noting, it’s periodically updated, and seems to be in place for Cocoa apps like iMovie, iPhoto, and iDVD, however none of them check for the file in ~/Documents (so if you look in the the secondary location, you and iTunes are already one step in sync better than Apple’s own iApps). The tracks are also numbered inside the XML with a Track ID, and in AppleScript they are referred to as “Database ID”, these values aren’t constant, and every so often they get renumbered, it’s worth noting as this has been the bane of iEatBrainz in the past and present. Finally, while it doesn’t concern most, in my opinion there is a major bug regarding the dates in the XML file. The XML file uses the GMT offset for the daylight savings time that you are currently observing, not the offset for when that date occurred in time. So on this day of posting I’m currently not observing daylight savings time. So that’s 6 hours behind GMT where my thinks it’s located. Song A was added in November (not DTS, thus 6 hours behind) Which is right, everything matches, however: Song B with a Data added in July, thus in DTS That’s wrong! the XML doesn’t match up with the GUI and AppleScript! If I change my current time to a day in daylight savings time: iTunes rewrote the date, and now the time matches the GUI, however all the non DTS dates now don’t match! It’s just frustrating, I filed a bug report with Apple last June, but I’m not sure if they care as iMovie, iDVD, and iPhoto, don’t care about dates. So yeah, I guess that’s the iTunes Music Library.xml file in a nutshell. Continue reading "iTunes Music Library.xml"Thursday, February 24. 2005
iEatBrainz -- the status, ... Posted by Jay
at
22:57
Comments (8) Trackbacks () Defined tags for this entry: ieatbrainz, programming
iEatBrainz -- the status, Introducing iEatMetaSo it feels like with each new version of iTunes, the hackish applescript retagging gets less effective. It motivated me to dig deeper in finding out about how meta information is stored in the M4A files. I found out it was pretty easy to parse (ATOMS are amazing) and I had a test app, and figured out all the atoms that I would need to know to read the equivalent of what iTunes allows you to edit. After that i decided I’d try getting mp3 id3 tags using a library. So I wanted something that i could dynamically link to (with out making my code GPL) and low level to get iTunes specific tags, thus I used id3lib, which seems work really well. I’m a little concerned that projects seem to moving from this to libid3tag, however, the only complaints I’ve read are that it’s “over engineered” which makes me feel a little better. I have a library now, iEatMeta.Framework, that reads metadata, and I’m currently working on writing metadata, and hopefully it won’t be too long before I get it how i want it, and I release it under MPL/LGPL. This framework would be the foundation for redesigning iEatBrianz. Continue reading "iEatBrainz -- the status, Introducing iEatMeta"Thursday, August 5. 2004iEatBrainz applescript to add iTunes selectionI received an email a little earlier asking what iEatBrainz applescript commands would allow you to add songs from an iTunes selection. iEatBrainz only has a applescript dictionary because it’s an Apple Script Studio app with a lot of Obj-C and just a small bit of applescript. However, since the applescript dictionary encompasses almost all of cocoa, it wasn’t too hard to write a script that takes the currently selected song in iEatBrainz and add it to the tagging list (As long as you know what methods to call). Open this script in Script Editor on addSongWithDatabaseID(aDatabaseID, aLibrary, aTaggingController)tell application “iEatBrainz” set aTrack to call method “trackForTrackID:” of aLibrary with parameter (aDatabaseID as string) call method “addiTunesTrack:” of aTaggingController with parameter aTrack end tell end addSongWithDatabaseID tell application “iEatBrainz” set myLibrary to call method “musicLibrary” of call method “mediator” of call method “delegate” of application set taggingController to call method “musicMatchings” of call method “mediator” of call method “delegate” of application end tell tell application “iTunes” set these_tracks to the selection of browser window 1 —if no selection if these_tracks is {} then error “No tracks are selected in the front window.” end tell repeat with i from 1 to number of items in these_tracks set this_item to item i of these_tracks tell application “iTunes” set dbID to database ID of this_item end tell addSongWithDatabaseID(dbID, myLibrary, taggingController) end repeat This still will have problems on occasion when iEatBrainz gets out of sync with iTunes, due to iTunes renumbering its database. Continue reading "iEatBrainz applescript to add iTunes selection"Tuesday, August 3. 2004Oh for Joy! For Joy! Pie Menus!So I was looking through the cocoa blogs on Cocoa Dev and I found this post Apple Pie . This guy is actually implementing pie menus, and they look rather nice too. I don’t know how many MacWarriors meetings someone would someone would bring up pie menus (Robert or Mark as I recall, one or both of them are obsessed more than I). Anyway VERY COOL!!!! Continue reading "Oh for Joy! For Joy! Pie Menus!" |
QuicksearchStatic PagesCalendar
ArchivesSyndicate This BlogShow tagged entries |
|||||||||||||||||||||||||||||||||||||||||||||||||
