Friday, October 22, 2010

iPad External Screen Mirroring

At last week's Melbourne CocoaHeads meeting I did a presentation and demo of Locayta Search Mobile. What was cool about it (besides the content of course!) was that I did the whole presentation – including live demos – from the iPad, using the external VGA adapter. iPad's Keynote works well with the VGA adapter (besides a few niggles) as you would expect. However, there's no automatic mirroring of standard apps to the external display like there is on the Mac which makes live demoing a little more tricky.

So how did I perform live iPad app demos on the projector? Well, I didn't jailbreak to run background screen mirroring; and I didn't spend ages customising the demo apps to draw their UI on both the iPad and external displays (both of which are possible options).

I fortunately found a little hack on Google Code called iphoneos-screen-mirroring.  It simply provides a UIApplication category that gives you a single method to call to enable mirroring of the iPad display to the external display.  The minimum amount of code you'd need to add to your app delegate is:


#import "UIApplication+ScreenMirroring.h"

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    /* ... your app set up ... */
    // Start screen mirroring to Video Out (if connected)
    [[UIApplication sharedApplication]
      setupScreenMirroringWithFramesPerSecond:5];
}

The screen mirroring hack has no effect until an external adapter is plugged in to the iPad. When an external display is connected it kicks off a loop that continuously snapshots the main iPad display and copies the contents to the external display.  The mirroring frame rate can be customised when setting it up (like in the above example) and the reason to lower the frame rate is because the snapshotting kills the iPad performance quite a bit.  Not enough to prevent demoing of apps that don't refresh the display too much, but animations and scrolling suffer quite a bit.

For my case the hack worked well enough at 5 fps.  If you were trying to demo a 30 fps game I think you'd be a little disappointed.

Note that the mirroring hack uses UIGetScreenImage() to snapshot the main screen and so is not App Store "safe".

A similar project, robterrell's TVOutManager, claims to provide an App Store friendly technique (with certain caveats).  However, I found the performance to be slightly worse with that one and I wasn't planning on submitting the mirroring code to the App Store so I stuck with iphoneos-screen-mirroring.

4 comments:

  1. I am using the screen mirroring in an application and it works great except for one issue. When I hook up an iPad to to screen mirror the screen I am connected to only displays the top right corner of the iPad screen. Is there a simple solution to this or will this require modifying the dimensions of the window that is displayed on the connected screen when the device is an iPad?

    ReplyDelete
  2. Dan: haven't seen that issue. You want to make sure the monitor/projector supports 1024x768. Perhaps test with a few screens to see if the problem is specific to only one.

    ReplyDelete
  3. Great post thanks, implemented exactly as described.

    For me the mirrored image is not full size on the external screen. Is this easily altered or is it just that the iPad image is what it is and won't fill the external screen?

    Thanks again

    ReplyDelete
  4. Colin: the mirrored image didn't fill the screen for me either. It wasn't a problem on the large projector we used, so I didn't bother digging for a solution. I'd suggest comparing the output of mirroring with other apps (like Keynote) that output to VGA. If other apps can fill the external display then we could look at improving iphoneos-screen-mirroring.

    ReplyDelete