This tutorial is very helpful to create a custom video camera with controls . With the help of this content you can designing your own camera GUI with flash light ,start capturing video,stop capturing video.This content also has a feature to open both front and rear camera .You can set flash light on/off, save video at your specific locations.This content has a Main Activity which send intent to open camera by Camera Activity . If you send a video capturing time variable from Main Activity to Camera Activity then camera capture a video according this time what you send .
Follow below some steps to create a custom video capturing camera.
Step-1 - Create a XML res file for Main Activity called main_activity.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:orientation="vertical" >
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="Start Video Recording" />
<TextView
android:id="@+id/timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="10dip"
android:text="dsfdsfsdf" />
<TextView
android:id="@+id/videoDurationTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="10dip"
android:textSize="25dp" />
</LinearLayout>
Step-2- Create Main Activity class which open camera using intent.
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener{
private Button openCamera;
private int requestCodeForCamera=1;
private TextView timerTextView,videoDurationTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
openCamera=(Button)findViewById(R.id.button);
openCamera.setOnClickListener(this);
timerTextView=(TextView)findViewById(R.id.timer);
videoDurationTextView=(TextView)findViewById(R.id.videoDurationTextView);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent(MainActivity.this,CameraActivity.class);
//intent.putExtra("time", 15);
//intent.putExtra("url", "/sdcard/recordingvideo.mp4");
startActivityForResult(intent, requestCodeForCamera);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if(requestCodeForCamera==requestCode){
try{
Bundle extras=data.getExtras();
if(extras!=null){
if(extras.containsKey("url")){
timerTextView.setText(extras.getString("url").toString());
}
if(extras.containsKey("videoDuration")){
timerTextView.setText(extras.getString("videoDuration").toString());
}
}else{
timerTextView.setText("not url");
}
}catch(Exception e){
}
}
}
}
Step-3 - Create a XML file to design custom video camera GUI called activity_camera.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:id="@+id/videoview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<TextView
android:id="@+id/timer_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:textSize="20dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical" >
<RelativeLayout
android:id="@+id/upper_relativelayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp" >
<Button
android:id="@+id/flash_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ic_action_flash_off" />
<Button
android:id="@+id/camera_switchbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="@drawable/ic_action_switch_camera" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/bottom_relativelayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp" >
<Button
android:id="@+id/pause_play_button"
android:layou_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ic_play_circle_outline_white_48dp"
android:visibility="invisible" />
<Button
android:id="@+id/start_video_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/ic_album_white_48dp" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
Step-4 - This is the final and very important activity class which has all camera functionalities called Camera Activity.
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
// This activity open camera and recording video
public class CameraActivity extends Activity implements OnClickListener{
private Camera myCamera;
private CameraPreview myCameraSurfaceView;
private MediaRecorder mediaRecorder;
private Button startVideoButton,cameraSwitchButton,flashButton,playPauseButton;
private TextView videoRecordingTimerTextView;
boolean recording = false;
private FrameLayout myCameraPreview = null; // this layout contains surfaceview
private boolean cameraFront = false;
private boolean isCameraFlashOn;
private boolean isVideoRecordingPause;
private int setOrientationHint;
// Defined CountDownTimer variables
private long startVideoRecordingTime=10*1000*60*10;
private CountDownTimer countDownTimer;
private long timeElapsed;
private String saveUrl="/sdcard/myvideo.mp4";
private Bundle extras=null;
private boolean isTime,isUrl;
private String videoDuration;
private Parameters p;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
intializeCameraPreview();
initid();
checkIntentExtra();
}
// Intialize camera preview first time
private void intializeCameraPreview() {
myCamera = getCameraInstance(); //Get Camera for preview
if(myCamera == null){
Toast.makeText(CameraActivity.this,"Failed to open Camera",Toast.LENGTH_LONG).show();
finish();
}
myCameraSurfaceView = new CameraPreview(this, myCamera);
myCameraPreview = (FrameLayout)findViewById(R.id.videoview);
myCameraPreview.addView(myCameraSurfaceView);
}
private void initid() {
// TODO Auto-generated method stub
startVideoButton = (Button)findViewById(R.id.start_video_button);
startVideoButton.setOnClickListener(this);
cameraSwitchButton = (Button)findViewById(R.id.camera_switchbutton);
cameraSwitchButton.setOnClickListener(this);
playPauseButton=(Button)findViewById(R.id.pause_play_button);
playPauseButton.setOnClickListener(this);
flashButton=(Button)findViewById(R.id.flash_button);
flashButton.setOnClickListener(this);
videoRecordingTimerTextView=(TextView)findViewById(R.id.timer_textview);
}
public void checkIntentExtra(){ // this function check intent has extras values or not
extras=getIntent().getExtras();
if (extras != null) {
if (extras.containsKey("time")) {
startVideoRecordingTime = (extras.getInt("time")+1)*1000;
isTime=true;
// TODO: Do something with the value of isNew.
}
if(extras.containsKey("url")){
saveUrl=extras.getString("url");
isTime=false;
isUrl=true;
Log.d("saveUrl", saveUrl);
}
}else{
Log.d("extras is null",extras+"");
isTime=false;
}
}
@Override
public void onClick(View v) {
if(v.getId()==R.id.start_video_button){
startVideoRecording();
}
if(v.getId()==R.id.camera_switchbutton){
switchCamera();
}
if(v.getId()==R.id.pause_play_button){
playPauseVideoRecording();
}
if(v.getId()==R.id.flash_button){
if(isFlashAvailable(this)){
if(isCameraFlashOn){
isCameraFlashOn=false;
flashButton.setBackgroundResource(R.drawable.ic_action_flash_off);
}else{
isCameraFlashOn=true;
flashButton.setBackgroundResource(R.drawable.ic_action_flash_on);
}
}else{
Log.d("flash not available", "flash not here");
}
}
}
// Choose camera with front and back functionaly
public void chooseCamera() {
if (cameraFront) { // if the camera preview is the front
int cameraId = findBackFacingCamera();
if (cameraId >= 0) {
// open the backFacingCamera
// set a picture callback
// refresh the preview
Log.d("findBackFacingCamera", cameraId+"");
myCamera = Camera.open(cameraId); // change switch camera icon image
myCamera.lock();
myCamera.setDisplayOrientation(90);
myCameraSurfaceView.refreshCamera(myCamera);
}
} else {
int cameraId = findFrontFacingCamera();
if (cameraId >= 0) {
// open the backFacingCamera
// set a picture callback
// refresh the preview
Log.d("findFrontFacingCamera", cameraId+"");
myCamera = Camera.open(cameraId); // change switch camera icon image
myCamera.lock();
myCamera.setDisplayOrientation(90);
myCameraSurfaceView.refreshCamera(myCamera);
}
}
}
// return cameraPreview Id 1 to open front camera
private int findFrontFacingCamera() {
//releaseCamera();
int cameraId = -1;
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
cameraId = i;
setOrientationHint=270;
cameraFront = true;
break;
}
}
return cameraId;
}
// return cameraPreview Id 0 to open back camera
private int findBackFacingCamera() {
//releaseCamera();
//releaseMediaRecorder();
int cameraId = -1;
// Search for the back facing camera
int numberOfCameras = Camera.getNumberOfCameras(); // get the number of cameras
// for every camera check
for (int i = 0; i < numberOfCameras; i++) {
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == CameraInfo.CAMERA_FACING_BACK) {
cameraId = i;
setOrientationHint=90;
cameraFront = false;
break;
}
}
return cameraId;
}
// return camera instance when activity open first time
private Camera getCameraInstance(){
// TODO Auto-generated method stub
releaseCamera();
releaseMediaRecorder();
Camera c = null;
try {
c =Camera.open(findBackFacingCamera());
c.setDisplayOrientation(90);
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
@SuppressLint("InlinedApi")
private boolean prepareMediaRecorder(){
mediaRecorder = new MediaRecorder();
try{
if(isCameraFlashOn){ // camera flash on off
setFlashOnOff(true);
}
myCamera.unlock();
}catch(Exception e){
//e.printStackTrace();
}
mediaRecorder.setCamera(myCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(CamcorderProfile.get(1, CamcorderProfile.QUALITY_HIGH));
mediaRecorder.setOutputFile(saveUrl);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder().getSurface());
mediaRecorder.setOrientationHint(setOrientationHint);
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
releaseMediaRecorder();
return false;
} catch (IOException e) {
e.printStackTrace();
releaseMediaRecorder();
return false;
}
return true;
}
// Setup video recording timer function and start timer
public void startVideoRecordingTimer(){
setupCountDown();
countDownTimer.start();
}
// switch camera to front or rear
private void switchCamera() {
if (!recording) {
int camerasNumber = Camera.getNumberOfCameras();
if (camerasNumber > 1) {
releaseCamera(); // release the old camera instance
chooseCamera(); // switch camera, from the front and the back and vice versa
} else {
Log.d("camerasNumber is not greateer than one", "1");
}
}
}
// start video recording function
private void startVideoRecording() {
// TODO Auto-generated method stub
// check if video recording already started
if(recording){
stopVideoRecording(); // stop recording and release camera
stopRecordingTimer();
}else{
Log.d("preparedMediaRecorder", prepareMediaRecorder()+"");
if(!prepareMediaRecorder()){
Toast.makeText(CameraActivity.this,
"Fail in prepareMediaRecorder()!\n - Ended -",
Toast.LENGTH_LONG).show();
finish();
}
startVideoRecordingTimer();
//Invisible view after start recording
cameraSwitchButton.setVisibility(View.INVISIBLE);
flashButton.setVisibility(View.INVISIBLE);
mediaRecorder.start();
recording = true;
}
}
/* this function is not in working now
* use to pause or resume video when recording
*/
private void playPauseVideoRecording() {
if(isVideoRecordingPause){
isVideoRecordingPause=false;
playPauseButton.setBackgroundResource(R.drawable.ic_play_circle_outline_white_48dp);
mediaRecorder.reset();
stopRecordingTimer();
}else{
isVideoRecordingPause=true;
playPauseButton.setBackgroundResource(R.drawable.ic_pause_circle_outline_white_48dp);
}
}
// stop recording timer when stop video record
private void stopRecordingTimer(){
countDownTimer.cancel();
}
// set camera flash on off
private void setFlashOnOff(boolean flash){
if(flash){
Parameters params = myCamera.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_TORCH);
myCamera.setParameters(params);
}else{
Parameters params = myCamera.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_OFF);
myCamera.setParameters(params);
}
}
// stop video recording
public void stopVideoRecording(){
//Invisible view after start recording
try{
cameraSwitchButton.setVisibility(View.VISIBLE);
flashButton.setVisibility(View.VISIBLE);
mediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object\
if(isFlashAvailable(this))
setFlashOnOff(false);
releaseCamera();
recording = false;
stopRecordingTimer();
/*
* intent use here to send back response to activity that start this current activity
*/
Intent returnIntent = new Intent();
// check that video save url coming from previous activity or not
if(!isUrl){
returnIntent.putExtra("url", saveUrl);
}
returnIntent.putExtra("videoDuration", videoDuration);
setResult(1, returnIntent);
finish();
}catch(Exception e){
e.printStackTrace();
}
}
@Override
protected void onPause() {
super.onPause();
/* this code check video recording continue or not when current activity goes in pause state
*
*/
if(recording){
Log.d("onPause", "OK");
stopVideoRecording();
}else{
Log.d("finishActivity", "ok");
finish();
}
//myCameraSurfaceView.onPauseMySurfaceView();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
// myCameraSurfaceView.onResumeMySurfaceView();
}
private void releaseMediaRecorder(){
if (mediaRecorder != null) {
mediaRecorder.reset(); // clear recorder configuration
mediaRecorder.release(); // release the recorder object
mediaRecorder = null;
myCamera.lock(); // lock camera for later use
}
}
private void releaseCamera(){
if (myCamera != null){
myCamera.release(); // release the camera for other applications
myCamera = null;
}
}
@Override
public void onBackPressed()
{
if(recording){
stopVideoRecording();
}else{
releaseCamera();
finish();
}
Log.d("onBackPressed","yes");
// finish();
}
// function setup countdown timer for video recording
private void setupCountDown() {
Log.d("startVideoRecordingTime", startVideoRecordingTime+"");
countDownTimer = new CountDownTimer(startVideoRecordingTime, 1000) {
public void onTick(long millisUntilFinished) {
// check that video recording time coming previous activity or not
if(!isTime){
// if time not coming from previous activity then time will increase
timeElapsed = startVideoRecordingTime - millisUntilFinished;
// Get video duration
videoDuration=String.format("%d :%d ",
TimeUnit.MILLISECONDS.toMinutes(timeElapsed),
TimeUnit.MILLISECONDS.toSeconds(timeElapsed) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeElapsed)));
showRecordingTime(timeElapsed);
}else{
timeElapsed = startVideoRecordingTime - millisUntilFinished;
// Get video duration
videoDuration=String.format("%d :%d ",
TimeUnit.MILLISECONDS.toMinutes(timeElapsed),
TimeUnit.MILLISECONDS.toSeconds(timeElapsed) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeElapsed)));
showRecordingTime(millisUntilFinished);
}
}
public void onFinish() {
Log.d("finish", "yes");
stopVideoRecording();
}
};
}
@SuppressLint("InlinedApi")
public void showRecordingTime(long time){
Log.d("startVideoRecordingTime", startVideoRecordingTime+"");
videoRecordingTimerTextView.setText(""+String.format("%d :%d ",
TimeUnit.MILLISECONDS.toMinutes(time),
TimeUnit.MILLISECONDS.toSeconds(time) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time))));
}
/*
* @return true if a flash is available, false if not
*/
public static boolean isFlashAvailable(Context context) {
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
}
}
Step-5- Defined manifest.xml file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.videorecorder"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="21" />
<!-- Uses Permissions -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Uses hardware flash light -->
<uses-feature android:name="android.hardware.camera" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.videorecorder.MainActivity"
android:configChanges="keyboardHidden"
android:label="@string/title_activity_main"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Camera Activity -->
<activity
android:name="com.example.videorecorder.CameraActivity"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.NoTitleBar" />
</application>
</manifest>
2 Comment(s)