您好!欢迎来到源码码网

Android使用MediaRecorder进行视频录制

  • 源码教程
  • 来源:源码码网
  • 编辑:admin
  • 时间:2021-01-14 20:44
  • 阅读:361

视频录制也可以通过 MediaRecorder 类完成,其步骤与音频录制基本相同,只是添加了一些对视频进行处理的操作。

视频录制的基本步骤如下:

1) 调用Camera.open()方法打开摄像头。

2) 调用 Camera.setPreviewDisplay() 连接预览窗口

以便将从摄像头获取的图像放置到预览窗口中显示出来。

3) 调用 Camera.startPreview()启动预览
显示摄像头拍摄到的图像。

4) 使用 MediaRecorder 进行视频录制。

1.使用 Camera.unlock() 方法解锁摄像头,以使 MediaRecorder 获得对摄像头的使用权。

2.配置 MediaRecorder。


1)建立 MediaRecorder 类的对象,并设置音频源和视频源:

MediaRecorder recorder=new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

2)设置视频的输出和编码格式。在 Android 2.2(API Level 8)以上版本的 SDK 中,可以直接调用 MediaRecorder.setProfile 方法进行相关配置:

recorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));

其中,MediaRecorder.setProfile() 方法为 Android 2.2(API Level 8)之后 MediaRecorder 类新提供的方法,通过 CamcorderProfile 对象可用于对 MediaRecorder 进行相关设置。

CamcorderProfile 为预先定义好的一组视频录制相关配置信息。

Android SDK 共定义了 14 种 CamcorderProfile 配置,如 CamcorderProfile. QUALITY_HIGH、CamcorderProfile. QUALITY_LOW、CamcorderProfile. QUALITY_TIME_LAPSE_1080P 等。其中,QUALITY_LOW 和 QUALITY_HIGH 两种配置是所有的摄像头都支持的,其他配置则根据硬件性能决定。

每一种配置都涉及文件输出格式、视频编码格式、视频比特率、视频帧率、视频的高和宽、音频编码格式、音频的比特率、音频采样率和音频录制的通道数几个方面。通过使用这些预定义配置能够降低代码复杂度,提高编码效率。

3)设置录制的视频文件的保存位置及文件名:

MediaRecorder.setOutputFile(PATH_NAME);


4)使用 MediaRecorder.setPreviewDisplay() 方法指定 MediaRecorder 的视频预览窗口。

需要注意的是,以上配置过程必须按照顺序进行,否则会发生错误。

3.将录像器置于准备状态:

MediaRecorder.prepare();

4.启动录像器:

MediaRecorder.start();

5.进行视频录制:

5) 视频录制完成后,可使用以下方法停止视频录制。

1.停止录像器:

MediaRecorder.stop();


2.重置录像器的相关配置:

MediaRecorder.reset()


3.释放录像器对象:

MediaRecorder.release();


4.调用 Camera.lock() 方法锁定摄像头。从 Android N 开始,该调用也不再必需,除非 MediaRecorder.prepare() 方法失败。

6) 调用Camera.stopPreview()方法停止预览。

7) 调用Camera.release()方法释放摄像头 。


另外,在 Android N 系统下,Camera.unlock() 方法和 Camera.lock() 方法可由 Android 框架来完成。

实例 VideoRecorderDemo 演示了使用 MediaRecorder 进行视频录制的过程,该实例的运行效果如图 1 所示。

VideoRecorderDemo

图 1  VideoRecorderDemo 

实例 VideoRecorderDemo 使用的布局文件 main.xml 的内容如下:

  1. <?xml version="1.0" encoding="utf-8"?>

  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

  3. android:layout_width="fill_parent"

  4. android:layout_height="fill_parent"

  5. android:orientation="vertical">


  6. <TextView

  7. android:layout_width="fill_parent"

  8. android:layout_height="wrap_content"

  9. android:text="@string/hello" />


  10. <SurfaceView

  11. android:id="@+id/surfaceView1"

  12. android:layout_width="fill_parent"

  13. android:layout_height="wrap_content"

  14. android:layout_weight="0.58" />


  15. <LinearLayout

  16. android:id="@+id/linearLayout1"

  17. android:layout_width="match_parent"

  18. android:layout_height="wrap_content"

  19. android:gravity="center">


  20. <Button

  21. android:id="@+id/button1"

  22. android:layout_width="wrap_content"

  23. android:layout_height="wrap_content"

  24. android:text="@string/opBtn" />


  25. <Button

  26. android:id="@+id/button2"

  27. android:layout_width="wrap_content"

  28. android:layout_height="wrap_content"

  29. android:text="@string/play" />


  30. <Button

  31. android:id="@+id/button3"

  32. android:layout_width="wrap_content"

  33. android:layout_height="wrap_content"

  34. android:text="@string/cloBtn" />


  35. </LinearLayout>


  36. </LinearLayout>


其对应的资源文件 strings.xml 的内容如下:

  1. <resources>

  2. <string name="hello">使用MediaRecorder进行视频录制实例</string>

  3. <string name="app_name">VideoRecorder</string>

  4. <string name="opBtn">打开摄像头</string>

  5. <string name="play">录制</string>

  6. <string name="cloBtn">关闭摄像头</string>

  7. </resources>


由于实例 VideoRecorderDemo 中涉及音频录制、使用摄像头、向 SD 卡写文件等操作,因此需要在该工程的 AndroidManifest.xml 文件中声明相应权限。该文件内容如下:

  1. <?xml version="1.0" encoding="utf-8"?>

  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"

  3. package="introduction.android.mycamerademo"

  4. android:versionCode="1"

  5. android:versionName="1.0">


  6. <uses-sdk android:minSdkVersion="14" />

  7. <uses-feature android:name="android.hardware.camera.autofocus" />

  8. <uses-feature android:name="android.permission.CAMERA"/>

  9. <uses-permission android:name="android.permission.CAMERA" />

  10. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


  11. <application

  12. android:allowBackup="true"

  13. android:icon="@mipmap/ic_launcher"

  14. android:label="@string/app_name"

  15. android:roundIcon="@mipmap/ic_launcher_round"

  16. android:supportsRtl="true"

  17. android:theme="@style/AppTheme">

  18. <activity android:name=".MainActivity">

  19. <intent-filter>

  20. <action android:name="android.intent.action.MAIN" />


  21. <category android:name="android.intent.category.LAUNCHER" />

  22. </intent-filter>

  23. </activity>

  24. </application>


  25. </manifest>

实例 VideoRecorderDemo 的主 Activity 为 VideoRecorderDemoActivity,其代码如下:


  1. package introduction.android.mycamerademo;


  2. import java.io.BufferedOutputStream;

  3. import java.io.File;


  4. import java.io.FileNotFoundException;

  5. import java.io.FileOutputStream;

  6. import java.io.IOException;


  7. import android.app.Activity;

  8. import android.graphics.Bitmap;

  9. import android.graphics.BitmapFactory;

  10. import android.graphics.PixelFormat;

  11. import android.hardware.Camera;

  12. import android.hardware.Camera.Parameters;

  13. import android.hardware.Camera.PictureCallback;

  14. import android.media.MediaRecorder;

  15. import android.os.Bundle;

  16. import android.util.Log;

  17. import android.view.SurfaceHolder;

  18. import android.view.SurfaceView;

  19. import android.view.View;

  20. import android.view.View.OnClickListener;

  21. import android.widget.Button;


  22. public class MainActivity extends Activity {

  23. private Button opbtn;

  24. private Button playbtn;

  25. private Button clobtn;

  26. private SurfaceView surfaceView;

  27. private SurfaceHolder surfaceHolder;

  28. private Camera camera;

  29. private MediaRecorder videoRecorder;

  30. private String myVideofilepath = "sdcard/myvideo.3gp";


  31. /**

  32.     * Called when the activity is first created.

  33.     */

  34. @Override

  35. public void onCreate(Bundle savedInstanceState) {

  36. super.onCreate(savedInstanceState);

  37. setContentView(R.layout.activity_main);

  38. opbtn = (Button) this.findViewById(R.id.button1);

  39. playbtn = (Button) this.findViewById(R.id.button2);

  40. clobtn = (Button) this.findViewById(R.id.button3);

  41. videoRecorder = new MediaRecorder();

  42. surfaceView = (SurfaceView) this.findViewById(R.id.surfaceView1);

  43. surfaceHolder = surfaceView.getHolder();

  44. surfaceHolder.addCallback(new SurfaceHolder.Callback() {


  45. @Override

  46. public void surfaceDestroyed(SurfaceHolder holder) {

  47. // TODO Auto-generated method stub

  48. Log.i("camera", "surface destroyed.");

  49. surfaceHolder = null;

  50. stopRecording();

  51. releaseCamera();

  52. }


  53. @Override

  54. public void surfaceCreated(SurfaceHolder holder) {

  55. // TODO Auto-generated method stub

  56. Log.i("camera", "surface destroyed");

  57. surfaceHolder = holder;

  58. }


  59. @Override

  60. public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

  61. // TODO Auto-generated method stub

  62. Log.i("camera", "surface changed.");

  63. surfaceHolder = holder;

  64. }

  65. });

  66. opbtn.setOnClickListener(new OnClickListener() {

  67. @Override

  68. public void onClick(View argO) {

  69. // TODO Auto-generated method stub

  70. openCamera();

  71. }

  72. });

  73. playbtn.setOnClickListener(new OnClickListener() {

  74. @Override

  75. public void onClick(View v) {

  76. // TODO Auto-generated method stub

  77. benginRecording();

  78. }

  79. });

  80. clobtn.setOnClickListener(new OnClickListener() {

  81. @Override

  82. public void onClick(View v) {

  83. // TODO Auto-generated method stub

  84. stopRecording();

  85. }

  86. });

  87. }


  88. @Override

  89. protected void onPause() {

  90. // TODO Auto-generated method stub

  91. super.onPause();

  92. stopRecording();

  93. releaseCamera();

  94. }


  95. protected void stopRecording() {

  96. // TODO Auto-generated method stub

  97. Log.i("videoRecorder", "stopRecording...");

  98. if (videoRecorder != null) {

  99. videoRecorder.stop();

  100. videoRecorder.reset();

  101. videoRecorder.release();

  102. videoRecorder = null;

  103. camera.lock();

  104. }

  105. }


  106. private void releaseCamera() {

  107. if (camera != null) {

  108. camera.release();

  109. camera = null;

  110. }

  111. }


  112. protected void benginRecording() {

  113. Log.i("videoRecorder", "beginRecording");

  114. //给摄像头解锁

  115. camera.unlock();

  116. //MediaRecorder获取到摄像头的访问权

  117. videoRecorder.setCamera(camera);

  118. //设置视频录制过程中所录制的音频来自手机的麦克风

  119. videoRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);

  120. //设置视频源为摄像头

  121. videoRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

  122. //设置视频录制的输出文件为3gp文件

  123. videoRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);

  124. //设置音频编码方式为AAC

  125. videoRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

  126. //设置录制的视频编码为H.264

  127. videoRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

  128. videoRecorder.setVideoSize(176, 144);

  129. videoRecorder.setVideoFrameRate(20);

  130. if (!checkSDCard()) {

  131. Log.e("videoRecorder", "未找到SD卡!");

  132. return;

  133. }

  134. videoRecorder.setOutputFile(myVideofilepath);

  135. videoRecorder.setPreviewDisplay(surfaceHolder.getSurface());

  136. try {

  137. videoRecorder.prepare();

  138. } catch (IllegalStateException e) {

  139. // TODO Auto-generated catch block

  140. e.printStackTrace();

  141. } catch (IOException e) {

  142. // TODO Auto-generated catch block

  143. e.printStackTrace();

  144. }

  145. videoRecorder.start();

  146. }


  147. private void openCamera() {


  148. // TODO Auto-generated method stub

  149. Log.i("videoRecorder", "openCamera.");

  150. try {

  151. camera = Camera.open(); // attempt to get a Camera instance

  152. } catch (Exception e) {

  153. // Camera is not available (in use or does not exist)

  154. Log.e("camera", "open camera error!");

  155. e.printStackTrace();

  156. return;

  157. }


  158. try {

  159. camera.setPreviewDisplay(surfaceHolder);

  160. } catch (IOException e) {

  161. // TODO Auto-generated catch block

  162. Log.e("camera", "preview failed.");

  163. e.printStackTrace();

  164. }

  165. camera.startPreview();

  166. }


  167. private boolean checkSDCard() {

  168. // 判断SD存储卡是否存在

  169. if (android.os.Environment.getExternalStorageState().equals(

  170. android.os.Environment.MEDIA_MOUNTED)) {

  171. return true;

  172. } else {

  173. return false;

  174. }

  175. }

  176. }

该实例中,在对 MediaRecorder 进行设置时,没有使用:

videoRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));

而是使用以下代码对 MediaRecorder 进行设置:

  1. //设置视频录制的输出文件为3gp文件

  2. videoRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);

  3. //设置音频编码方式为AAC

  4. videoRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

  5. //设置录制的视频编码为H.264

  6. videoRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

  7. //设置视频录制的分辨率,必须放在设置编码和格式的后面,否则报错

  8. videoRecorder.setVideoSize(176, 144);

  9. //设置录制的视频的视频帧率,必须放在设置编码和格式的后面,否则报错

  10. videoRecorder.setVideoFrameRate(20);


特别声明:
1、如无特殊说明,内容均为本站原创发布,转载请注明出处;
2、部分转载文章已注明出处,转载目的为学习和交流,如有侵犯,请联系客服删除;
3、编辑非《源码码网》的文章均由用户编辑发布,不代表本站立场,如涉及侵犯,请联系删除;
全部评论(0)
推荐阅读
  • bootstrap ui框架能用在uniapp中吗?
  • bootstrap ui框架能用在uniapp中吗?
  • BootstrapUI框架通常是前端开发中的一种工具,它提供了一套预定义的CSS样式和组件,用于快速构建响应式布局的网页。然而,UniApp是一个使用Vue.js开发跨平台应用的框架,它可以用来开发iOS、Android、以及各种小程序和H5应用。
  • 互动社区
  • 来源:源码码网
  • 编辑:热度建站
  • 时间:2024-04-12 00:04
  • 阅读:175
  • css实现banner图由中心点动态放大效果
  • css实现banner图由中心点动态放大效果
  • 在日常的网页设计中,为了让网页增加一定的特效以达到交互的目的,我们尝尝会在网页中使用一些动画效果。今天来说说实现banner图由中心点动态放大效果,实现这个效果需要用到css中的动画:animation​和关键帧:@keyframes,具体示例如下:
  • 源码教程
  • 来源:源码码网
  • 编辑:源码码网
  • 时间:2024-04-11 18:52
  • 阅读:189
  • countUp.js实现鼠标滑动到某个位置数字自动滚动增加的效果
  • countUp.js实现鼠标滑动到某个位置数字自动滚动增加的效果
  • 在网页开发中为了提升网页的交互效果,经常会用到使用js给网页增加一定的特效,下边就来说说使用js实现鼠标滑动到某个位置数字自动滚动增加的效果。其实这种效果有很多中解决办法,自己也可以去写,下边我们借助countUp.js来实现,关于这个js文件,我放在末尾:
  • 源码教程
  • 来源:源码码网
  • 编辑:源码码网
  • 时间:2024-04-08 09:20
  • 阅读:265
  • 响应式网页设计思路及注意事项
  • 响应式网页设计思路及注意事项
  • 一、什么是响应式网页响应式网页设计就是让网页具有根据设备类型应用CSS样式的能力。设计:设想、计划。设计就是把想法实现。网页设计:按照一定的设计思路布局网页内容。传统网页设计:都是针对PC端浏览器而设计的,不具备查询设备的能力,更不能对多种访问设备做出响应。传统网页设计的弊端:在移动互联网时代,传统的网页设计不适合多屏幕时代。响应式网页设计应运而生。响应式网页设计是一种设计网页的思想/方法。响应:指让我们的网页能够自动查询用户的访问设备
  • 源码教程
  • 来源:源码码网
  • 编辑:源码码网
  • 时间:2024-04-02 11:24
  • 阅读:172
  • css中rel的属性值都有哪些,分别代表什么意思
  • css中rel的属性值都有哪些,分别代表什么意思
  • 在HTML中,元素的rel属性用于定义当前文档与被链接文档之间的关系。这个属性在CSS的上下文中经常与样式表关联,但rel属性的用途远不止于此。以下是一些常见的rel属性值及其意义:1、stylesheet:表示被链接的文档是一个样式表。这通常用于链接CSS文件。
  • 源码教程
  • 来源:源码码网
  • 编辑:源码码网
  • 时间:2024-03-28 12:28
  • 阅读:302
联系客服
源码代售 源码咨询 素材咨询 联系客服
029-84538663
手机版

扫一扫进手机版
返回顶部