【Android學習專題】多媒體篇:MediaRecoder 实现录像机

 


 

【Android學習專題】多媒體篇:MediaRecoder 实现录像机

   SkySeraph Feb 9th 2012  SZ

Email:skyseraph00@163.com 

 


啰嗦:前一篇介绍了MediaRecoder实现的录音机:【Android學習專題】多媒體篇:MediaRecorder 实现录音机 ,这篇介绍录像机的实现。

 


录像界面


关键步骤

开始录像

录像结束

返回 

屏幕下方计时实现 

 


完整源码

JAVA源码

  1 public class mediarecorder2 extends Activity implements SurfaceHolder.Callback
2 {
3 private Button mVideoStartBtn,mVideoStopBtn,mVideoReturnBtn;
4 private SurfaceView mSurfaceview; // 显示视频的控件
5 private MediaRecorder mMediaRecorder; // MediaRecorder对象,錄製視頻的類
6 private SurfaceHolder mSurfaceHolder; //
7 private File mRecVedioPath; // 录制的音視頻文件路徑
8 private File mRecAudioFile; // 录制的音視頻文件
9 private TextView tv01,tv02,tv03,tv04,tv05;
10 private int hour = 0;
11 private int minute = 0;
12 private int second = 0;
13 private boolean bool;
14
15 @Override
16 protected void onCreate(Bundle savedInstanceState)
17 {
18 super.onCreate(savedInstanceState);
19 /* 全局Activity设置 */
20 // 隐去Title(程序的名字)
21 this.requestWindowFeature(Window.FEATURE_NO_TITLE);
22 // 設置全屏:隐去电池等图标和一切修饰部分(状态栏部分)
23 this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
24 WindowManager.LayoutParams.FLAG_FULLSCREEN);
25 // 选择支持半透明模式,在有surfaceview的activity中使用。
26 getWindow().setFormat(PixelFormat.TRANSLUCENT);
27 setContentView(R.layout.mymultimedia_mediarecorder2);
28
29 tv01 = (TextView) findViewById(R.id.mediarecorder2_TextView01);
30 tv02 = (TextView) findViewById(R.id.mediarecorder2_TextView02);
31 tv03 = (TextView) findViewById(R.id.mediarecorder2_TextView03);
32 tv04 = (TextView) findViewById(R.id.mediarecorder2_TextView04);
33 tv05 = (TextView) findViewById(R.id.mediarecorder2_TextView05);
34 mVideoStartBtn = (Button) findViewById(R.id.mediarecorder2_VideoStartBtn);
35 mVideoStopBtn = (Button) findViewById(R.id.mediarecorder2_VideoStopBtn);
36 mVideoReturnBtn = (Button) findViewById(R.id.mediarecorder2_VideoReturnBtn);
37 mSurfaceview = (SurfaceView) this.findViewById(R.id.mediarecorder2_Surfaceview);
38
39 //设置TextView不可见
40 tv01.setVisibility(View.GONE);
41 tv02.setVisibility(View.GONE);
42 tv03.setVisibility(View.GONE);
43 tv04.setVisibility(View.GONE);
44 tv05.setVisibility(View.GONE);
45
46 /* 检测是否存在SD卡 */
47 if (Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
48 {
49 mRecVedioPath = Environment.getExternalStorageDirectory();// 得到SD卡得路径
50 } else
51 {
52 Toast.makeText(mediarecorder2.this, "没有SD卡", Toast.LENGTH_LONG).show();
53 }
54
55 //
56 SurfaceHolder holder = mSurfaceview.getHolder(); // 取得holder
57 holder.addCallback(mediarecorder2.this); // holder加入回调接口
58 holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// 設置顯示器類型,setType必须设置
59
60 // 按钮状态
61 mVideoStartBtn.setEnabled(true);
62 mVideoStopBtn.setEnabled(false);
63
64 // 開始
65 mVideoStartBtn.setOnClickListener(new Button.OnClickListener()
66 {
67 @Override
68 public void onClick(View v)
69 {
70 bool = true;
71 /* ①Initial:实例化MediaRecorder对象 */
72 if(mMediaRecorder == null)
73 mMediaRecorder = new MediaRecorder();
74 else
75 mMediaRecorder.reset();
76 /* 解決豎屏視頻被旋轉90°的錯誤
77 Camera c = Camera.open();
78 Camera.Parameters parameters = c.getParameters();
79 parameters.setRotation(90);
80 c.setParameters(parameters);
81 c.unlock();
82 mMediaRecorder.setCamera(c);*/
83 // 預覽
84 mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
85 /* ②setAudioSource/setVedioSource */
86 mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);// 设置Camera(相机)
87 mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
88 /* ②设置錄製視頻输出格式:THREE_GPP/MPEG-4/RAW_AMR/Default
89 * THREE_GPP(3gp格式,H263视频ARM音频编码)、MPEG-4、RAW_AMR(只支持音频且音频编码要求为AMR_NB)*/
90 mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
91 /* ②设置視頻/音频文件的编码:AAC/AMR_NB/AMR_MB/Default */
92 mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
93 mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
94 /* ②设置视频录制的分辨率。必须放在设置编码和格式的后面,否则报错 */
95 mMediaRecorder.setVideoSize(176, 144);
96 /* ②设置录制的视频帧率。必须放在设置编码和格式的后面,否则报错 */
97 mMediaRecorder.setVideoFrameRate(15);
98 /* ②设置输出文件的路径 */
99 try
100 {
101 mRecAudioFile = File.createTempFile("Vedio",".3gp",mRecVedioPath);
102 } catch (IOException e1)
103 {
104 // TODO Auto-generated catch block
105 e1.printStackTrace();
106 }
107 mMediaRecorder.setOutputFile(mRecAudioFile.getAbsolutePath());
108 try
109 {
110 /* ③准备 */
111 mMediaRecorder.prepare();
112 tv01.setVisibility(View.VISIBLE);
113 tv02.setVisibility(View.VISIBLE);
114 tv03.setVisibility(View.VISIBLE);
115 tv04.setVisibility(View.VISIBLE);
116 tv05.setVisibility(View.VISIBLE);
117 handler.postDelayed(task, 1000);
118 /* ④开始 */
119 mMediaRecorder.start();
120 /* 按钮状态 */
121 mVideoStartBtn.setEnabled(false);
122 mVideoStopBtn.setEnabled(true);
123 mVideoReturnBtn.setEnabled(true);
124 } catch (Exception e)
125 {
126 e.printStackTrace();
127 }
128 }
129 });
130 // 結束
131 mVideoStopBtn.setOnClickListener(new Button.OnClickListener()
132 {
133 @Override
134 public void onClick(View v)
135 {
136 if (mMediaRecorder != null)
137 {
138 /* ⑤停止录音 */
139 mMediaRecorder.stop();
140 bool = false;
141 tv01.setText(format(hour));
142 tv03.setText(format(minute));
143 tv05.setText(format(second));
144 /* ⑥释放MediaRecorder */
145 mMediaRecorder.release();
146 mMediaRecorder = null;
147 /* 按钮状态 */
148 mVideoStartBtn.setEnabled(true);
149 mVideoStopBtn.setEnabled(false);
150 mVideoReturnBtn.setEnabled(true);
151 }
152 }
153 });
154 // 返回
155 mVideoReturnBtn.setOnClickListener(new Button.OnClickListener()
156 {
157 @Override
158 public void onClick(View v)
159 {
160 if(mMediaRecorder != null)
161 {
162 mMediaRecorder.stop();
163 mMediaRecorder.release();
164 mMediaRecorder = null;
165 }
166 finish();
167 }
168 });
169 }
170
171 @Override
172 public void surfaceCreated(SurfaceHolder holder)
173 {
174 // TODO Auto-generated method stub
175 mSurfaceHolder = holder;
176 }
177
178 @Override
179 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
180 {
181 // TODO Auto-generated method stub
182 mSurfaceHolder = holder;
183 }
184
185 @Override
186 public void surfaceDestroyed(SurfaceHolder holder)
187 {
188 // TODO Auto-generated method stub
189 mSurfaceview = null;
190 mSurfaceHolder = null;
191 mMediaRecorder = null;
192 }
193
194
195 /*定时器设置,实现计时*/
196 private Handler handler = new Handler();
197 private Runnable task = new Runnable()
198 {
199 public void run()
200 {
201 if (bool)
202 {
203 handler.postDelayed(this, 1000);
204 second++;
205 if (second < 60)
206 {
207 tv05.setText(format(second));
208 } else if (second < 3600)
209 {
210 minute = second / 60;
211 second = second % 60;
212 tv03.setText(format(minute));
213 tv05.setText(format(second));
214 } else
215 {
216 hour = second / 3600;
217 minute = (second % 3600) / 60;
218 second = (second % 3600) % 60;
219 tv01.setText(format(hour));
220 tv03.setText(format(minute));
221 tv05.setText(format(second));
222 }
223 }
224 }
225 };
226
227 /* 格式化时间*/
228 public String format(int i)
229 {
230 String s = i + "";
231 if (s.length() == 1)
232 {
233 s = "0" + s;
234 }
235 return s;
236 }
237 }

XML布局文件

  1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 android:layout_width="fill_parent"
3 android:layout_height="fill_parent"
4 android:orientation="vertical" >
5
6 <LinearLayout
7 android:layout_width="fill_parent"
8 android:layout_height="fill_parent"
9 android:layout_weight="1" >
10
11 <SurfaceView
12 android:id="@+id/mediarecorder2_Surfaceview"
13 android:layout_width="fill_parent"
14 android:layout_height="fill_parent" />
15 </LinearLayout>
16
17 <LinearLayout
18 android:layout_width="fill_parent"
19 android:layout_height="fill_parent"
20 android:layout_weight="5"
21 android:gravity="center"
22 android:orientation="vertical" >
23
24 <AbsoluteLayout
25 android:layout_width="fill_parent"
26 android:layout_height="fill_parent"
27 android:layout_weight="2" >
28
29 <TextView
30 android:id="@+id/mediarecorder2_TextView01"
31 android:layout_width="40px"
32 android:layout_height="40px"
33 android:layout_x="5px"
34 android:layout_y="1px"
35 android:text="00"
36 android:textColor="#ffff0000"
37 android:textStyle="bold" >
38 </TextView>
39
40 <TextView
41 android:id="@+id/mediarecorder2_TextView02"
42 android:layout_width="20px"
43 android:layout_height="40px"
44 android:layout_x="25px"
45 android:layout_y="1px"
46 android:text=":"
47 android:textColor="#ffff0000"
48 android:textStyle="bold" >
49 </TextView>
50
51 <TextView
52 android:id="@+id/mediarecorder2_TextView03"
53 android:layout_width="40px"
54 android:layout_height="40px"
55 android:layout_x="35px"
56 android:layout_y="1px"
57 android:text="00"
58 android:textColor="#ffff0000"
59 android:textStyle="bold" >
60 </TextView>
61
62 <TextView
63 android:id="@+id/mediarecorder2_TextView04"
64 android:layout_width="20px"
65 android:layout_height="40px"
66 android:layout_x="55px"
67 android:layout_y="1px"
68 android:text=":"
69 android:textColor="#ffff0000"
70 android:textStyle="bold" >
71 </TextView>
72
73 <TextView
74 android:id="@+id/mediarecorder2_TextView05"
75 android:layout_width="40px"
76 android:layout_height="40px"
77 android:layout_x="65px"
78 android:layout_y="1px"
79 android:text="00"
80 android:textColor="#ffff0000"
81 android:textStyle="bold" >
82 </TextView>
83
84 <TextView
85 android:layout_width="wrap_content"
86 android:layout_height="wrap_content"
87 android:layout_x="350dp"
88 android:layout_y="1dp"
89 android:text="SkySeraph"
90 android:textColor="#ffff00"
91 android:textStyle="bold" >
92 </TextView>
93
94 </AbsoluteLayout>
95
96 <LinearLayout
97 android:layout_width="fill_parent"
98 android:layout_height="fill_parent"
99 android:layout_weight="1"
100 android:gravity="center"
101 android:orientation="horizontal" >
102
103 <Button
104 android:id="@+id/mediarecorder2_VideoStartBtn"
105 android:layout_width="fill_parent"
106 android:layout_height="fill_parent"
107 android:layout_weight="1"
108 android:background="@layout/button1"
109 android:text="Start" />
110
111 <Button
112 android:id="@+id/mediarecorder2_VideoStopBtn"
113 android:layout_width="fill_parent"
114 android:layout_height="fill_parent"
115 android:layout_weight="1"
116 android:background="@layout/button1"
117 android:text="Stop" />
118
119 <Button
120 android:id="@+id/mediarecorder2_VideoReturnBtn"
121 android:layout_width="fill_parent"
122 android:layout_height="fill_parent"
123 android:layout_weight="1"
124 android:background="@layout/button2"
125 android:text="Return" />
126 </LinearLayout>
127 </LinearLayout>
128
129 </LinearLayout>

 


Refs

1  http://developer.android.com/reference/android/media/MediaRecorder.html

2  http://blog.csdn.net/iamlazybone/article/details/5764118 

3  http://blog.sina.com.cn/s/blog_6111ce890100pouu.html

4  http://blog.csdn.net/peijiangping1989/article/details/7049991

5  http://www.codeproject.com/Articles/107270/Recording-and-Playing-Video-on-Android




作者:skyseraph
出处:http://www.cnblogs.com/skyseraph/
更多精彩请直接访问SkySeraph个人站点:http://skyseraph.com//
Email/GTalk: zgzhaobo@gmail.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文地址:https://www.cnblogs.com/skyseraph/p/2387417.html