Monday, April 4, 2011

CamcorderProfile: predefined camcorder profile settings for camcorder applications

How to "Start Video Recording using android.provider.MediaStore.ACTION_VIDEO_CAPTURE" have been described in last exercise. If you want to develope your own custom camcorder applications (will be introduced in coming post), you have to set many settings manually; such as
- file output format
- Video codec format
- Video bit rate in bits per second
- Video frame rate in frames per second
- Video frame width and height
- Audio codec format
- Audio bit rate in bits per second,
- Audio sample rate
- Number of audio channels for recording.

Starting with Android 2.2 (API Level 8), android.media.CamcorderProfile class provide a static method get(int quality) to retrieve the predefined camcorder profile settings, QUALITY_HIGH and QUALITY_LOW (More profiles for API Level 11). It's a exercise to list the predefined settings for each profile.

QUALITY_HIGH
QUALITY_LOW

First of all, create a /res/values/array.xml to define the profiles, it have to be matched with constCamcorderProfile[] in AndroidCamcorderProfile.java
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="profile">
<item>QUALITY_HIGH</item>
<item>QUALITY_LOW</item>
</string-array>
</resources>


AndroidCamcorderProfile.java
package com.exercise.AndroidCamcorderProfile;

import android.app.Activity;
import android.media.CamcorderProfile;
import android.media.MediaRecorder.AudioEncoder;
import android.media.MediaRecorder.OutputFormat;
import android.media.MediaRecorder.VideoEncoder;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;

public class AndroidCamcorderProfile extends Activity {

Spinner spProfileList;
TextView textProfile;

int[] constCamcorderProfile ={
CamcorderProfile.QUALITY_HIGH,
CamcorderProfile.QUALITY_LOW};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

spProfileList = (Spinner)findViewById(R.id.profilelist);
textProfile = (TextView)findViewById(R.id.profile);

ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.profile, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spProfileList.setAdapter(adapter);
spProfileList.setOnItemSelectedListener(spProfileListOnItemSelectedListener);
}

private Spinner.OnItemSelectedListener spProfileListOnItemSelectedListener
= new Spinner.OnItemSelectedListener(){

@Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
String selectedProfile = parent.getAdapter().getItem(position).toString();
textProfile.setText(selectedProfile);
CamcorderProfile camcorderProfile
= CamcorderProfile.get(constCamcorderProfile[position]);

String profileInfo;
profileInfo = selectedProfile + " : \n"
+ camcorderProfile.toString() + "\n";
profileInfo += "\n" + "audioBitRate: "
+ String.valueOf(camcorderProfile.audioBitRate)
+ "\n" + "audioChannels: "
+ String.valueOf(camcorderProfile.audioChannels)
+ "\n" + "audioCodec: "
+ getAudioCodec(camcorderProfile.audioCodec)
+ "\n" + "audioSampleRate: "
+ String.valueOf(camcorderProfile.audioSampleRate)
+ "\n" + "duration: "
+ String.valueOf(camcorderProfile.duration)
+ "\n" + "fileFormat: "
+ getFileFormat(camcorderProfile.fileFormat)
+ "\n" + "quality: "
+ String.valueOf(camcorderProfile.quality)
+ "\n" + "videoBitRate: "
+ String.valueOf(camcorderProfile.videoBitRate)
+ "\n" + "videoCodec: "
+ getVideoCodec(camcorderProfile.videoCodec)
+ "\n" + "videoFrameRate: "
+ String.valueOf(camcorderProfile.videoFrameRate)
+ "\n" + "videoFrameWidth: "
+ String.valueOf(camcorderProfile.videoFrameWidth)
+ "\n" + "videoFrameHeight: "
+ String.valueOf(camcorderProfile.videoFrameHeight);

textProfile.setText(profileInfo);
}

@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
textProfile.setText("");
}};

private String getAudioCodec(int audioCodec){
switch(audioCodec){
case AudioEncoder.AMR_NB:
return "AMR_NB";
case AudioEncoder.DEFAULT:
return "DEFAULT";
default:
return "unknown";
}
}

private String getFileFormat(int fileFormat){
switch(fileFormat){
case OutputFormat.MPEG_4:
return "MPEG_4";
case OutputFormat.RAW_AMR:
return "RAW_AMR";
case OutputFormat.THREE_GPP:
return "THREE_GPP";
case OutputFormat.DEFAULT:
return "DEFAULT";
default:
return "unknown";
}
}

private String getVideoCodec(int videoCodec){
switch(videoCodec){
case VideoEncoder.H263:
return "H263";
case VideoEncoder.H264:
return "H264";
case VideoEncoder.MPEG_4_SP:
return "MPEG_4_SP";
case VideoEncoder.DEFAULT:
return "DEFAULT";
default:
return "unknown";
}
}

}


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Spinner
android:id="@+id/profilelist"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/profile"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>


Download the files.

Related Article:
- A simple exercise of Video Capture using MediaRecorder

1 comment:

variable said...

thanks handy stuff