Perfecting Imperfection
“Oh, you’re an art major?” This question makes me panic. After the fleeting moment of pride in doing what I love, that windpipe-crushing anxiety sets in. In about two seconds, one of two things will usually happen: 1) the person will follow up with a condescending “that’s fun,” and I’ll have to attempt to legitimize my career choice, or 2) I will be pressured to draw a dragon on the spot. If I cannot produce a fire-breathing beastie upon command, I risk losing many respect points. The person will give up on me and later tell someone, “oh, yea, she’s an art major now.”
It is this panic-stricken conversation that drives many young art/illustration students—and hobbyists—into a manic pursuit of photo-realistic drawing skills. We think that in order to be respected by our peers, by our professors, by the “non-creatives,” we need to be able to produce a carbon copy of a pineapple. While skills like this are incredibly useful in any art practice, young and budding creatives often lose so much in attempting to chase down realism. When we could be developing our creative process, our imaginations, our risk-taking, we are instead painstakingly copying strands of hair.
But you know what? Photo-realism for the most part is really boring. We all know that person who can draw celebrities in stunning likeness. Their drawings are amazing at first, but it gets old really fast. If your work looks like something out of a Lee Hammond how-to-draw book, you should be very worried. Your best hope is to get a job in caricature, because very likely, your art lacks personality, voice. And in an increasingly technological world, people respond to a sense of humanity, not automaton-like reproduction. It is for this reason that I ask us all to stop screwing around with perfectionism and start experimenting with what we can tell the world in our own unique way.
by Melanie Richards
Annoyances with Android: MediaPlayer [Part 1]
For the past six months I’ve been a member of Grooveshark’s Android team. Before working on the Android project I was a Flash and Flex developer, working on the main Grooveshark web application and was moved to Android to, as I recall, help fix some of the problems with the 1.0 version of the application. Soon after joining the Android team my team member and I decided that the best way to fix 1.0 was to completely scrap it and start over. Many of the problems in the first version were because of some fundamental design decisions that did not fit well with the Android platform and to fix these problems would almost necessitate a complete rewrite either way.
Around this time others in the mobile group began planning the next versions of all the mobile applications so my teammate and I rushed to begin work on the 2.0 release of Grooveshark for Android. My primary responsibilities were with the player and its various systems–the player cache, offline cache, and other related things.
I learned Java and the Android framework at the same time and along the way encountered what I consider to be several annoyances and shortcomings with and of the Android platform. While on the whole I find both Java and Android a pleasure to work with, some things need improvement.
I initially wanted to compile a Top n list of problems but after writing the first few I found that I had too much for a single post so I’ve chosen to spread these out across multiple entries. Of any of my complaints I’m more than willing to admit to ignorance if it turns out that I’m just doing it wrong. So find fault if you can.
-
MediaPlayer doesn’t accept an InputStream
Grooveshark for Android does much more with music than just play it. We save to cache recently-played songs, pre-buffer enqueued songs, and allow users to save songs to an explicit “offline” cache for listening when they’re not connected to a high-speed data network. Two of these, saving to a recent cache and saving to an offline cache require that we do more things with an MP3 than simply play it. The Android MediaPlayer object accepts only three sources of audio data, or rather, supports only three ways to play an audio file. One can give the MediaPlayer a URL to a file, open a local file, or use a ContentProvider, which is useful if the audio data is embedded into the application’s installation package (APK).
It would seem that the first two methods, that of playing from a URL and from a file would suit the Grooveshark application’s needs well: for playing live streams we would provide a URL to the song on one of Grooveshark’s stream servers, and for playing offline cached songs we’d simply direct MediaPlayer to open a file on disk. However in both scenarios these input sources do not provide for everything we require.
In the first instance we can play from a URL without problem but once this song is played, we cannot access the downloaded data in order to save it to a recently-played cache. Doing this is necessary because if a user has a few songs enqueued, plays one, skips to the next song, then skips back to a previously listened-to song, we do not want to download this song again. Users do not expect that we’d need to download the song again, having just listened to it. When skipping back there would be a noticeable lag as the song buffered again and we’d be unnecessarily transferring data that we’ve already downloaded. Not everyone has an unlimited data plan and it seems that in the near future unlimited data plans may become unavailable anyway.
Because there’s no way to access the MediaPlayer’s data once downloaded, we could use a URL InputStream to download the file and pipe the stream both into the MediaPlayer and out to the disk. This would allow us to both play the song and save it for later use. But because MediaPlayer does not accept an InputStream, this cannot be done. The only thing you can do with a URL is to play it.
In the other instance, that of saving a file to disk for offline playback, we could download the file then pass a FileDescriptor to the MediaPlayer. MediaPlayer does allow for this. However we need to encrypt the file because we wouldn’t want users to simply be able to mount their phones on their computer and copy their offline songs elsewhere. If MediaPlayer accepted an InputStream, we could wrap the File’s InputStream in a FilterInputStream which would decrypt the file as it is played. But again we cannot do this. Arguably we could first decrypt the file to a temporary file, then play this file, but this would make available an unencrypted MP3 for a time and on older phones would produce a noticeable lag as the file was decrypted and written-out to disk before playback could begin.
Others have found this MediaPlayer deficiency to be a problem and a bug was filed with a supposed fix. InputStreams can now be played with the new AudioTrack object first made available in Android 1.5, but AudioTrack can only play raw PCM data, not an MP3 source, and as far as I can tell, to play an MP3 using AudioTrack the MP3 would need to be decoded in software as no hooks to the underlying MP3 hardware is provided (if there even is any, I really don’t know).
A proposed solution to this shortcoming is to run a local HTTP server which can manipulate the incoming and outgoing data in any way it likes. Ultimately this is what I ended up implementing. The application runs a thread which downloads a song, encrypts it as it writes it out to disk, and passes it along to the MediaPlayer object, sending the necessary HTTP headers as it connects to localhost. A stupid fix but it works.
-
There’s a major bug in OpenCORE
OpenCORE is the underlying media framework on Android. It’s what the MediaPlayer and other objects use to play audio and video data. Like other parts of the Android API it ships with the phone and save firmware upgrades and patches from Google (assuming Google sends patches over-the-air, which I don’t even know if they do, and they probably do not), what comes on the phone is what you get.
Unfortunately there’s a major bug in OpenCORE that prevents high-bitrate files from playing.
The MediaPlayer object has several states that it enters into and leaves when it is directed to play audio data. When you provide a data source to the MediaPlayer, it enters into its “preparing” state. At this state it buffers data until it detects that it has enough to play the data source, audio or video, uninterrupted. Or rather, that it has buffered enough data that it can start playback without playing past its buffered amount and then pausing while it fetches more data.
When trying to play certain high-bitrate MP3s, MediaPlayer never leaves its preparing state, never enters into the “prepared” state, and so playback never begins. The song will appear to buffer forever. In some instances it will buffer the song almost completely but it never believes it has enough data. This is a documented bug and I don’t know if there’s any way around this.
The Grooveshark “Now Playing” screen shows buffer progress and player progress and when this bug exhibits itself, to the user the application just looks broken. It’s infuriating, embarrasing, and unfortunately seemingly out of our control. This seems to affect upwards of fifty percent of high-bitrate files, but the most frustrating part is that this problem cannot be reliably reproduced for any given file. You can usually stop and start playback (by pressing pause and play) a few times and the song will eventually play. If the problem was because of how the MP3 is encoded, I could possibly manipulate the MP3 data as it comes across the wire before it is sent to the MediaPlayer, but I can’t seem to find a pattern or a trigger for this problem. So I’m stumped.
In the eleventh hour before the release of Grooveshark 2.0 for Android I added a “prefer low-bitrate files” option, defaulted to enabled, to the application’s settings. This is only a band-aid of course, but it at least diminishes the problem. Unfortunately all songs on Grooveshark aren’t yet transcoded, so the problem still manifests itself from time to time. One possible fix is to run a watcher thread that monitors bytes downloaded and MediaPlayer state, and if the file is high-bitrate and a threshold percentage of the total file is downloaded but the MediaPlayer has never entered the prepared state, to start and stop playback until it does.
More to come in part two.
by Skyler Slade
User Expectations: Flash
This little gem popped up in my inbox not to long ago. VIP users of grooveshark are able to provide feedback and get to complain or file bug reports, which I randomly check (it would be a full-time job if I answered them). Most of the time it’s either feature requests, complaints that they spent about a cup of coffee’s worth of money, or in this case telling us how awesome we are.
Here’s the guts of the email (obviously removed some content for privacy):
mood: Impressed
feedback report:
Nothing too contributary to say to be honest.Just that your product is AMAZING.
It’s literally changed my entire view that every flash application is buggy and unreliable, you guys have done an absolutely stunning job. It’s so bug-less it’s suspicious!
Keep up the great work!
So, what are we supposed to take away from this? That we’re really good at what we do. Or maybe there’s something else we can glean from this comment. Users expect flash to be “buggy and unreliable”. Let’s review some common complaints that people (including myself) have thought about flash.
It takes forever to load
Typically a lot of flash applications have these front and center. But the problem is the typical programmer makes this dead simple and almost pummels the user visually with the “holy-shit-this-is-a-loading” screen. With the user unable to even perceivably able to interact with the site, the wait is made more apparent. I think primarily the difference between flash and other web applications is that the user already gets an instant layed-out interface and they see the page loading in, therefore it feels more responsive.
Realistically that up front cost of loading things in makes the application feel more responsive later in the applications session lifetime. If you were to compare the actual loading times between flash sites and normal sites I think you might be surprised if you used a stop-watch (or firebug).
It has annoying intros, with not a lot of content
I have to agree that this is super annoying. I simply loathe sitting through a preloaded intro with no perceptible way to skip only to be taken to a sub-par website. Intros have more or less faded in time, but watching horribly animated, boring segues has weighed on peoples perception of flash. There is a certain level of taste to be considered. Let’s not blame flash for others’ poor taste. Moving on.
It’s always Glitchy / Buggy
Pretend I am told to make a desk and I am provided with all the equipment I need and then some: hammers, screwdrivers, nice oak wood, etc… The problem is I have never made a desk and not a very good carpenter, so I hack it together. The desk I make turns out ok, is functional, but not quite what I wanted, and now the varnish is chipping off.
So, instead I buy a desk from IKEA, and have to assemble it. The desk is packaged in a really cool way (I recently bought a chair from their in a stair-case package) and it takes me a couple hours because it comes with dead simple instructions.
What I’m getting at is that Flash is a great set of tools. If I’m a great carpenter (hire me) the desk is going to come out better than something I bought, because I got to make the desk I wanted to from the beginning. Heck, if I wanted to I could’ve made a matching bookcase and hutch, and with the scraps a stylish spice rack for my girlfriend. Sweet!
But, if you’re a bad carpenter, you’re going to have a horribly buggy misshapen turd. You have way more points of failure. IKEA is that package (e.g. wordpress) people get when they want a quick fix, and not a lot of customization. There are fewer ways to screw it up.
So, maybe what we need to take away from this is that programmers and not their tools which are “buggy and unreliable”.
by Joe Kelly
HTML Eats Babies and Spits Hot Fire
HTML5 is fast becoming the new hot thang that all the guys want to fuck. But, like the hot girl: she’s a raging bitch, requires a ton of maintenance, actually is just so-so in bed, and you cannot protect your investment (because she’s open, but remember she has standards). And all the boys want to have their way with her: Google is the new kid on the block, Microsoft the rich kid that wants to buy her, her best friend Mozilla has been holding her hands when time was tough, and now Apple the bad boy because he wants to prove to his gay lover that it’s really over.
I on the other hand am totally gay for flash, but that’s because when I originally wrote for the web in HTML/JS/CSS it was slowly killing my soul. I have and still consider myself pretty darn good at writing clean well-formed markup, making some custom components for jquery (I actually liked mootools for a time), and awesome at skinning sites in CSS. But, all while doing this it never for once felt like real programming. And, that’s what makes me think that this particular trio is really good at: creating sloppy, unmaintainable spaghetti code. But sometimes, that’s ok.
Heck, most of the time that’s ok. The web (initially) is supposed to be open and easy for people to get their message out there, and that’s exactly why HTML began as a dumb way to publish data. Not everyone has to make mind-blowing applications. HTML in its initial form never was about looking awesome or protecting content. So what we have now is adding patches on top of a platform never intended to be commercial and flashy.
However, on the other side are the people that want to send a message, provide a product of content, and deliver a brand or platform. It’s applications like these that defy the trend of openness and may never be able to reconcile with standards, which is what’s really funny about Apple: releasing a demo for HTML5, when it was more or less a demo for Safari.
I am not saying HTML5 and JavaScript is a bad thing; I’m saying it’s not something good for production of commercial code. If HTML5 and JavaScript is so great, then my friends shouldn’t have to bother writing applications for the iPhone or iPad in XCode (sorry Adobe), when I can have them develop for Safari.
Things about flash that make me shit rainbows:
- Compiled code
- Object oriented
- Distributed player with high market acceptance
So what is it that I want from standards? How about something better than and more “well-formed” than JavaScript; maybe even be able to send byte-code to the client, which is exactly why flash has been thriving for years: its been filling in the gap that HTML and JavaScript was never equipped to serve.
by Joe Kelly
Show Me More: Paging Array Collections
I have been working for a while recently on grooveshark’s newest feature: activity I needed to come up with a way for our array collections to only render or show a small set of what feeds actually have in them. [People stop listening to so much damn music.]
What is great about array collections is they handle all sorts of stuff for you, such as binding and updates. But what’s really great is the ability to differentiate a view from the underlying data, which allows you the use of filters for features like active searching on a collection.
So what I needed was a way to click show more and it would reveal the next set.
And extend and implement…
private var _pagesVisible:uint = 1;
[ChangeEvent("collectionChange")]
public function get pagesVisible():uint
{
return _pagesVisible;
}
public function set pagesVisible(value:uint):void
{
// allow it to be ready for soon to be populated data
if (value <= (pages+1)) {
_pagesVisible = value;
this.refresh();
}
}
private function feedFilter(item:Object):Boolean
{
var isIncluded:Boolean
= (source.indexOf(item) < PAGE_SIZE * pagesVisible);
hasMorePages = !isIncluded;
return (isIncluded);
}
by Joe Kelly
The Openness of Flash
Thanks to Steve Jobs’ Thoughts on Flash post, there’s been a whole new flurry of posts on the subject of flash vs html5, this time with some focus on the issue of openness, since Steve made such a point to bring that up.
Some people have already pointed out that Adobe has been moving Flash to be more and more open over time, including the open screen project, contributing tamarin to Mozilla, and Flex being completely open source. That’s all well and good, but people seem to be forgetting that historically, Flash had a very good reason for being closed. If one remembers back to the early days of the web, the wild west era as I do since it was such an exciting time for a young whippersnapper like me, one must only think back to what happened to Java to realize why making Flash closed was a very smart move.
For those who don’t remember or weren’t on the web back then, I’ll share what I remember which may be a bit off (that was quite a while ago now!). I’m talking about the hairy days when Netscape was revolutionizing the world and threatening to make desktop operating systems irrelevant and Microsoft was playing catch up. Java was an open and exciting platform to write once and run anywhere, promising to make proprietary operating systems even more irrelevant.
Of course, what ended up happening was that Microsoft created their own implementation of Java that not only failed to completely follow the Java spec, but added on some proprietary extensions, completely breaking the “write once, run anywhere” paradigm and helping to marginalize Java on the web, something it seems Java on the web has never fully recovered from, even though Microsoft has since settled with Sun and dropped their custom JVM after being sued.
This directly affected my personal experience with the language, when I took a Java class at the local community college while I was in high school. I wanted to write apps for the web, but even basic apps which compiled and ran fine locally would not work on IE, Netscape or both, the only solution being to spend hours fiddling and making custom versions for each browser. Needless to say, I quickly lost interest and haven’t really touched Java since I finished that class.
The atmosphere has certainly changed since those early days, and I don’t think it’s nearly as dangerous to “go open” now as it was back then, so Adobe’s choice to open up more and more of the platform now makes perfect sense, just as the decision to keep it closed until relatively recently also made sense.
by jay
Fuck the word blog. This is a journal!
“Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!”
Poop, not gonna… In today’s let’s-make-a-clever-portmanteau webosphere, let’s KISS. That way it’ll be super sexy and intimate.
Pixxid is a development journal, and will house writings of the developmental process. Instead of sifting through a series of tutorials and easy-bake lessons, we will inform via process. The stories and work presented here will emerge tangent to any of the writers (developers and designers) work through existing, creating, and completing projects.
Hooray for real-world examples!
Note: I hope to bury this post soon. Writers, please write.