Android开发之使用MediaRecorder录制视频



MediaRecorder类详解


手机一般都有麦克风和摄像头,而Android系统就可以利用这些硬件来录制音视频了。

为了增加对录制音视频的支持,Android系统提供了一个MediaRecorder的类。该类的使用也非常简单,下面让我们来了解一下这个类:


一、类结构:


java.lang.Object

?

android.media.MediaRecorder

二、类概述:


用于录制音频和视频的一个类。

三、状态图:


<img src="http://www.2cto.com/uploadfile/Collfiles/20140815/2014081509185897.jpg" alt="mediarecZ喎�" http:="" www.2cto.com="" kf="" ware="" vc="" "="" target="_blank" class="keylink" style="border-width: 0px; padding: 0px 0px 4px; margin: 0px; list-style: none; height: 560px; width: 504.854px;">vcmRlcl9zdGF0ZV9kaWFncmFt">

说明:

与MediaPlayer类非常相似MediaRecorder也有它自己的状态图。下面是关于MediaRecorder的各个状态的介绍:

Initial:初始状态,当使用new()方法创建一个MediaRecorder对象或者调用了reset()方法时,该MediaRecorder对象处于Initial状态。在设定视频源或者音频源之后将转换为Initialized状态。另外,在除Released状态外的其它状态通过调用reset()方法都可以使MediaRecorder进入该状态。

Initialized:已初始化状态,可以通过在Initial状态调用setAudioSource()或setVideoSource()方法进入该状态。在这个状态可以通过setOutputFormat()方法设置输出格式,此时MediaRecorder转换为DataSourceConfigured状态。另外,通过reset()方法进入Initial状态。

DataSourceConfigured:数据源配置状态,这期间可以设定编码方式、输出文件、屏幕旋转、预览显示等等。可以在Initialized状态通过setOutputFormat()方法进入该状态。另外,可以通过reset()方法回到Initial状态,或者通过prepare()方法到达Prepared状态。

Prepared:就绪状态,在DataSourceConfigured状态通过prepare()方法进入该状态。在这个状态可以通过start()进入录制状态。另外,可以通过reset()方法回到Initialized状态。

Recording:录制状态,可以在Prepared状态通过调用start()方法进入该状态。另外,它可以通过stop()方法或reset()方法回到Initial状态。

Released:释放状态(官方文档给出的词叫做Idle state 空闲状态),可以通过在Initial状态调用release()方法来进入这个状态,这时将会释放所有和MediaRecorder对象绑定的资源。

Error:错误状态,当错误发生的时候进入这个状态,它可以通过reset()方法进入Initial状态。

提示:与MediaPlayer相似使用MediaRecorder录音录像时需要严格遵守状态图说明中的函数调用先后顺序,在不同的状态调用不同的函数,否则会出现异常。

下面一个实例描述了的创建过程:

MediaRecorder recorder=newMediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(PATH_NAME);
recorder.prepare();
recorder.start(); // Recording is now started
...
recorder.stop();
recorder.reset(); // You can reuse the object by going back to setAudioSource() step
recorder.release();// Now the object cannot be reused

四、构造方法和公有方法


Public Constructors

MediaRecorder()

Default constructor.

Public Methods

final static int

getAudioSourceMax()

获取音频源的最大值。

int

getMaxAmplitude()

获取在前一次调用此方法之后录音中出现的最大振幅。

void

prepare()

准备录制。

void

release()

释放资源。

void

reset()

将MediaRecorder设为空闲状态,即Initial状态。

void

setAudioChannels(int numChannels)

设置录制的音频通道数。

void

setAudioEncoder(int audio_encoder)

设置所录制的声音的编码格式。

void

setAudioEncodingBitRate(int bitRate)

设置所录制的声音的编码位率。

void

setAudioSamplingRate(int samplingRate)

设置所录制的声音的采样率。

void

setAudioSource(int audio_source)

设置声音来源,一般传入 MediaRecorder. AudioSource.MIC参数指定录制来自麦克风的声音。

void

setCamera(Camera c)

设置一个摄像头用于录制。

void

setCaptureRate(double fps)

设置视频帧捕获率。

void

setLocation(float latitude, float longitude)

设置并存储在输出文件中的地理数据(经度和纬度)。

void

setMaxDuration(int max_duration_ms)

设置录制会话的最长持续时间(以ms为单位)。

void

setMaxFileSize(long max_filesize_bytes)

设置录制文件的最大文件大小。

void

setOnErrorListener(MediaRecorder.OnErrorListener l)

注册一个用于记录录制时出现的错误的监听器。

void

setOnInfoListener(MediaRecorder.OnInfoListener listener)

注册一个用于记录录制时出现的信息事件。

void

setOrientationHint(int degrees)

设置输出的视频播放的方向提示。

void

setOutputFile(FileDescriptor fd)

设置录制的音频文件的保存位置。

void

setOutputFile(String path)

设置录制的音频文件的保存位置。

void

setOutputFormat(int output_format)

设置所录制的音视频文件的格式。

void

setPreviewDisplay(Surface sv)

设置使用哪个SurfaceView来显示视频预览。

void

setProfile(CamcorderProfile profile)

指定CamcorderProfile对象。

void

setVideoEncoder(int video_encoder)

设置所录制视频的编码格式。

void

setVideoEncodingBitRate(int bitRate)

设置所录制视频的编码位率。

void

setVideoFrameRate(int rate)

设置录制视频的捕获帧速率。

void

setVideoSize(int width, int height)

设置要拍摄的宽度和视频的高度。

void

setVideoSource(int video_source)

设置用于录制的视频来源。

void

start()

开始录制。

void

stop()

停止录制。

五、应用实例






MediaRecorder除了可以用于录制音频,还可用于录制视频。关于MediaRecorder的详解大家可以参考《Android开发之MediaRecorder类详解》。使用MediaRecorder录制视频与录制音频的步骤基本相同。只是录制视频时不仅需要采集声音,还需要采集图像。为了让MediaRecorder录制时采集图像,应该在调用setAudioSource(int audio source)方法时再调用setVideoSource(int video source)方法来设置图像来源。

除此之外,还需在调用setOutputFormat()设置输出文件格式之后进行如下步骤:

1) 调用MediaRecorder 对象的setVideoEncoder()、setVideoEncodingBitRate(intbitRate)、setVideoFrameRate设置所录制的视频的编码格式、编码位率、每秒多少帧等,这些参数将可以控制所录制的视频的品质、文件的大小。一般来说,视频品质越好,视频文件越大。

2) 调用 MediaRecorder的setPreviewDisplay(Surfacesv)方法设置使用哪个SurfaceView来显示视频预览。

剩下的代码则与录制音频的代码基本相同:

实例使用MediaRecorder录制视频:

1.RecordVideo类:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package com.jph.recordvideo;
 
import java.io.File;
 
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.graphics.PixelFormat;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.Toast;
 
/**
  * Description:
  * 使用MediaRecorder录制视频
  * @author jph
  * Date:2014.08.14
  * <br>
  */
public class RecordVideo extends Activity
     implements OnClickListener
{
     // 程序中的两个按钮
     ImageButton record , stop;
     // 系统的视频文件
     File videoFile ;
     MediaRecorder mRecorder;
     // 显示视频预览的SurfaceView
     SurfaceView sView;
     // 记录是否正在进行录制
     private boolean isRecording = false ;
 
     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super .onCreate(savedInstanceState);
         // 去掉标题栏 ,必须放在setContentView之前
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         setContentView(R.layout.main);     
          // 设置横屏显示  
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
         // 设置全屏  
         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
                     WindowManager.LayoutParams.FLAG_FULLSCREEN);
         // 选择支持半透明模式,在有surfaceview的activity中使用。  
         getWindow().setFormat(PixelFormat.TRANSLUCENT);  
         // 获取程序界面中的两个按钮
         record = (ImageButton) findViewById(R.id.record);
         stop = (ImageButton) findViewById(R.id.stop);
         // 让stop按钮不可用。
         stop.setEnabled( false );
         // 为两个按钮的单击事件绑定监听器
         record.setOnClickListener( this );
         stop.setOnClickListener( this );
         // 获取程序界面中的SurfaceView
         sView = (SurfaceView) this .findViewById(R.id.sView);
         // 设置分辨率
         sView.getHolder().setFixedSize( 1280 , 720 );
         // 设置该组件让屏幕不会自动关闭
         sView.getHolder().setKeepScreenOn( true );
     }
 
     @Override
     public void onClick(View source)
     {
         switch (source.getId())
         {
             // 单击录制按钮
             case R.id.record:
                 if (!Environment.getExternalStorageState().equals(
                     android.os.Environment.MEDIA_MOUNTED))
                 {
                     Toast.makeText(RecordVideo. this
                         , "SD卡不存在,请插入SD卡!"
                         , Toast.LENGTH_SHORT).show();
                     return ;
                 }
                 try
                 {
                     // 创建保存录制视频的视频文件
                     videoFile = new File(Environment
                         .getExternalStorageDirectory()
                         .getCanonicalFile() + "/testvideo.3gp" );
                     // 创建MediaPlayer对象
                     mRecorder = new MediaRecorder();
                     mRecorder.reset();
                     // 设置从麦克风采集声音(或来自录像机的声音AudioSource.CAMCORDER)
                     mRecorder.setAudioSource(MediaRecorder
                         .AudioSource.MIC);
                     // 设置从摄像头采集图像
                     mRecorder.setVideoSource(MediaRecorder
                         .VideoSource.CAMERA);
                     // 设置视频文件的输出格式
                     // 必须在设置声音编码格式、图像编码格式之前设置
                     mRecorder.setOutputFormat(MediaRecorder
                         .OutputFormat.THREE_GPP);
                     // 设置声音编码的格式
                     mRecorder.setAudioEncoder(MediaRecorder
                         .AudioEncoder.AMR_NB);
                     // 设置图像编码的格式
                     mRecorder.setVideoEncoder(MediaRecorder
                         .VideoEncoder.H264);
                     mRecorder.setVideoSize( 1280 , 720 );
                     // 每秒 4帧
                     mRecorder.setVideoFrameRate( 20 );
                     mRecorder.setOutputFile(videoFile.getAbsolutePath());
                     // 指定使用SurfaceView来预览视频
                     mRecorder.setPreviewDisplay(sView
                         .getHolder().getSurface());  //①
                     mRecorder.prepare();
                     // 开始录制
                     mRecorder.start();
                     System.out.println( "---recording---" );
                     // 让record按钮不可用。
                     record.setEnabled( false );
                     // 让stop按钮可用。
                     stop.setEnabled( true );
                     isRecording = true ;
                 }
                 catch (Exception e)
                 {
                     e.printStackTrace();
                 }
                 break ;
             // 单击停止按钮
             case R.id.stop:
                 // 如果正在进行录制
                 if (isRecording)
                 {
                     // 停止录制
                     mRecorder.stop();
                     // 释放资源
                     mRecorder.release();
                     mRecorder = null ;
                     // 让record按钮可用。
                     record.setEnabled( true );
                     // 让stop按钮不可用。
                     stop.setEnabled( false );
                 }
                 break ;
         }
     }
}


2.布局文件:

?
1
2
3
4
5
6
7
8
9
<!--?xml version= "1.0" encoding= "utf-8" ?-->
<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android" android:orientation= "vertical" android:layout_width= "match_parent" android:layout_height= "match_parent" >
     <!-- 显示视频预览的SurfaceView -->
     <surfaceview android:id= "@+id/sView" android:layout_width= "match_parent" android:layout_height= "match_parent" >
     <linearlayout android:orientation= "horizontal" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:gravity= "center_horizontal" android:layout_alignparentbottom= "true" android:layout_centerhorizontal= "true" >
         <imagebutton android:id= "@+id/record" android:layout_width= "66dp" android:layout_height= "66dp" android:scaletype= "fitCenter" android:src= "@drawable/recored" >
         <imagebutton android:id= "@+id/stop" android:layout_width= "66dp" android:layout_height= "66dp" android:scaletype= "fitCenter" android:src= "@drawable/stop" >
     </imagebutton></imagebutton></linearlayout>
</surfaceview></relativelayout>

3.为程序添加相应权限:

?
1
2
3
4
5
6
7
<!-- 授予该程序录制声音的权限 -->
     <uses-permission android:name= "android.permission.RECORD_AUDIO" >
     <!-- 授予该程序使用摄像头的权限 --> 
     <uses-permission android:name= "android.permission.CAMERA" >
     <uses-permission android:name= "android.permission.MOUNT_UNMOUNT_FILESYSTEMS" >
     <!-- 授予使用外部存储器的权限 -->
     <uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE" ></uses-permission></uses-permission></uses-permission></uses-permission>

4.程序运行预览:





为了在 Android 应用中录制声音,Android提供了 MediaRecorder 类,关于MediaRecorder的详解大家可以参考《Android开发之MediaRecorder类详解》。

使用MediaRecorder录制声音的步骤:

1) 创建 MediaRecorder 对象。

2) 调用MediaRecorder对象的setAudioSource()方法设置声音来源,一般传入 MediaRecorder. AudioSource.MIC参数指定录制来自麦克风的声音。

3) 调用MediaRecorder对象的setOutputFormat()设置所录制的音频文件的格式

4) 调用MediaRecorder 对象的setAudioEncoder()、setAudioEncodingBitRate(intbitRate)、 setAudioSamplingRate(int samplingRate)设置所录制的声音的编码格式编码位率采样率等, 这些参数将可以控制所录制的声音的品质、文件的大小。一般来说,声音品质越好,声音文件越大。

5) 调用MediaRecorder的setOutputFile(Stringpath)方法设置录制的音频文件的保存位置

6) 调用MediaRecorder的prepare()方法准备录制

7) 调用MediaRecorder对象的start()方法开始录制

8) 录制完成,调用MediaRecorder对象的stop()方法停止录制,并调用release()方法释放资源

提示:1.上面的步骤中第3和第4两个步骤千万不能搞反,否则程序将会抛出lllegalStateException 异常。

2. 设置声音编码格式要和声音的输出格式相对应,不然录制的音频文件不标准。如果编码格式和输出格式不对应,录制出的音频文件虽然可以播放,但是将多个这类音频文件合并之后,会出现只播放合并文件中的部分文件。

应用实例

使用MediaRecorder录制声音:

实例代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<span style= "font-size:18px;" > package com.jph.recordsound;
 
import java.io.File;
import org.crazyit.sound.R;
import android.app.Activity;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.Toast;
 
 
public class RecordSound extends Activity
     implements OnClickListener
{
     // 定义界面上的两个按钮
     ImageButton record, stop;
     // 系统的音频文件
     File soundFile;
     MediaRecorder mRecorder;
 
     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.main);
         // 获取程序界面中的两个按钮
         record = (ImageButton) findViewById(R.id.record);
         stop = (ImageButton) findViewById(R.id.stop);
         // 为两个按钮的单击事件绑定监听器
         record.setOnClickListener( this );
         stop.setOnClickListener( this );
     }
 
     @Override
     public void onDestroy()
     {
         if (soundFile != null && soundFile.exists())
         {
             // 停止录音
             mRecorder.stop();
             // 释放资源
             mRecorder.release();
             mRecorder = null ;
         }
         super .onDestroy();
     }
 
     @Override
     public void onClick(View source)
     {
         switch (source.getId())
         {
         // 单击录音按钮
             case R.id.record:
                 if (!Environment.getExternalStorageState().equals(
                     android.os.Environment.MEDIA_MOUNTED))
                 {
                     Toast.makeText(RecordSound. this , "SD卡不存在,请插入SD卡!" ,
                         Toast.LENGTH_SHORT).show();
                     return ;
                 }
                 try
                 {
                     // 创建保存录音的音频文件
                     soundFile = new File(Environment
                         .getExternalStorageDirectory().getCanonicalFile()
                         + "/sound.amr" );
                     mRecorder = new MediaRecorder();
                     // 设置录音的声音来源
                     mRecorder.setAudioSource(MediaRecorder
                         .AudioSource.MIC);
                     // 设置录制的声音的输出格式(必须在设置声音编码格式之前设置)
                     mRecorder.setOutputFormat(MediaRecorder
                         .OutputFormat.AMR_NB);
                     // 设置声音编码的格式
                     mRecorder.setAudioEncoder(MediaRecorder
                         .AudioEncoder.AMR_NB);
                     mRecorder.setOutputFile(soundFile.getAbsolutePath());
                     mRecorder.prepare();
                     // 开始录音
                     mRecorder.start();  //①
                 }
                 catch (Exception e)
                 {
                     e.printStackTrace();
                 }
                 break ;
             // 单击停止按钮
             case R.id.stop:
                 if (soundFile != null && soundFile.exists())
                 {
                     // 停止录音
                     mRecorder.stop();  //②
                     // 释放资源
                     mRecorder.release();  //③
                     mRecorder = null ;
                 }
                 break ;
         }
     }
}</span>

程序运行效果图:








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值