williamandmary – TLB Entries https://archive.tiffanyb.net Musings on cooking, travel, social media, higher ed & web technology by Tiffany Broadbent Beker Tue, 28 Jun 2016 20:58:14 +0000 en-US hourly 1 https://wordpress.org/?v=4.9.7 Full-screen video playback for Android https://archive.tiffanyb.net/2011/05/19/full-screen-video-playback-for-android/ Thu, 19 May 2011 17:55:47 +0000 http://tlbtechentries.wordpress.com/?p=5 AndroidSo you want to have video playback in your Android app? This is pretty straightforward to do once you know what you’re looking for and, aside from a few (rather tedious to figure out) small snags which I’ll go into later, can be completed relatively quickly.

What we wanted to do for W&M’s Dress the Griffin app was, when a button was pressed, open a video fullscreen, automatically play it, and when the video completes, return to the previous screen. It took me a while to find the correct Android widget to use, but once I did, things were pretty straightforward (I went off-track for a bit trying to get a MediaPlayer to work, but it turns out there’s a VideoView explicitly for doing what I was looking to accomplish).

The two main files you’ll need for a full-screen video player are a new Activity class that will create a VideoView and set it as the main content view until the video playback has completed:

package yourpkg;

import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.os.Bundle;
import android.widget.VideoView;

public class VideoPlayer extends Activity
   implements OnCompletionListener {

	private VideoView mVideoView;

	@Override
	public void onCreate(Bundle b) {
		super.onCreate(b);
		// Bring the video player to the front
		setContentView(R.layout.videoplayer);
		// Get a handle on the VideoView
		mVideoView =
			(VideoView)findViewById(R.id.surfacevideoview);
		// Load in the video file
		mVideoView.setVideoURI(
			Uri.parse("android.resource://yourpkg/raw/videoname"));
		// Handle when the video finishes playing
		mVideoView.setOnCompletionListener(this);
		// Start playing the video
		mVideoView.start();
	}

	@Override
	public void onCompletion(MediaPlayer mp) {
		// The video has finished, return from this activity
		finish();
	}
}

And a layout XML file to show your video fullscreen:

<?xml version="1.0" encoding="utf-8"?>
<!-- Create a full-screen layout
	The video I'm playing back is portrait/vertical so
	set the orientation accordingly.
-->
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

<!-- Create a full-screen VideoView -->
    <VideoView
        android:id="@+id/surfacevideoview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
    />

</LinearLayout>

Once these are set up you are pretty much ready to go, all you’ll need to do is start the video playback activity, spurred by a button press or something similar:

Intent videoPlaybackActivity =
	new Intent(v.getContext(), VideoPlayer.class);
startActivity(videoPlaybackActivity);

and you’re off.

The three main things you have to be aware of are file size, aspect ratio, and video encoding.

File Size: Try and make your video the smallest file size and lowest resolution that you can tolerate, since this will be played back on a myriad of devices with a wide range of memory limitations.

Aspect Ratio: Keep in mind your video will be letterboxed to fit the screen dimensions of each device, so make sure you can handle the smallest size and screen density that you can (depending on what devices you plan on supporting). For more about supporting multiple screen sizes the Android documentation offers a pretty nice overview.

Video Encoding: This caused me more problems than anything else. I was presented with a lot of “Sorry this video cannot be played” messages, blank screens that would immediately kick back to the main screen, or blank screens that would only play the audio and not the video on my way to finding the correct video encoding (and all of those symptoms are frequently, if not exclusively, caused by incorrect video encoding).

The Android documentation’s list of supported media formats was a good start, but even when I thought I had the correct encoding I was still having major issues with playback. Luckily a great open-source multi-platform video transcoder app called Handbrake came to the rescue. After tweaking seemingly every possible combination of controls in Handbrake I ended up back on what was essentially the “iPhone and iPod Touch” preset. So here are the video export settings for Handbrake that worked for me for video playback for Android:

  • MP4 format (so end up with a .m4v file)
  • MPEG-4 video codec (with “constant quality” setting QP 14)
  • AAC audio codec, 128 kbps

The only change from the “iPhone and iPod Touch” preset is that the video codec is changed from H.264 to MPEG-4. This tweak wasn’t really intuitive from the documentation (which made it seem like either H.264 or MPEG-4 should’ve been fine) but this is what ultimately worked for me.

Happy full-screen video playing!

]]>
Programmatically taking a screenshot of your app in iOS https://archive.tiffanyb.net/2011/04/05/programmatically-taking-a-screenshot-of-your-app-in-ios/ https://archive.tiffanyb.net/2011/04/05/programmatically-taking-a-screenshot-of-your-app-in-ios/#comments Tue, 05 Apr 2011 19:57:33 +0000 http://tlbtechentries.wordpress.com/?p=12 Dress the Griffin on the iPadFor William & Mary’s Dress the Griffin app we offer the option to save the Griffin’s current outfit as an image to the iOS device’s photo album (which can then be shared via email or various social media outlets). I had a hard time finding a place that outlined these steps clearly, so here is the rundown of what needs to be done to programmatically save a full screen screenshot of your iOS app to the user’s photo album.

/* Action taken when the "Save" button (saveAsImageButton) is pressed in the app */
- (IBAction)saveScreenshot {

   // Define the dimensions of the screenshot you want to take (the entire screen in this case)
   CGSize size =  [[UIScreen mainScreen] bounds].size;

   // Create the screenshot
   UIGraphicsBeginImageContext(size);
   // Put everything in the current view into the screenshot
   [[self.view layer] renderInContext:UIGraphicsGetCurrentContext()];
   // Save the current image context info into a UIImage
   UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
   UIGraphicsEndImageContext();

   // Save the screenshot to the device's photo album
   UIImageWriteToSavedPhotosAlbum(newImage, self,
      @selector(image:didFinishSavingWithError:contextInfo:), nil);
}

// callback for UIImageWriteToSavedPhotosAlbum
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {

   if (error) {
       // Handle if the image could not be saved to the photo album
   }
   else {
      // The save was successful and all is well
   }
}

Note: The bulk of these functions are out of Apple’s UIKit framework so check out their documentation for even more information.

]]>
https://archive.tiffanyb.net/2011/04/05/programmatically-taking-a-screenshot-of-your-app-in-ios/feed/ 9