Jay Tuley

Posts tagged with niceplayer

Cocoa Script Menu Revised 1.01 by Jay

So 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 Shortcuts

The 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

%25 – 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 Scripts

I 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 Compatibility

I 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.

PS


MarsEdit rocks, I wrote this post in it and didn’t have to worry about the UTF8 characters, they were safely converted to html Entities.

My Sunday Project - Reusable Cocoa Script Menu by Jay

The Sunday Project

So 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 NicePlayer

Having 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 Program

The 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:

  1. Add the framework binary to your project
  2. Add the framework to a copy phase that puts it into the Frameworks folder of your app bundle
  3. Add this line [[CSMScriptMenu sharedMenuGenerator] updateScriptMenu]; somewhere right after the nib loads (while including <CocoaScriptMenu/CocoaScriptMenu.h> for that file of course)

And that will give you a typical script menu once you compile and run your app.

Features

I 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%25 of the script menus I’ve seen with out any extra customization. Some of the features are

  • It looks for scripts in Application Support/AppName/Scripts in all domains.
  • You can make submenus by nesting folders.
  • You can add a menu separator by adding a file or folder with a dash as it’s name.
  • You can order scripts, separators, and folders using a two digit prefix on the file name (two digit prefix not required).
  • It runs AppleScripts, Automator Files (.workflow), Application Bundles, and Shell Scripts (sh/python/perl/whatever but remember you need executable permission for shell scripts).
  • It automatically updates the menu, without relaunching the application, as you add items or folders nested inside the script folder, unless that folder didn’t exist at Application Launch.

Extending w/o Modifying

The 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;

If your delegate implements this method, it needs to return a NSMenuItem that should be used instead of the Open Scripts Folder menu item. An example would be a menuitem with a submenu with an open command for each each script folder in the domains. The default behavior is a menuitem to open the first location returned by the delegate method -(NSArray*)scriptLocations; in the finder.

-(NSArray*)argumentsForShellScripts;
The default implementation returns nil. Implement this method in your delegate if you want to pass string arguments to any shell script. (is not used for AppleScripts, Application Bundles or Workflows)

-(id)scriptMenuItemOrItems;
This should return something that has a subMenu or menu getter for an NSMenu. This NSMenu is what the script menu items get added too. You may also return an array to add the script menu in multiple places in your app. The default implementation adds a Script Menu in-front of the Help menu and returns it.

-(NSArray*)scriptLocations;
The default implementation, returns the paths to Application Support/MainBundleName/Scripts for every domain that the path exists, with the User domain guaranteed first. Also creates the folder for the user domain if it doesn’t exist.

Extending by Modifying

So 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

Odds and Ends, Summer of Non-Code by Jay

Apple Bug Friday

So I’m was reading many blogs today, and I feel so uncool with all these “Apple Bug Friday” posts. I have an apple bug (or at least I considerate it, don’t know if apple will) that I had written some unit tests to explain the behavior problems. I’ll have to prime for next friday it’s 19 minutes past saturday!

The state of the projects

Yeah so this was not the summer of code for Jay Tuley, but now that the girlfriend is finishing school in London, I’ll have some time this fall that will need occupying with code.

So basically NicePlayer is the project that has gotten the most attention from me, because Robert works on it too, and I use it on a regular basis being that it’s now september we’ve missed another self imposed milestone, whoops. I’ll have some time to work on this for sure this fall.

i’ve worked on iEatBrainz very intermittently, fixing little bugs, trying to get the applescript update to be more reliable, I’m going to release it soon, and that will probably be the last update of that code base by me, then I’ll focus on iEatMeta.

iEatMeta was going really good in the spring, and then poof I stopped working on it as life got in the way, it’s current status is that I have reading m4a, m4p, and mp3 metadata that iTunes does plus MusicBrainz data, I want to make some design changes in the api, before releasing the source, I’m not sure the best way to implement writing the m4a tags, I have some ideas, but I think reading is quite useful, and it’s better to get the framework out there, just incase for some reason life gets in the way again.

Sleep

I had some other odds and ends but I’m too sleepy, and am starting to forget what I’m writing, I’d rather just post something now than waiting and posting later. Good night!

NicePlayer 0.92 the Dark Horse by Jay

So NicePlayer 0.92 was released this week, and it seems to be downloaded more an more with each release, it’s by no means the most popular video player but it’s got an devoted fan base growing. Tiger QuickTime 7 playback is just really awesome, and the new NicePlayer Core Video plug-in fixed the problem I had with getting dropped frames with 1080 H.264, it’s now very smooth on my Dual 2Ghz G5.

While 0.92 works on Panther, it was barely tested (but I did test it), future versions I can’t guarantee will work. A lot of AppleScript bugs in the previous version disappeared in Tiger, and also I’m getting better at making things scriptable, so I think there will be less problems with this release (at least in Tiger). The most notable applescript change was that I added some multi-screen support for the enter full screen command so that you can do:

tell application “NicePlayer”
   activate
   open choose file
   enter full screen on screen 2
end tell

and get the video to fullscreen on an alternate monitor with out having to move the window there first. Actually, since I haven’t setup my second monitor since moving, I only tested this with “on screen 1”, so that was bad of me, don’t let Robert know, and if you have multiple monitors should let me know if this works.

Something fun I thought of after releasing NicePlayer (so it wasn’t added to the example scripts) was a script for auto playing DVDs in NicePlayer when you insert a video DVD.

You just tell the System Preferences to run this script ->

on video DVD appeared aDVD
   tell application “NicePlayer”
      activate
      set tPlaylist to make new playlist
      add (POSIX path of aDVD) to tPlaylist
      enter full screen window of tPlaylist
      play tPlaylist
   end tell
end video DVD appeared

And Voilà you don’t even need to set the preferences to auto play or auto fullscreen or anything awesome!

The playlist support in NicePlayer is a much simpler than what I had planned, just haven’t had enough time. I’ve been wondering if all the stuff I wanted to add would have been excessive. I’m starting to feel more and more like the simple playlist is closer to the right level of sophistication and to go beyond that NicePlayer needs to just integrate with a separate video database program instead.

The last thing I’d like to mention, if you want to localize NicePlayer or fix a localization, email us before you try and we’ll send you the file to edit, by doing it this way we can keep translations with each version that don’t change, this technique isn’t very reliable when we are given a nib rather than this file.

Anyway that’s all for now, and I’ll post the full new feature list here:

Latest release: 0.92 (v320)

  • Basic Saving/Loading Playlists (.nicelist)
  • Completed plugin interface
  • Basic Core Video support (Tiger only) for improved playback
  • Option to resize width and height independently
  • Option to use scroll wheel for volume
  • Support for notification overlays
  • Smart window layout when opening new windows
  • Fixes for interface bugs
  • Can associate WMF and ASF files with NicePlayer
  • Button in title bar for showing and hiding playlist
  • AppleScript support for enter full screen on screen x for multiple monitors

NicePlayer 0.91 by Jay

Lot’s of changes in NicePlayer 0.91

Version 0.91 (v251) • AppleScript Support • Faster Application Startup • Better DVD playback support • Context menus, especially useful for DVDs • New media navigation menu • Screen no longer sleeps during DVD playback • UI elements fade out and other GUI improvements • Option arrow keys do frame step • Bug Reporting website • Improved Japanese Localization • Chinese Localization

There’s also a real product information website at http://niceplayer.indyjt.com/
And we have a support website powered by trac at http://charon.laya.com/niceplayer/

So Applescript Support is probably the biggest thing in this update, and I didn’t get near all I wanted into the applescript dictionary, but I learned a lot about implementing applescript dictionaries, and hope to add more in later versions. I am still kind of wondering if the cocoa scripting classes are still second class, but maybe it’s just because apple’s documentation on implementing applescript dictionaries in cocoa is so poorly documented. I was pretty much using this very useful cocoadev page to figure out how to implement the less straight forward stuff. Anyway I hope the dictionary gets some use, and wouldn’t mind suggestions on further things to add.