Monday 29 June 2015

Video Recording using surfaceview

1) Create class MainActivity.java
package com.example.videorecording;

import java.io.File;
import java.io.IOException;
import java.util.Date;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.MediaController;
import android.widget.Toast;
import android.widget.VideoView;

public class MainActivity extends Activity implements Callback, OnClickListener {
private VideoView videoView = null;
private MediaController mc = null;
private SurfaceHolder surfaceHolder;
private SurfaceView surfaceView;
public MediaRecorder mediaRecorder = new MediaRecorder();
private Camera mCamera;
private Button btnStart;

@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

surfaceView = (SurfaceView) findViewById(R.id.surface_camera);
mCamera = Camera.open();
// mCamera.setDisplayOrientation(90);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
btnStart = (Button) findViewById(R.id.btnStart);
btnStart.setOnClickListener(this);
}

@SuppressLint("NewApi")
protected void startRecording() throws IOException {
if (mCamera == null)
mCamera = Camera.open();

File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + "/WWF/WWF Videos");
if (!dir.exists()) {
dir.mkdirs();
}

Date date = new Date();
String fileName =  "/rec" + date.toString().replace(" ", "_").replace(":", "_") + ".mp4";
File file = new File(dir, fileName);

mediaRecorder = new MediaRecorder();
mCamera.lock();
mCamera.unlock();
// Please maintain sequence of following code.
// If you change sequence it will not work.
mediaRecorder.setCamera(mCamera);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
mediaRecorder.setOutputFile(dir + fileName);
mediaRecorder.setOrientationHint(90);
mediaRecorder.prepare();
mediaRecorder.start();
refreshGallery(file);
}

private void refreshGallery(File file) {
Intent mediaScanIntent = new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScanIntent.setData(Uri.fromFile(file));
sendBroadcast(mediaScanIntent);
}

protected void stopRecording() {
if (mediaRecorder != null) {
mediaRecorder.stop();
mediaRecorder.release();
mCamera.release();
// mCamera.lock();
}
}

private void releaseMediaRecorder() {

if (mediaRecorder != null) {
mediaRecorder.reset(); // clear recorder configuration
mediaRecorder.release(); // release the recorder object
}
}

private void releaseCamera() {
if (mCamera != null) {
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {

}

@Override
public void surfaceCreated(SurfaceHolder holder) {
if (mCamera != null) {
Parameters params = mCamera.getParameters();
mCamera.setParameters(params);
mCamera.setDisplayOrientation(90);
Log.i("Surface", "Created");
} else {
Toast.makeText(getApplicationContext(), "Camera not available!",
Toast.LENGTH_LONG).show();
finish();
}
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStart:
if (btnStart.getText().toString().equalsIgnoreCase("Start")) {
btnStart.setText("Stop");
try {
startRecording();
} catch (IOException e) {
String message = e.getMessage();
Log.i(null, "Problem " + message);
mediaRecorder.release();
e.printStackTrace();
}
} else {
btnStart.setText("Start");
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
}
break;

default:
break;
}
}
}

2) create xml activity_main.xml
=======================
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.videorecording.MainActivity" >

    <SurfaceView
        android:id="@+id/surface_camera"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </SurfaceView>
    <Button 
        android:id="@+id/btnStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerInParent="true"
        android:text="Start"/>

</RelativeLayout>

3) Manifest.java
 ===========
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.videorecording"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

5 comments:

  1. Outstanding blog post and this tutorial will certainly be helpful. I use Total Recall call recorder app for my android phone which is working great and has turned out to be useful for recording two way calls with no beep noise and fabulous sound recording

    ReplyDelete
  2. How can we add views to surfaceview?

    ReplyDelete
  3. hi this is creating video stretch issues ? How to resolve this ?

    ReplyDelete
  4. Hi for me recording is not working,file is saving with duration 0:0 and not opening video file.

    ReplyDelete
  5. how can i set front camera view instead of back

    ReplyDelete