zoukankan      html  css  js  c++  java
  • 【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
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    ios -- 教你如何轻松学习Swift语法(一)
    collectionView,tableView的细节处理
    主流界面搭建原理(类似百思不得姐主界面)
    ios--时间格式化(cell业务逻辑处理)
    test
    Mac下安装Matlab R2015b
    最大奇约数
    编码问题
    最优二叉查找树
    二维数组和二级指针
  • 原文地址:https://www.cnblogs.com/skyseraph/p/2387417.html
Copyright © 2011-2022 走看看