どなたかカメラから動画保存の方法を教えて下さい。

1,470 views
Skip to first unread message

yamasan

unread,
Aug 4, 2010, 3:26:43 AM8/4/10
to 日本Androidの会福岡支部
こんにちわ。
山口と言います。
現在、カメラから動画を撮影して保存する仕組みをAndroidで調査しているのですが、どうしてもうまくいきません。
ネットで調べた限りで、実装して見たのですが、何故か直ぐに画面表示されず、終了してしまいます。mp4で所定の場所には、ファイルは出来ますが、0バ
イトとなり録画されておりません。
カメラからの録画について、御教授頂きたく思います。
よろしくお願いします。

開発環境と致しましては、実機が、エクスペリアの為、ver1.6となります。

以下が、今の実装コードになります。

------------------------------------------------

import java.io.IOException;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.hardware.Camera;

import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;

public class CameraView extends Activity {
/** Called when the activity is first created. */

private MediaRecorder recorder;
private Preview mPreview;

@Override
public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
mPreview = new Preview(this);
setContentView(mPreview);

SurfaceHolder holder = mPreview.getHolder();

recorder = new MediaRecorder();

String PATH_NAME = "/sdcard/test.mp4";

recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setVideoFrameRate(15);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);

recorder.setOutputFile(PATH_NAME);


recorder.setPreviewDisplay(holder.getSurface());


this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

recorder.prepare();

recorder.start();


}


class Preview extends SurfaceView implements SurfaceHolder.Callback
{
SurfaceHolder mHolder;
Camera mCamera;

Preview(Context context) {
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

}

public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
}

public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}

public void surfaceChanged(SurfaceHolder holder, int format, int
w, int h) {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(w, h);
mCamera.setParameters(parameters);
mCamera.startPreview();
}
}

}

-----------------------------------------

よろしくお願いします。

findup

unread,
Aug 4, 2010, 12:42:13 PM8/4/10
to android-group...@googlegroups.com
こんばんは。findupです。

とりあえず、録画するだけなら以下のコードで動きました。
実機はGalaxy S(Android 2.1)で、Surfaceサイズとカメラプレビューのアスペクト比が合わないので、少しプレビューが横に伸びますが。

元ソースを見て、個人的に気になったのは、以下の点です。

・CameraとMediaRecorderとで両方カメラデバイスを指定しているのでおそらく二重オープンっぽくなっている
→録画だけならMediaRecorderだけで良いので一本化

・SurfaceCreated()が呼ばれるまではSurfaceは生成されていないので、setPreviewDisplay()を呼んでもおそらく無効
→setPreviewDisplay()の呼び出し箇所をonCreate()から移動

公式リファレンスのCameraクラス

http://developer.android.com/reference/android/hardware/Camera.html

で説明されているような、Cameraを使ったプレビュー状態(非録画中)からMediaRecorderを使った録画へ切り替えるには
もう少し手順が必要そうですね。

-----------------
import java.io.IOException;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;

import android.media.MediaRecorder;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraView extends Activity {

private MediaRecorder recorder;
private Preview mPreview;

@Override
public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
mPreview = new Preview(this);
setContentView(mPreview);

recorder = new MediaRecorder();

String PATH_NAME = "/sdcard/test.mp4";

recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setVideoFrameRate(15);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);

recorder.setOutputFile(PATH_NAME);

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

}

class Preview extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;

Preview(Context context) {


super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public void surfaceCreated(SurfaceHolder holder) {

}

public void surfaceDestroyed(SurfaceHolder holder) {

recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
}

public void surfaceChanged(SurfaceHolder holder, int format, int w,
int h) {

recorder.setPreviewDisplay(holder.getSurface());

try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

recorder.start();
}
}

}
-----------------------------------


--
Toshiyuki Sugimoto < find...@gmail.com >
blog : http://www.swingingblue.net/mt/
twitter : http://twitter.com/findup

yamasan

unread,
Aug 8, 2010, 5:36:31 AM8/8/10
to 日本Androidの会福岡支部
こんにちわ。
山口です。

findupさんへ

録画の件、返信が遅くなり申し訳ありません。
以下のコードにて無事に録画することが出来ました。
ホントにありがとうございました。

ご指摘の通り、非録画状態から録画にする場合は、もう少し仕組みを
考える必要はあるようですが、今回は、まずは録画が出来るようになる
事が調査目標でしたので、助かりました。
ありがとうございます。
> Toshiyuki Sugimoto < findu...@gmail.com >
Reply all
Reply to author
Forward
0 new messages