您好我正在开发类似于此链接的Android视频应用程序 http://android-er.blogspot.in/2011/10/video-capture-using-mediarecorder-with.html 视频应用中的哪个位置以框架布局显示。
我在表面视图上尝试上面的一个,我的xml如下所示。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textSize="20sp" >
<SurfaceView
android:id="@+id/CameraView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="true" />
<ImageView
android:id="@+id/mybutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:src="@drawable/record_video" />
</RelativeLayout>
我不确定为什么它显示黑屏而不是相机视图。我的ViewActivity.java如下所示。
public class ViewActivity extends Activity implements OnClickListener, SurfaceHolder.Callback
{
MediaRecorder recorder;
SurfaceHolder holder;
boolean recording=false;
private MediaRecorder mediaRecorder;
private File file;
private ImageView recVideo;
private SurfaceView cameraView;
private Camera camera;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
recorder = new MediaRecorder();
initRecorder();
setContentView(R.layout.view);
recVideo = (ImageView)findViewById(R.id.mybutton);
cameraView = (SurfaceView) findViewById(R.id.CameraView);
holder = cameraView.getHolder();
holder.addCallback(ViewActivity.this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
recVideo.setClickable(true);
recVideo.setOnClickListener(this);
}
private void initRecorder()
{
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
recorder.setOutputFile(this.initFile().getAbsolutePath());
recorder.setMaxDuration(60000); // Set max duration 60 sec.
recorder.setMaxFileSize(5000000); // Set max file size 5M
}
private void prepareRecorder()
{
recorder.setPreviewDisplay(holder.getSurface());
try
{
recorder.prepare();
} catch (IllegalStateException e)
{
e.printStackTrace();
finish();
}
catch (IOException e)
{
e.printStackTrace();
finish();
}
}
public void onClick(View v)
{
if (recording)
{
recorder.stop();
recording = false;
initRecorder();
prepareRecorder();
Toast.makeText(ViewActivity.this,"Video Saved!",Toast.LENGTH_SHORT).show();
startActivity(new Intent(ViewActivity.this,ViewActivity.class));
finish();
}
else
{
recorder.start();
recording = true;
recVideo.setImageDrawable(getResources().getDrawable(R.drawable.stop_recording));
}
}
public void surfaceCreated(SurfaceHolder holder)
{
prepareRecorder();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height)
{
}
public void surfaceDestroyed(SurfaceHolder holder)
{
if (recording) {
recorder.stop();
recording = false;
}
recorder.release();
finish();
}
我不确定我哪里出错了。如何使表面视图显示摄像机视图而不是黑屏。
请帮助。
谢谢!
答案 0 :(得分:2)
这样做:
public class AndroidVideoCapture extends Activity {
private Camera myCamera;
private MyCameraSurfaceView myCameraSurfaceView;
private MediaRecorder mediaRecorder;
Button myButton;
RadioButton flashOff, flashTorch;
SurfaceHolder surfaceHolder;
boolean recording;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
recording = false;
setContentView(R.layout.main);
// Get Camera for preview
myCamera = getCameraInstance();
if (myCamera == null) {
Toast.makeText(AndroidVideoCapture.this, "Fail to get Camera",Toast.LENGTH_LONG).show();
}
myCameraSurfaceView = new MyCameraSurfaceView(this, myCamera);
FrameLayout myCameraPreview = (FrameLayout) findViewById(R.id.videoview);
myCameraPreview.addView(myCameraSurfaceView);
myButton = (Button) findViewById(R.id.mybutton);
myButton.setOnClickListener(myButtonOnClickListener);
flashOff = (RadioButton) findViewById(R.id.flashoff);
flashTorch = (RadioButton) findViewById(R.id.flashtorch);
}
Button.OnTouchListener flashButtonOnTouchListener = new Button.OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
// TODO Auto-generated method stub
if (myCamera != null) {
Parameters parameters = myCamera.getParameters();
switch (arg1.getAction()) {
case MotionEvent.ACTION_DOWN:
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
myCamera.setParameters(parameters);
break;
case MotionEvent.ACTION_UP:
parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
myCamera.setParameters(parameters);
break;
}
;
}
return true;
}
};
Button.OnClickListener flashModeButtonOnClickListener = new Button.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
};
Button.OnClickListener myButtonOnClickListener = new Button.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (recording) {
// stop recording and release camera
mediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
myCamera.lock();
// take camera access back from
recording = false;
// MediaRecorder
// inform the user that recording has stopped
// Exit after saved
//finish();
} else {
// Release Camera before MediaRecorder start
releaseCamera();
if (!prepareMediaRecorder()) {
Toast.makeText(AndroidVideoCapture.this,
"Fail in prepareMediaRecorder()!\n - Ended -",
Toast.LENGTH_LONG).show();
finish();
}
mediaRecorder.start();
recording = true;
myButton.setText("STOP");
}
}
};
private Camera getCameraInstance() {
// TODO Auto-generated method stub
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
c.setDisplayOrientation(90);
} catch (Exception e) {
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
private String getFlashModeSetting() {
if (flashTorch.isChecked()) {
return Parameters.FLASH_MODE_TORCH;
} else {
return Parameters.FLASH_MODE_OFF;
}
}
private boolean prepareMediaRecorder() {
myCamera = getCameraInstance();
Parameters parameters = myCamera.getParameters();
parameters.setFlashMode(getFlashModeSetting());
myCamera.setParameters(parameters);
mediaRecorder = new MediaRecorder();
myCamera.unlock();
mediaRecorder.setCamera(myCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
mediaRecorder.setOutputFile(getOutputMediaFile("movie"));
mediaRecorder.setMaxDuration(6000000); // Set max duration 60 sec.
mediaRecorder.setMaxFileSize(50000000); // Set max file size 5M
mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder().getSurface());
mediaRecorder.setOrientationHint(90);
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}
return true;
}
@Override
protected void onPause() {
super.onPause();
releaseMediaRecorder(); // if you are using MediaRecorder, release it
// first
releaseCamera(); // release the camera immediately on pause event
}
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;
}
}
public class MyCameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public MyCameraSurfaceView(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format,int weight, int height) {
// If your preview can change or rotate, take care of those events
// here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
// make any resize, rotate or reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
// The Surface has been created, now tell the camera where to draw
// the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
private static String getOutputMediaFile(String sufix) {
String mediaFile;
File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), "/YappBack");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("VideoLogger", "failed to create directory");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss").format(new Date());
if (!sufix.equals("movie")) {
mediaFile = mediaStorageDir.getPath() + File.separator + "output_"+ timeStamp + "_" + sufix + ".txt";
} else {
mediaFile = mediaStorageDir.getPath() + File.separator + "output_"+ timeStamp + ".mp4";
}
//mediaFile = Environment.getExternalStorageDirectory().getPath()+ "/default.mp4";
return mediaFile;
}
}
XML文件:
<?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" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:id="@+id/videoview"
android:layout_width="match_parent"
android:layout_height="600px" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<Button
android:id="@+id/mybutton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="REC"
android:textSize="12dp" />
<RadioGroup
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<RadioButton
android:id="@+id/flashoff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="OFF"
android:textSize="8dp" />
<RadioButton
android:id="@+id/flashtorch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Torch"
android:textSize="8dp" />
</RadioGroup>
</LinearLayout>
</LinearLayout>
</LinearLayout>
答案 1 :(得分:0)
确保您已在清单文件中声明了CAMERA权限。
同时检查您是否已从设置中授予了相机权限。
答案 2 :(得分:0)
确保您在mediaRecorder.setPreviewDisplay(new Surface(surfaceTexture));
之后致电camera.setPreviewTexture(surfaceTexture);
,然后诀窍就是camera.stopPreview()
之前调用mediaRecorder.start();