欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android使用MediaRecorder实现录像功能

程序员文章站 2024-02-09 21:16:34
用mediarecorder实现简单的录像功能 思路:定义一个surfaceview用来显示预览,在surfaceholder的回调中用camera对象启动预览。然后调用...

用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);
 }
 }
}

效果例如以下:

Android使用MediaRecorder实现录像功能

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