当前位置: 移动技术网 > IT编程>移动开发>Android > Android使用MediaRecorder实现录像功能

Android使用MediaRecorder实现录像功能

2019年07月24日  | 移动技术网IT编程  | 我要评论

奥巴马当选演讲稿,a955刷机,钢水温度

用mediarecorder实现简单的录像功能

思路:定义一个surfaceview用来显示预览,在surfaceholder的回调中用camera对象启动预览。然后调用mediarecorder来录像。仅仅是实现了简单的录像開始和停止功能。顶部能显示显示录像的时间,还有待完好。

代码例如以下:

在androidmanifest.xml加入以下的权限:

<uses-permission android:name="android.permission.camera" />
<uses-permission android:name="android.permission.record_audio" />
<uses-permission android:name="android.permission.mount_unmount_filesystems" />
<uses-permission android:name="android.permission.read_external_storage" />
<uses-permission android:name="android.permission.write_external_storage"/>
<!-- 硬件支持 -->
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>
activity_main.xml
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent" >

 <surfaceview
 android:id="@+id/camera_preview"
 android:layout_width="match_parent"
 android:layout_height="match_parent" />

 <linearlayout
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_alignparenttop="true"
 android:layout_centerhorizontal="true"
 android:orientation="horizontal">

 <textview
  android:id="@+id/timestamp_minute_prefix"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:textcolor="#7f00ff"
  android:textsize="30sp"
  android:text="0"/>

 <textview
  android:id="@+id/timestamp_minute_text"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:textcolor="#7f00ff"
  android:textsize="30sp"
  android:text="0"/>

 <textview
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:textcolor="#7f00ff"
  android:textsize="30sp"
  android:text=":"/>

 <textview
  android:id="@+id/timestamp_second_prefix"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:textcolor="#7f00ff"
  android:textsize="30sp"
  android:text="0"/>

 <textview
  android:id="@+id/timestamp_second_text"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:textcolor="#7f00ff"
  android:textsize="30sp"
  android:text="0"/>
 </linearlayout>

 <imagebutton
 android:id="@+id/record_shutter"
 android:layout_width="64dp"
 android:layout_height="64dp"
 android:layout_alignparentbottom="true"
 android:layout_centerhorizontal="true"
 android:layout_marginbottom="15dp"
 android:background="@android:color/transparent"
 android:scaletype="centercrop"
 android:src="@drawable/recording_shutter" />

</relativelayout>

mainactivity.java

package com.jackie.videorecorder;

import java.io.file;

import android.app.activity;
import android.hardware.camera;
import android.hardware.camera.parameters;
import android.hardware.camera.size;
import android.media.mediarecorder;
import android.os.bundle;
import android.os.environment;
import android.os.handler;
import android.util.log;
import android.view.surfaceholder;
import android.view.surfaceview;
import android.view.view;
import android.view.view.onclicklistener;
import android.widget.imagebutton;
import android.widget.textview;

import org.w3c.dom.text;

public class mainactivity extends activity implements onclicklistener {
 private surfaceview mcamerapreview;
 private surfaceholder msurfaceholder;
 private imagebutton mshutter;
 private textview mminuteprefix;
 private textview mminutetext;
 private textview msecondprefix;
 private textview msecondtext;

 private camera mcamera;
 private mediarecorder mrecorder;

 private final static int camera_id = 0;

 private boolean misrecording = false;
 private boolean missufacecreated = false;

 private static final string tag = "jackie";

 private handler mhandler = new handler();

 @override
 protected void oncreate(bundle savedinstancestate) {
 super.oncreate(savedinstancestate);
 setcontentview(r.layout.activity_main);

 mcamerapreview = (surfaceview) findviewbyid(r.id.camera_preview);
 mminuteprefix = (textview) findviewbyid(r.id.timestamp_minute_prefix);
 mminutetext = (textview) findviewbyid(r.id.timestamp_minute_text);
 msecondprefix = (textview) findviewbyid(r.id.timestamp_second_prefix);
 msecondtext = (textview) findviewbyid(r.id.timestamp_second_text);

 msurfaceholder = mcamerapreview.getholder();
 msurfaceholder.addcallback(msurfacecallback);
 msurfaceholder.settype(surfaceholder.surface_type_push_buffers);

 mshutter = (imagebutton) findviewbyid(r.id.record_shutter);
 mshutter.setonclicklistener(this);
 }

 @override
 protected void onpause() {
 super.onpause();
 if (misrecording) {
  stoprecording();
 }
 stoppreview();
 }

 private surfaceholder.callback msurfacecallback = new surfaceholder.callback() {

 @override
 public void surfacedestroyed(surfaceholder holder) {
  missufacecreated = false;
 }

 @override
 public void surfacecreated(surfaceholder holder) {
  missufacecreated = true;
 }

 @override
 public void surfacechanged(surfaceholder holder, int format, int width, int height) {
  startpreview();
 }
 };

 //启动预览
 private void startpreview() {
 //保证仅仅有一个camera对象
 if (mcamera != null || !missufacecreated) {
  log.d(tag, "startpreview will return");
  return;
 }

 mcamera = camera.open(camera_id);

 parameters parameters = mcamera.getparameters();
 size size = getbestpreviewsize(camerautils.preview_width, camerautils.preview_height, parameters);
 if (size != null) {
  parameters.setpreviewsize(size.width, size.height);
 }

 parameters.setfocusmode(parameters.focus_mode_continuous_video);
 parameters.setpreviewframerate(20);

 //设置相机预览方向
 mcamera.setdisplayorientation(90);

 mcamera.setparameters(parameters);

 try {
  mcamera.setpreviewdisplay(msurfaceholder);
// mcamera.setpreviewcallback(mpreviewcallback);
 } catch (exception e) {
  log.d(tag, e.getmessage());
 }

 mcamera.startpreview();
 }

 private void stoppreview() {
 //释放camera对象
 if (mcamera != null) {
  try {
  mcamera.setpreviewdisplay(null);
  } catch (exception e) {
  log.e(tag, e.getmessage());
  }

  mcamera.stoppreview();
  mcamera.release();
  mcamera = null;
 }
 }

 private camera.size getbestpreviewsize(int width, int height, camera.parameters parameters) {
 camera.size result = null;

 for (camera.size size : parameters.getsupportedpreviewsizes()) {
  if (size.width <= width && size.height <= height) {
  if (result == null) {
   result = size;
  } else {
   int resultarea = result.width * result.height;
   int newarea = size.width * size.height;

   if (newarea > resultarea) {
   result = size;
   }
  }
  }
 }

 return result;
 }

 @override
 public void onclick(view v) {
 if (misrecording) {
  stoprecording();
 } else {
  initmediarecorder();
  startrecording();

  //開始录像后,每隔1s去更新录像的时间戳
  mhandler.postdelayed(mtimestamprunnable, 1000);
 }
 }

 private void initmediarecorder() {
 mrecorder = new mediarecorder();//实例化
 mcamera.unlock();
 //给recorder设置camera对象,保证录像跟预览的方向保持一致
 mrecorder.setcamera(mcamera);
 mrecorder.setorientationhint(90); //改变保存后的视频文件播放时是否横屏(不加这句。视频文件播放的时候角度是反的)
 mrecorder.setaudiosource(mediarecorder.audiosource.mic); // 设置从麦克风採集声音
 mrecorder.setvideosource(mediarecorder.videosource.camera); // 设置从摄像头採集图像
 mrecorder.setoutputformat(mediarecorder.outputformat.mpeg_4); // 设置视频的输出格式 为mp4
 mrecorder.setaudioencoder(mediarecorder.audioencoder.default); // 设置音频的编码格式
 mrecorder.setvideoencoder(mediarecorder.videoencoder.h264); // 设置视频的编码格式
 mrecorder.setvideosize(176, 144); // 设置视频大小
 mrecorder.setvideoframerate(20); // 设置帧率
// mrecorder.setmaxduration(10000); //设置最大录像时间为10s
 mrecorder.setpreviewdisplay(msurfaceholder.getsurface());

 //设置视频存储路径
 file file = new file(environment.getexternalstoragepublicdirectory(environment.directory_movies) + file.separator + "videorecorder");
 if (!file.exists()) {
  //多级目录的创建
  file.mkdirs();
 }
 mrecorder.setoutputfile(file.getpath() + file.separator + "vid_" + system.currenttimemillis() + ".mp4");
 }

 private void startrecording() {
 if (mrecorder != null) {
  try {
  mrecorder.prepare();
  mrecorder.start();
  } catch (exception e) {
  misrecording = false;
  log.e(tag, e.getmessage());
  }
 }

 mshutter.setimagedrawable(getresources().getdrawable(r.drawable.recording_shutter_hl));
 misrecording = true;
 }

 private void stoprecording() {
 if (mcamera != null) {
  mcamera.lock();
 }

 if (mrecorder != null) {
  mrecorder.stop();
  mrecorder.release();
  mrecorder = null;
 }

 mshutter.setimagedrawable(getresources().getdrawable(r.drawable.recording_shutter));
 misrecording = false;

 mhandler.removecallbacks(mtimestamprunnable);

 //将录像时间还原
 mminuteprefix.setvisibility(view.visible);
 mminutetext.settext("0");
 msecondprefix.setvisibility(view.visible);
 msecondtext.settext("0");

 //重新启动预览
 startpreview();
 }

 private runnable mtimestamprunnable = new runnable() {
 @override
 public void run() {
  updatetimestamp();
  mhandler.postdelayed(this, 1000);
 }
 };

 private void updatetimestamp() {
 int second = integer.parseint(msecondtext.gettext().tostring());
 int minute = integer.parseint(mminutetext.gettext().tostring());
 second++;
 log.d(tag, "second: " + second);

 if (second < 10) {
  msecondtext.settext(string.valueof(second));
 } else if (second >= 10 && second < 60) {
  msecondprefix.setvisibility(view.gone);
  msecondtext.settext(string.valueof(second));
 } else if (second >= 60) {
  msecondprefix.setvisibility(view.visible);
  msecondtext.settext("0");

  minute++;
  mminutetext.settext(string.valueof(minute));
 } else if (minute >= 60) {
  mminuteprefix.setvisibility(view.gone);
 }
 }
}

效果例如以下:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网