Android录制视频(二)

来源:互联网 发布:梁国平广东广电网络 编辑:程序博客网 时间:2024/06/10 16:40


package com.demo01;
/**
 * 视频录制
 */

import java.io.File;
import java.io.IOException;

import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
 private SurfaceView surfaceView;
 private Button luXiang_bt; 
 private Button tingZhi_bt; 
 private TextView time_tv; //显示时间的文本框
 private MediaRecorder mRecorder;
 private boolean recording;  // 记录是否正在录像,fasle为未录像, true 为正在录像
 private File videoFolder;  // 存放视频的文件夹
 private File videFile;   // 视频文件
 private Handler handler;
 private int time;   // 时间
 private Camera myCamera; // 相机声明
 private SurfaceHolder holder;
 /**
  * 录制过程中,时间变化
  */
 private Runnable timeRun = new Runnable() {

  @Override
  public void run() {
   time++;
   time_tv.setText(time + "秒");
   handler.postDelayed(timeRun, 1000);
  }
 };


 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);// 强制横屏
  setContentView(R.layout.main);

  //获取控件
  surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
  luXiang_bt = (Button) findViewById(R.id.luXiang_bt);
  tingZhi_bt = (Button) findViewById(R.id.tingZhi_bt);
  time_tv = (TextView) findViewById(R.id.time);

  handler = new Handler();
  holder = surfaceView.getHolder();

  // 判断sd卡是否存在
  boolean sdCardExist = Environment.getExternalStorageState().equals(
    android.os.Environment.MEDIA_MOUNTED);
  System.out.println("sdCard存在: " + sdCardExist);

  if (sdCardExist) {
   // 设定存放视频的文件夹的路径
   String path = Environment.getExternalStorageDirectory().getAbsolutePath()
       + File.separator
       + "VideoFolder"
       + File.separator;

   // 声明存放视频的文件夹的File对象
   videoFolder = new File(path);

   // 如果不存在此文件夹,则创建
   if (!videoFolder.exists()) {
    videoFolder.mkdirs();
   }

   // 设置surfaceView不管理的缓冲区
   surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
   // 设置surfaceView分辨率
   surfaceView.getHolder().setFixedSize(800, 480);

   // 录像点击事件
   luXiang_bt.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
     if (!recording) {
      try {
       // 关闭预览并释放资源
       myCamera.stopPreview();
       myCamera.release();
       myCamera = null;

       mRecorder = new MediaRecorder();
       // 获取当前时间,作为视频文件的文件名
       String nowTime = java.text.MessageFormat.format(
            "{0,date,yyyyMMdd_HHmmss}",
            new Object[] {new java.sql.Date(System.currentTimeMillis())});
       // 声明视频文件对象
       videFile = new File(videoFolder.getAbsoluteFile()
           + File.separator + "video" + nowTime + ".mp4");
       // 创建此视频文件
       videFile.createNewFile();
       System.out.println("视频文件: " + videFile.getAbsolutePath());

       mRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface()); // 预览
       mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 视频源
       mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 录音源为麦克风
       mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); // 输出格式为mp4
       /* 引用android.util.DisplayMetrics 获取分辨率 */
//        DisplayMetrics dm = new DisplayMetrics();
//        getWindowManager().getDefaultDisplay().getMetrics(dm);
       mRecorder.setVideoSize(800, 480); // 视频尺寸
       mRecorder.setVideoFrameRate(30); // 视频帧频率
       mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); // 视频编码
       mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); // 音频编码
       mRecorder.setMaxDuration(1800000);
       mRecorder.setOutputFile(videFile.getAbsolutePath());
       mRecorder.prepare(); // 准备录像
       mRecorder.start(); // 开始录像
       time_tv.setVisibility(View.VISIBLE); // 设置文本框可见
       handler.post(timeRun); // 调用Runable
       recording = true; // 改变录制状态为正在录制
      } catch (IOException e1) {
       e1.printStackTrace();
      } catch (IllegalStateException e) {
       e.printStackTrace();
      }
     }
     else
      Toast.makeText(MainActivity.this, "视频正在录制中...", Toast.LENGTH_LONG).show();
    }

   });
  } 
  else 
   Toast.makeText(this, "未找到sdCard!", Toast.LENGTH_LONG).show();

  // 停止点击事件
  tingZhi_bt.setOnClickListener(new View.OnClickListener() {

   @Override
   public void onClick(View v) {
    if (recording) {
     mRecorder.stop();
     mRecorder.release();
     handler.removeCallbacks(timeRun);
     time_tv.setVisibility(View.GONE);
     int videoTimeLength = time;
     time = 0;
     recording = false;
     Toast.makeText(MainActivity.this,
         videFile.getAbsolutePath() + "  " + videoTimeLength + "秒",
         Toast.LENGTH_LONG).show();
    }
    // 开启相机
    if (myCamera == null) {
     myCamera = Camera.open();
     try {
      myCamera.setPreviewDisplay(holder);
     } catch (IOException e) {
      e.printStackTrace();
     }
    }
    myCamera.startPreview(); // 开启预览
   }
  });

  // 添加回调
  holder.addCallback(new SurfaceHolder.Callback() {

   @Override
   public void surfaceCreated(SurfaceHolder holder) {
    System.out.println("------surfaceCreated------");
    // 开启相机
    if (myCamera == null) {  
     myCamera = Camera.open();
     try {
      myCamera.setPreviewDisplay(holder);
     } catch (IOException e) {
      e.printStackTrace();
     }
    }

   }

   @Override
   public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    System.out.println("------surfaceChanged------");
    // 开始预览
    myCamera.startPreview();

   }

   @Override
   public void surfaceDestroyed(SurfaceHolder holder) {
    System.out.println("------surfaceDestroyed------");
    // 关闭预览并释放资源
    if (myCamera != null) {
     myCamera.stopPreview();
     myCamera.release();
     myCamera = null;
    }
   }
  });

 }

 @Override
 protected void onDestroy() {
  handler.removeCallbacks(timeRun);
  if (mRecorder != null) {
   mRecorder.release();
  }
  if (myCamera != null) {
   myCamera.stopPreview();
   myCamera.release();
  }
  super.onDestroy();
 }

}

AndroidManifast文件:


http://schemas.android.com/apk/res/android"
    package="com.demo01"
    android:versionCode="1"
    android:versionName="1.0" >

    
 
 

 
 

 

    
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" >
        
            android:name=".MainActivity"
            android:label="视频录制DEMO" >
            
                

                
            
        
    

 

 

布局文件:


http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#ffffff" >

    
        android:id="@+id/surfaceview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"/>

    <BUTTON 

<button 
       android:id="@+id/tingZhi_bt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:text="停止"/>


    <BUTTON 

<button
        android:id="@+id/luXiang_bt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_toLeftOf="@id/tingZhi_bt"
        android:text="录像"/>

    <TEXTVIEW 

<textview 
<TEXTVIEW 

        android:id="@+id/time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#FF0000"
        android:text="1秒"
        android:visibility="gone"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="10dp"/>

 

这样录制出来的视频,其码率只有不到100的码率.视频很模糊
而调动系统录像程序,录制出来的视频,码率有将近3000的码率,非常清晰

解决方法一:

mMediaRecorder
       .setVideoSource(MediaRecorder.VideoSource.CAMERA);
     mMediaRecorder
       .setAudioSource(MediaRecorder.AudioSource.MIC);

//     mMediaRecorder
//       .setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
//     mMediaRecorder
//       .setVideoEncoder(MediaRecorder.VideoEncoder.H264);
//     mMediaRecorder
//       .setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
//     mMediaRecorder.setVideoSize(1920, 1020);
//     mMediaRecorder.setVideoFrameRate(15);//现象:在2.3上正常,4.0上报错,原因:每秒12-15帧之间足以表示运动,电视是30


     mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
     mMediaRecorder.setPreviewDisplay(mSurfaceHolder
       .getSurface());
     String videoOutPath = Environment.getExternalStorageDirectory()
       + "/DCIM/"
       + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".3gp";
     mMediaRecorder.setOutputFile(videoOutPath);

 

设置属性在API 8以上只需要setProfile,outputformat/encoder等不用设置了,我改成这样之后视频清晰度和大小就和系统的录制视频一样了

 

 

参考:http://bbs.csdn.net/topics/390221289

 

本文出自 “Focus_000” 博客,请务必保留此出处http://120806872.blog.51cto.com/8289253/1395815

0 0