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实现录像功能
-
Python使用itertools模块实现排列组合功能示例
-
Python使用matplotlib实现基础绘图功能示例
-
android端实现验证码随机生成功能
-
Android实现ListView的A-Z字母排序和过滤搜索功能 实现汉字转成拼音
-
Android 使用fast-verification实现验证码填写功能的实例代码
-
Android使用vitamio插件实现视频播放器
-
Android基于ibeacon实现蓝牙考勤功能
-
Android PhoneWindowManager监听屏幕右侧向左滑动实现返回功能
-
Android自定义View实现搜索框(SearchView)功能