![]() So, right now the Scrobbler app keeps its queue. Again one of those things that sound very easy, but no: it’s completely impossible to read the queue from the MediaPlayer. The client had a simple request: the Scrobbler app should show the playback queue in a table, just like the native Music app does. All third party music playback apps (that use MediaPlayer) suffer from the same problem, and I don’t even want to think about the amount of time that we’ve wasted on it. It’s an extremely annoying problem that Apple should really fix, but instead it has only gotten worse with iOS6. The button state will often fix itself after that as well. And when you hit play, I first call pause, then play. Our solution is to always call play and then pause when you want to pause. Hitting it doesn’t do anything either, because music is already playing. Right now, this scenario happens all too often: music is playing, but the play / pause button is set to “play” instead of “pause”. This causes a lot of problems in our interface, as the state of play / pause buttons is dependent on the proper response from the MediaPlayer. When you ask the MediaPlayer what its play state is, you would expect an honest answer, right? Apparently Apple doesn’t think this is necessary, and so even though music is clearly playing, sometimes the system will happily tell you that it’s currently paused or stopped. This solution brought its own set of problems to solve like battery drain, but let’s get back to MediaPlayer’s problems. It’s a stupid hack, but the only way to stay alive in the background and support iTunes Match as well. In the end we solved the background problem by playing a silent audio track using AVPlayer, while playing all music using the MediaPlayer framework. Problems one and two were once again unsolved. Needless to say, this was unacceptable, and I switched back to the standard MediaPlayer framework. Until I found problem number three: AVPlayer can’t play music in the cloud, so the Scrobbler app would be useless to anyone using iTunes Match. I was really happy with the result, it did exactly what I needed it to do: with minor changes in my app, I now had solved my 2 problems. ![]() Sounds good! So I created GVMusicPlayerController, “the power of AVPlayer with the simplicity of MPMusicPlayerController”, because while AVPlayer will let your app be alive in the background, it doesn’t offer the MediaPlayer features like queries, queues, shuffling, repeat modes and all that good stuff. Meaning, we can scrobble while in the background. Your app is then the one doing the actual playback so the correct icon will be displayed, plus you’re alive in the background and thus notifications will be received. My proposed solution was to switch to AVPlayer for music playback. So, we had 2 problems to solve: we need notifications in the background, and the client wants to see his icon as the app that’s playing music. Problem 3: AVPlayer can’t play iTunes Match content in the cloud And when they kill the Music app, of course the music stops, even though in their mind they’re using Scrobbler to play their tracks. It’s a small problem, until we discovered that some people are obsessive about killing apps that they’re not using via the multitasking bar. That means that the Music app is visible in the iOS multitasking bar, and its icon will be displayed as the app that’s playing music, not Scrobbler’s icon. We’re using the MediaPlayer framework to play back whatever track you select in the app, and quickly found a problem: the native Music app is actually doing the playback, not some background API that’s invisible to the user. Problem 2: music is played back via the native Music app As soon as the screen automatically locks or you open another app, your app won’t get the notifications, and thus you can’t scrobble. Problem: this only works when the app is running in the foreground. The basics are really simple: the app subscribes to the NowPlayingItemDidChangeNotification notification, and on every track change you get a callback and you can do whatever it is you need to: in our case sending the scrobble to the Last.fm servers. This has to be extremely reliable, and should preferably work in realtime, even when the app is in the background. The number one feature of the Scrobbler is of course that it scrobbles, which means sending the track you’re playing to your Last.fm profile. Problem 1: notifications in the background Note: when talking about MediaPlayer, I am mostly talking about. ![]() After all, it’s basically a couple of lists of artists, albums and tracks, and all actual music playback will be done using the MediaPlayer framework. When I started to work on Last.fm’s Scrobbler for iOS, I though it would be quite an easy app to create.
0 Comments
Leave a Reply. |