ビデオレコーダーを作成したいのですが、これまでのところ、MediaRecorder.prepare()メソッドを正常に実行するためにパラメーターを設定する方法がわかりません。
次のメソッドを実行する
_public void start() throws IOException{
String state = Android.os.Environment.getExternalStorageState();
if(!state.equals(Environment.MEDIA_MOUNTED))
{
throw new IOException("SD card is not mounted. It is " + state + ".");
}
File directory = new File(path).getParentFile();
if(!directory.exists() && !directory.mkdirs())
{
throw new IOException("Path to file could not be created.");
}
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
recorder.setVideoFrameRate(15);
recorder.setVideoSize(176, 144);
recorder.setOutputFile(path);
recorder.prepare();
recorder.start();
this.state = VideoRecorderState.STATE_RECORDING;
}
_
行recorder.prepare().
に例外をスローします
ビデオをキャプチャできるようにパラメータを設定するにはどうすればよいですか?
機能するスニペットを次に示します。
m_recorder = new MediaRecorder();
m_recorder.setPreviewDisplay(m_BeMeSurface);
m_recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
m_recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
m_recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
m_recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
m_recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
m_recorder.setMaxDuration((int) MAX_TIME);
m_recorder.setOnInfoListener(m_BeMeSelf);
m_recorder.setVideoSize(320, 240);
m_recorder.setVideoFrameRate(15);
m_recorder.setOutputFile(m_path);
m_recorder.prepare();
m_recorder.start();
最も重要なことは表面です。あなたはそれを持っていないので、それなしでは失敗します。
よろしく
BeMeCollective
私は次のチュートリアルでこの質問に正確に答えています: http://integratingstuff.wordpress.com/2010/10/18/writing-code-that-captures-videos-on-Android/
Prepare()でコードが失敗するのは、必要なプロパティをすべて設定していないためです。たとえば、maxDurationも設定する必要があります。
同じ質問がありました。私はバックグラウンドオーディオレコーディングサービスを利用しており、バックグラウンドビデオレコーディングサービスを作成したいと考えていました。バックグラウンドビデオを実際に記録することはできませんが、既存のUIでビデオプレビューを非常に小さくすることができます。私はチュートリアルに従いました http://integratingstuff.wordpress.com/2010/10/18/writing-code-that-captures-videos-on-Android/ とサンプルのカメラプレビューデモ。しかし、最終的には http://www.apress.com/downloadable/download/sample/sample_id/39/ のサンプルコードは、tweekまで十分にシンプルでしたが、setCameraで動作するのに十分なほど完成しました。ここに私のソリューションを投稿して、おもちゃの例から、高品質の背景ビデオ録画を使用した複雑な例(必要に応じて正面カメラを使用)までの進行時間を節約します。
これは、Androidプレビューなしのビデオレコーダー(プレビューは控えめな録画LEDをシミュレートする1x1ピクセルです)のソースであり、ユーザーの注意をそらすことなくビデオを録画します。独自のUIを使用するには、単にvideo_recorder.xmlをレイアウトに変更します(必ずVideoViewを保持してください)。これはAndroid 2.2および3.0デバイスでテストされています。
適切な使用例:
レイアウトxml:
<?xml version="1.0" encoding="utf-8"?>
<!-- This file is /res/layout/video_recorder.xml based on listing 9-6 in Pro Android 2 -->
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical" Android:layout_width="fill_parent"
Android:layout_height="fill_parent">
<RelativeLayout Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:gravity="center">
<VideoView Android:id="@+id/videoView" Android:layout_width="1px"
Android:layout_height="1px" />
</RelativeLayout>
</LinearLayout>
Javaクラス:
import Java.io.File;
import Android.app.Activity;
import Android.hardware.Camera;
import Android.media.MediaRecorder;
import Android.os.Bundle;
import Android.util.Log;
import Android.view.MotionEvent;
import Android.view.SurfaceHolder;
import Android.widget.Toast;
import Android.widget.VideoView;
/**
* Android video recorder with "no" preview (the preview is a 1x1 pixel which
* simulates an unobtrusive recording led). Based on Pro Android 2 2010 (Hashimi
* et al) source code in Listing 9-6.
*
* Also demonstrates how to use the front-facing and back-facing cameras.
* A calling Intent can pass an Extra to use the front facing camera if available.
*
* Suitable use cases:
* A: eye gaze tracking library to let users use eyes as a mouse to navigate a web page
* B: use tablet camera(s) to replace video camera in lab experiments
* (psycholingusitics or other experiments)
*
* Video is recording is controlled in two ways:
* 1. Video starts and stops with the activity
* 2. Video starts and stops on any touch
*
* To control recording in other ways see the try blocks of the onTouchEvent
*
* To incorporate into project add these features and permissions to
* manifest.xml:
*
* <uses-feature Android:name="Android.hardware.camera"/>
* <uses-feature Android:name="Android.hardware.camera.autofocus"/>
*
* <uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE" />
* <uses-permission Android:name="Android.permission.CAMERA" />
* <uses-permission Android:name="Android.permission.RECORD_AUDIO" />
*
* Tested Date: October 2 2011 with manifest.xml
* <uses-sdk Android:minSdkVersion="8" Android:targetSdkVersion="11"/>
*/
public class VideoRecorderSubExperiment extends Activity implements
SurfaceHolder.Callback {
public static final String EXTRA_USE_FRONT_FACING_CAMERA ="frontcamera";
private static final String OUTPUT_FILE = "/sdcard/videooutput";
private static final String TAG = "RecordVideo";
private Boolean mRecording = false;
private Boolean mUseFrontFacingCamera = false;
private VideoView mVideoView = null;
private MediaRecorder mVideoRecorder = null;
private Camera mCamera;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video_recorder);
mVideoView = (VideoView) this.findViewById(R.id.videoView);
//mUseFrontFacingCamera = getIntent().getExtras().getBoolean(
// EXTRA_USE_FRONT_FACING_CAMERA, true);
if(mUseFrontFacingCamera){
// If caller wants to use front facing camera, then make sure the device has one...
// Hard coded to only open front facing camera on Xoom (model MZ604)
// For more universal solution try:
// http://stackoverflow.com/questions/2779002/how-to-open-front-camera-on-Android-platform
String deviceModel = Android.os.Build.MODEL;
if (deviceModel.contains("MZ604")) {
mUseFrontFacingCamera = true;
} else {
Toast.makeText(
getApplicationContext(),
"The App isn't designed to use this Android's front facing camera.\n " +
"The device model is : " + deviceModel, Toast.LENGTH_LONG).show();
mUseFrontFacingCamera = false;
}
}
final SurfaceHolder holder = mVideoView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_Push_BUFFERS);
}
public boolean onTouchEvent(MotionEvent event) {
// can use the xy of the touch to start and stop recording
float positionX = event.getX();
float positionY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// Screen is pressed for the first time
break;
case MotionEvent.ACTION_MOVE:
// Screen is still pressed, float have been updated
break;
case MotionEvent.ACTION_UP:
// Screen is not touched anymore
if (mRecording) {
// To stop recording attach this try block to another event listener,
// button etc
try {
stopRecording();
} catch (Exception e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
} else {
// To begin recording attach this try block to another event listener,
// button etc
try {
beginRecording(mVideoView.getHolder());
} catch (Exception e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
}
break;
}
return super.onTouchEvent(event);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
beginRecording(holder);
} catch (Exception e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.v(TAG, "Width x Height = " + width + "x" + height);
}
private void stopRecording() throws Exception {
mRecording = false;
if (mVideoRecorder != null) {
mVideoRecorder.stop();
mVideoRecorder.release();
mVideoRecorder = null;
}
if (mCamera != null) {
mCamera.reconnect();
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
@Override
protected void onDestroy() {
try {
stopRecording();
} catch (Exception e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
super.onDestroy();
}
/**
* Uses the surface defined in video_recorder.xml
* Tested using
* 2.2 (HTC Desire/Hero phone) -> Use all defaults works, records back facing camera with AMR_NB audio
* 3.0 (Motorola Xoom tablet) -> Use all defaults doesn't work, works with these specs, might work with others
*
* @param holder The surfaceholder from the videoview of the layout
* @throws Exception
*/
private void beginRecording(SurfaceHolder holder) throws Exception {
if (mVideoRecorder != null) {
mVideoRecorder.stop();
mVideoRecorder.release();
mVideoRecorder = null;
}
if (mCamera != null) {
mCamera.reconnect();
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
String uniqueOutFile = OUTPUT_FILE + System.currentTimeMillis() + ".3gp";
File outFile = new File(uniqueOutFile);
if (outFile.exists()) {
outFile.delete();
}
try {
if (mUseFrontFacingCamera) {
//hard coded assuming 1 is the front facing camera
mCamera = Camera.open(1);
} else {
mCamera = Camera.open();
}
// Camera setup is based on the API Camera Preview demo
mCamera.setPreviewDisplay(holder);
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(640, 480);
mCamera.setParameters(parameters);
mCamera.startPreview();
mCamera.unlock();
mVideoRecorder = new MediaRecorder();
mVideoRecorder.setCamera(mCamera);
// Media recorder setup is based on Listing 9-6, Hashimi et all 2010
// values based on best practices and good quality,
// tested via upload to YouTube and played in QuickTime on Mac Snow Leopard
mVideoRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mVideoRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mVideoRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);// THREE_GPP
// is big-endian,
// storing and
// transferring
// the most
// significant
// bytes first.
// MPEG_4 as another option
mVideoRecorder.setVideoSize(640, 480);// YouTube recommended size: 320x240,
// OpenGazer eye tracker: 640x480
// YouTube HD: 1280x720
mVideoRecorder.setVideoFrameRate(20); //might be auto-determined due to lighting
mVideoRecorder.setVideoEncodingBitRate(3000000);// 3 megapixel, or the max of
// the camera
mVideoRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);// MPEG_4_SP
// Simple Profile is
// for low bit
// rate and low
// resolution
// H264 is MPEG-4 Part 10
//is commonly referred to
// as H.264 or AVC
int sdk = Android.os.Build.VERSION.SDK_INT;
// Gingerbread and up can have wide band ie 16,000 hz recordings
// (Okay quality for human voice)
if (sdk >= 10) {
mVideoRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_WB);
mVideoRecorder.setAudioSamplingRate(16000);
} else {
// Other devices only have narrow band, ie 8,000 hz
// (Same quality as a phone call, not really good quality for any purpose.
// For human voice 8,000 hz means /f/ and /th/ are indistinguishable)
mVideoRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
}
mVideoRecorder.setMaxDuration(30000); // limit to 30 seconds
mVideoRecorder.setPreviewDisplay(holder.getSurface());
mVideoRecorder.setOutputFile(uniqueOutFile);
mVideoRecorder.prepare();
mVideoRecorder.start();
mRecording = true;
} catch (Exception e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
}
}
これを確認しましたか?
http://code.google.com/p/Android/issues/detail?id=505
これらの人たちは、それがタイミングの問題であり、MediaRecorder状態マシンが状態間で(ハードウェアに依存する)遅延を必要とする可能性があることを示唆しています。
各状態が完全に達成されたときにコールバックがあった場合、それはいいことです。その場合、準備を整えることができます。
カメラアプリケーションの source は、これをデバッグするのに役立ちます。
これは権限エラーの可能性があります。 AndroidManifestファイルにAndroid.permission.CAMERA権限が設定されていますか?
私の場合、上記のサンプルをコピーして貼り付けることができませんでした。次に、MediaRecorderでメソッドを表示すると、setPreviewDisplayが見つかりました。 Camera.setPreviewDisplayで使用されるサーフェスを渡してこのメソッドを呼び出し、.prepareのIOExceptionがなくなり、ビデオを記録することができました。自分で試して、結果を投稿してください。