Transcript video

Cosc 5/4730
Android media Part 2:
Pictures and Video
Emulators and Samsung
• The emulators all have problems, much of the
following code has been tested on the actual
phones
• Video playback code works, but the video may
not always display in the emulators
• android
– Video/picture capture does not work as documented.
• Samsung hardware!
– Some Samsung devices have many problems.
Something about their hardware… search for the
video and samsung for some possible answers.
Android android.media
PLAY MEDIA
Supported formats
• In general Android’s support is consistent with other
mobile phones.
• It supports the 3GP (.3gp) and MPEG-4 (.mp4) file
formats.
– 3GP is a video standard derived from MPEG-4 specifically
for use by mobile devices.
• As far as codecs go, Android supports H.263, a codec
designed for low-latency and low-bitrate
videoconferencing applications. H.263 video is
supported in either MPEG-4 (.mp4) or 3GP (.3gp) files.
Android also supports MPEG-4 Simple Profile in 3GP
files (.3gp) as well as H.264.
Android
• First method
– For greater flexibility you will need to use the mediaPlayer
and a surfaceView
• MediaPlayer like the audio and use a surfaceView to display the
video.
• There are examples in the API demo, plus several of the books.
• The second method uses a VideoView to display.
– The VideoView uses a MediaController to start and stop
and provide functions to control the video play back.
– With a MediaPlayer like the audio. prepare(), then start()
– This is one I’ll cover in this lecture.
VideoView
• VideoView is a View that has video playback
capabilities and can be used directly in a
layout.
• We can then add controls (play, pause,
forward, back, etc) with the MediaController.
ViewView example
• Get the ViewView out of the layout
vv = (VideoView) this.findViewById(
R.id.VideoView);
• Setup where the file to play is
Uri videoUri =
Uri.parse(Environment.getExternalStorageDirectory
().getPath() + "/example.mp4");
vv.setVideoURI(videoUri);
• play the video
vv.start();
Adding media controllers.
• Very simple
vv = (VideoView) this.findViewById(R.id.VideoView);
vv.setMediaController(new MediaController(this));
• Now media controls will show up on the
screen.
Using native media player
• Call for an Intent and send it.
Uri data = Uri.parse(VideoFile);
intent.setDataAndType(data, "video/mp4");
startActivity(intent);
• Remember, your app is now in the
background.
Example code
• The VideoPlay example code
– This will play a video from the internet.
– If you can uncomment the code to have it play the
video from the sdcard, but you will need to copy
the file to the sdcard.
DISPLAYING A PICTURE
Displaying Pictures
– See code already covered to how display pictures.
• ImageView for example…
Android
TAKING A PICTURE
What to use
• Android packages
• import android.hardware.CameraDevice;
• import android.hardware.CameraDevice.CaptureParams;
– Permissions and features
• <uses-permission
android:name="android.permission.CAMERA" />
• This too, if you change the how the camera is functioning.
• <uses-feature android:name="android.hardware.camera" />
• <uses-feature
android:name="android.hardware.camera.autofocus" />
Taking a picture
• In brief
– CameraDevice cameraDevice =
CameraDevice.open()
– To preview you need a surfaceHolder then use
setPreviewDisplay(surfaceHolder) and
cameraDevice.startPreview()
– Finally use the takePicture(…) to get the picture
– release() and close() the CameraDevice to release
it.
“View Finder”
• The view finder is implemented via a SurfaceHolder and SurfaceView
– In the layout, the a surfaceView is used.
• Example:
public class PicCapture extends Activity implements OnClickListener,
SurfaceHolder.Callback, Camera.PictureCallback {
…
cameraView = (SurfaceView) this.findViewById(R.id.CameraView);
surfaceHolder = cameraView.getHolder();
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceHolder.addCallback(this);
• To finally take the picture we need all this too.
cameraView.setFocusable(true);
cameraView.setFocusableInTouchMode(true);
cameraView.setClickable(true);
cameraView.setOnClickListener(this);
“View Finder” (2)
• The code to implement the surfaceHolder can be very simple.
• When created open the camera and set the display
surfaceCreated() {
camera = Camera.open();
try { camera.setPreviewDisplay(holder);
catch (IOException exception) {
camera.release(); }
}
• Once it’s ready, start the preview
surfaceChanged() {
camera.startPreview();
}
“View Finder” (3)
• When we are done
surfaceDestroyed() {
camera.stopPreview();
camera.release();
}
Get the Picture
• Using the Camera.PictureCallBack we implement,
we can get the data for the picture and decide
what to do it with it.
• In its simplest form, which doesn’t nothing with
the picture
public void onPictureTaken(byte[] data, Camera
camera) {
• byte[] data is the picture that was taken
• this just restarts the preview.
camera.startPreview();
}
Get the Picture (2)
• To take the picture we use the
• camera.takePicture method in the onClick method for the SurfaceView
public void onClick(View v) {
camera.takePicture(null, null, null, this);
}
• takePicture (Camera.ShutterCallback shutter, Camera.PictureCallback raw,
Camera.PictureCallback postview , Camera.PictureCallback jpeg)
• We only need the last to get the picture and it show on the previous slide.
– shutter
• the callback for image capture moment, or null
– raw
•
the callback for raw (uncompressed) image data, or null
– postview
• the callback with postview image data, may be null
– jpeg
• the callback for JPEG image data, or null
Via an Intent.
• You can also have the default “camera app”
take the picture and return it to your app.
• Also doesn’t require any permissions.
Intent intent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_C
APTURE);
startActivityForResult(intent, myID);
• Picture is returned in onActivityResult
Via an Intent (2)
protected void onActivityResult(int requestCode, int
resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode,
data);
//get the picture out of the intent and display in an
image view.
Bitmap bp = (Bitmap)
data.getExtras().get("data");
iv.setImageBitmap(bp);
}
Android Example Code
• A note for the example code PicCapture
– The example code will put any pictures taken into
the “Camera roll” and can be seen with the gallery
app.
– Remember it uses touch to take the picture.
• PicCapture2 uses a button and separates the
code a little better.
• PicCapture3 uses an intent to take the picture.
Android android.media
RECORDING VIDEO
First…
• Most examples and code on the web and from
the android books, DO NOT work.
– lots of subtle errors
• debugging is made more difficult, because
– the camera throws errors
• CameraInput Recording is not ready … frame dropped.
– the AudioFlinger shows constant buffer overflow
warnings.
– And this is when the app is working correctly.
Uses a surfaceView
• Like a taking a picture, we need a view finder
which uses a surfaceView.
• Call for the MediaRecorder
• and setup the encoding.
– both audio and video.
Example SurfaceView
• in onCreate
recorder = new MediaRecorder();
//setup recorder settings Next Slide
SurfaceView cameraView = (SurfaceView) findViewById(R.id.CameraView);
holder = cameraView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
• implemented methods.
public void surfaceCreated(SurfaceHolder holder) {
recorder.setPreviewDisplay(holder.getSurface());
recorder.prepare();
}
Example SurfaceView (2)
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
if (recording) {
recorder.stop();
recording = false;
}
recorder.release();
finish();
}
Recorder Settings
• We need to set the sources for audio and video
recorder.setAudioSource( MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(
MediaRecorder.VideoSource.DEFAULT);
– MediaRecorder.VideoSource.CAMERA should work as well.
• Now we need to setup encoders.
– In android 2.2 we can use profiles instead of setting everything
manually.
– CamcorderProfile.QUALITY_HIGH or QUALITY_LOW
CamcorderProfile cpHigh =
CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
recorder.setProfile(cpHigh);
• And set the output location
recorder.setOutputFile("/sdcard/videocapture_example.mp4");
Recorder Settings (2)
• Manual settings could look like this:
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
• QUALITY_HIGH settings are MP4 file
• QUALITY_LOW settings are 3gp file
• The manual list is very long, see the android doc’s
or Apress - Pro Android Media Developing
Graphics, Music, Video, and Rich Media Apps for
Smartphones and Tablets, Chapter 11 for a full
list of settings.
Recording
• To record
recorder.start();
• To stop
recorder.stop();
– The file should be there at this point.
• Remember when you are done
recorder.release();
Example code
• The example code
– need an Sdcard to test code and the file will be located
/sdcard/videocapture_example.mp4
• The code uses an extended surfaceView call
captureSurface, instead of just a surfaceView
– The code is all there, but rearranged from the slides.
• Honesty, the code just didn’t work without an extended
SurfaceView
• The code starts up with the viewfinder, touch the
screen to start recording, again to stop recording. It
will then launch the native media player to replay the
video.
References
• Android
– http://developer.android.com/intl/zhCN/guide/topics/media/index.html
– http://www.brighthub.com/mobile/googleandroid/articles/43414.aspx (a difficult example to
follow and it’s for 1.6)
– Apress - Pro Android Media Developing Graphics,
Music, Video, and Rich Media Apps for Smartphones
and Tablets
• Chapter 2 for taking pictures, chapter 9 for video playback.
– API examples, com.example.android.apis.media
Q&A