Apr 20 2008

Forgetting Sarah Marshall …. Forget it

Categories: Movies

So, after a long hiatus Stacy and myself ventured out to see a movie yesterday. We figured we’d see Forgetting Sarah Marshall as it’s got some people behind it that we like.

Oh boy, were we disappointed. This movie tries too hard. It’s out to shock in places which just don’t fit. It can’t figure out which character you should have sympathy for. The writing is bad, which means I couldn’t tell if the acting was bad or if it was just the writing?

All in all. Skip this movie. Well, unless you want to see Jason Segal’s wang.


Apr 19 2008

Cocoa is hot

Categories: Programming
Tags:

I was playing with Cocoa a bit more today, looking to parse and display information from the Apple Trailers feed. This involved a few things, parsing the XML, loading the images and playing the video. Let me just say, Cocoa makes this stupidly easy.

Pulling down the XML feed was a simple matter using the NSXMLDocument object. I made one extension from a mactech article here which was to add the childNamed: method. Using this it’s really easy to pull the nodes out of the XML tree and build my objects. I don’t have to deal with the actual parsing and storing string values as the nodes are processed.

With that out of the way we move onto the image loading. If I tried to load up all the images at the parsing of the document the application loading would be too slow (trust me, I did this originally to make sure everything worked). After a bit of poking this is also trivial to deal with in Cocoa. You can create a NSImage with a reference to a URL using initByReferencingURL: which will lazy load the image. In other words, only load the image when there is an attempt to draw it. This works nicely with the IKImageBrowserView as, I believe, it only loads images for what’s on screen. (If you didn’t want to lazy load you could use initWithContentsOfURL: which will load the image immediately.)

Displaying the images is trivial using the IKImageBrowserView as seen in my previous MyTube image wall article.

The last bit was displaying the movie. Again, this was pretty simple. I just added a QTMovieView to my application then it’s just a matter of loading the movie using the QTMovie movieWithURL:error: method. This will load the movie from the given URL. I can then set the movie into my view and play it. I can also inform the movie view to maintain the aspect ratio of the movie by calling setPreserveAspectRation: which is quite nice.

So, all in all, I must say, the more I play with Cocoa the more it seems they’ve wrapped a lot of the tedious work up into a nice package for you. I wonder at what point the bubble is going to burst for me?


Apr 18 2008

MyTube, searching for fun and profit

Categories: Programming
Tags: ,

On to our next installment of the MyTube saga. This time I’m taking a look at adding query capabilities to the application. The queries will run against all the videos but it should be pretty simple to update to make the queries run against the category selector as well. I’ll mention this when we get there.

Before I started into the query stuff I cleaned up a few of the loose ends that have started to dangle since the start of this series. The first one was my lame WebView bug. If you’ll remember in imageBrowser:cellWasDoubleClickedAtIndex: I had a [web reload]; call in there. You’ll want to remove that. What I ended up doing was setting the new video then reloading the old one. This was the problem where it wasn’t always showing the correct video.

The other change I made was to cleanup the init method of MyTubeIKBrowserItem. I updated the function to have a the initVideo:image: signature. A bit cleaner and simpler then before. When I need the image ID or title I just grab it from the video object with [[video title] stringValue].

Those were the main, minor, changes I made so let’s get this party started. First off add IBOutlet NSTextField *search_box; to our MyTubeAppController interface. We’ll be using this to get the search value entered into the interface.

Now, double click on MainMenu.nib to start Interface Builder. From the Views & Cells section of the Library drag an NSTextField to the application window. With the text field selected open up the Inspector (apple-i). On the Information pane (apple-1) change the Action to Send on Enter Only. This way our backend code will only be called when the user hits enter. (Don’t worry, we’re also going to work if they press the Get Videos button). Oh, and that was the other change I made, I renamed the button to Get Videos.

With the text field still selected go to the Attributes pane (apple-5) of the Inspector. In the Sent Actions section we want to grab the circle beside the selector entry. We’ll then drag the mouse to the My Tube object in the control window. When we release the mouse we’ll select grab: in the window that pops up. This hooks the text field up so when the user hits enter it will call our grab method.

Now, in the control window right click on the My Tube object and drag the circle beside search_box to our new text field. We can now save and close Interface Builder.

All of our code changes will be in the grab: method. We’ll be re-using the same selectors to display the images as the combo box feed methods use.

- (IBAction)grab:(id)sender
{
    GDataServiceGoogleYouTube *service = [self youTubeService];
    GDataServiceTicket *ticket;

    NSString *searchString = [search_box stringValue];
    if ((searchString != nil) && ([searchString length] > 0))
    {
        NSURL *feedURL = [GDataServiceGoogleYouTube youTubeURLForFeedID:nil];
        GDataQueryYouTube *query = [GDataQueryYouTube youTubeQueryWithFeedURL:feedURL];
        [query setVideoQuery:searchString];

        ticket = [service fetchYouTubeQuery:query
                                   delegate:self
                          didFinishSelector:@selector(entryListFetchTicket:finishedWithFeed:)
                            didFailSelector:@selector(entryListFetchTicket:failedWithError:)];
    }
    else
    {
        NSString *feedName = [[feed_type selectedItem] title];
        feedName = [feedName lowercaseString];
        feedName = [feedName stringByReplacingOccurrencesOfString:@" " withString:@"_"];

        NSURL *feedURL = [GDataServiceGoogleYouTube youTubeURLForFeedID:feedName];
        ticket = [service fetchYouTubeFeedWithURL:feedURL
                                         delegate:self
                                didFinishSelector:@selector(entryListFetchTicket:finishedWithFeed:)
                                  didFailSelector:@selector(entryListFetchTicket:failedWithError:)];
    }

    [imageList removeAllObjects];
}

The else section of the if statement is the same code as our previous examples. It will be used if there is no value in the search box and just retrieves the entries for a given video feed.

The interesting bit is the if itself. So, what are we doing. First we grab the string value of our search box and if it isn’t blank we’ll do a search query. The query itself is similar to the code we use to retrieve the feeds.

We first construct the URL that we want to query. In this case you’ll notice I’m passing nil to the [GDataServiceGoogleYouTube youTubeURLForFeedID:nil] call. Passing in nil will give me the general video feed instead of a specialized feed. This is also where we could put in a feed name to search the specific feed instead of all videos.

Now that we’ve got our query URL we create a GDataQueryYouTube object. This will contain all of our query information. I then use the setVideoQuery method to pass in the query string. There are a bunch of other query options that can be used to limit date ranges, allow racy videos and other things. Take a look at the query header to see the full set of methods. This will, I believe, return a maximum of 999 videos.

With the query constructed we then use fetchYouTubeQuery which is very similar to the fetchYouTubeFeedWithURL function we were using earlier.

That’s it. You should be able to run MyTube and query videos from YouTube.

You can grab the complete list of source code for MyTube at MyTube 0.4.


Apr 18 2008

The anger that is Lost Odyssey

Categories: Video Games

So, I’ve been playing Lost Odyssey on and off for a few weeks. The game is pretty good. There are technical glitches in it but nothing like Mass Effect where they just stopped me from playing.

But, and this is a big but, it breaks a few of the cardinal rules about RPG games. These make it quite hard to keep playing.

Rule #1
I shouldn’t have to watch an hour of cut scenes. Before you ask, a cut scene, then a 2 minute interlude where you play but you can only do specific actions that advance the cut scene into the next cut scene all qualifies as one big cut scene. I played for a hour and a half yesterday but I think I put in 20 minutes of actual play time.

Rule #2
Don’t put in stupid little mini quests that have no real benefit for the overall story but pad out the game length. Case in point, during that 20 minutes I played yesterday about 15 of that was doing two stupid little mini quests. The sad thing is, the quests were almost identical. Go pick 10 flowers, ok, now go pick up 10 pieces of wood. Ok, now stand and move your torch like these other guys 5 times.

Those are the two big rules that it’s broken so far. Interestingly, they aren’t the cause of my Lost Odyssey anger. No, that stems from me fighting the boss in the Crimson Forest. First time I get there the game crashes, disk read error. I hadn’t hit the save point yet so I redo the last 30 minutes. Second time I go in and fight the boss, it’s going well, I get to the half way point and setup my attacks then, after my attacks are set and I can’t stop them, it gives a crucial piece of information. My attacks proceed and Game Over. Ok, 3rd time I get there, just as I’m about to get to the crucial point the game glitches and zooms out forever. Apparently other people have had this same issue. Ok, 4th time I’m fighting the boss, just as I get to the crucial point the game throws up a Loading screen and sits there for (well, I gave it 20 minutes). At this point I threw in the towel and played Ridge Racer.

So, while I really, really want to like this game, it’s making it quite hard not to Frisbee the 4 disks off the balcony.


Apr 15 2008

Bitch-slapping Evil

Categories: Life, Music, Plays

So, Stacy, myself and a couple of friends went to see Evil Dead - The Musical tonight.

I must say it was fan … wait for it … wait … wait for it … tastic. It was the right mix of singing, quotes and blood to keep the audience laughing.

Deaths a bitch …. a stupid bitch

If you get a chance, go see this show. It’s just been extended in Toronto until June 14th so get your tickets. Oh, and if you don’t want to get bloody, don’t sit in the first two rows. Some of those people were pretty wet by the end of the show.


Next Page »