Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發之打開閃光燈錄制視頻

Android開發之打開閃光燈錄制視頻

編輯:關於Android編程

Android的SDK在線API上對錄制視頻的方法、步驟都寫得非常清楚,但是如果沒有一點思路,寫起來也比較式費事。錄制視頻的全過程要打開閃光燈(可能是因為項目需要,或者特殊原因),則必須按照一定的順序進行開關,畢竟容易出錯。要實現錄制的同時開啟閃光燈也不難,官方API給出了一個大體的步驟.因為要采集點視頻數據,臨時寫了個簡單的Demo學習下,必要時再深度開發。     首先在工程中的AndroidManifest.xml中添加權限聲明,因為要使用到攝像頭,故需要添加Camera的相關權限,另外還需要寫SD卡的權限,如果同時需要錄制音頻,則還需要添加RECORD_AUDIO權限。   1 <uses-permission android:name="android.permission.CAMERA" /> 2 <uses-feature android:name="android.hardware.camera" /> 3 <uses-feature android:name="android.hardware.camera.autofocus" /> 4 <uses-permission android:name="android.permission.RECORD_AUDIO"/> 5 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />   再來分析下要使用到的類,錄制視頻使用的MediaRecorder類,官方給出了調用MediaRecorder錄制視頻的一個簡單狀態機,展示了各個狀態之間的轉化。然後也給出了一個簡單的調用方法,代碼如下:            View Code     錄制視頻是調用MediaRecorder類,但API中真正介紹如何錄制視頻的一般步驟卻被放在了Camera類中,在線API上有句話提示“For more information about how to use MediaRecorder for recording video, read the Camera developer guide.”。轉到Camera類去看看。     Camera類是用來控制照相機的,沒錯,就是這個類。照相機可以用來拍照,也可以用來錄制視頻(也叫捕捉視頻),但是錄制視頻需要按照一定的步驟來編寫程序,不然發生運行時錯誤是非常正常的。錄制視頻需要調用Camera和MediaRecorder類,下面說說一般步驟。     1) 打開照相機。直接調用Camera.open()來獲取一個Camera的實例。     2) 設置預覽控件。一般是設置在SurfaceView上面,通過調用Camera.setPreviewDisplay()來完成,但是這一步也可以放到MediaRecorder類DataSourceConfigured步驟中完成。     3) 開啟預覽。調用Camera.startPreview()。     4) 開始錄制視頻。為了確保你錄制成功,請務必按要求完成下面的步驟。       A. 解鎖照相機。通過調用Camera.unlock()解鎖照相機,以便照相機被MediaRecorder使用。       B. 設置MediaRecorder。         這裡有一系列的設置,根據需要設置吧。比如說,你只需要錄制視頻,就不必設置音頻的輸入源,也就不用設置音頻的編碼方式。對應於MediaRecorder state diagram中的Initialized和DataSourceConfigured。具體方法調用可以查看Android在線API的MediaRecorder類,上文已經將主要的代碼貼出,下文還會貼出實例代碼,這裡就不詳細介紹了。       C. 准備MediaRecorder。在調用MediaRecorder.prepare()之前一定要先設置好MediaRecorder對象的各項屬性,後面設置會引發運行時錯誤。       D. 開始MediaRecorder。調用MediaRecorder.start()之後,就開始錄制視頻了。     5) 停止錄制。       A. 停止MediaRecorder。調用MediaRecorder.stop()停止錄制。       B. 恢復MediaRecorder的默認設置。調用MediaRecorder.reset()來取消你對MediaRecorder所做的設置,但調用玩之後,MediaRecorder對象還是可以再次使用的。       C. 釋放MediaRecorder對象。調用MediaRecorder.release()釋放資源,之後該MediaRecorder對象銷毀了,再調用會出錯。       D. 給Camera上鎖。為了後面的MediaRecorder對象可以再次使用,需要調用Camera.lock(),Android 4.0以後,這個操作並不是必須的,除非MediaRecorder.prepare()調用失敗。     6) 停止預覽,調用Camera.stopPreview()。     7) 釋放照相機資源,調用Camera.release()。     以上就是打開照相機錄制視頻的一般步驟,當然你可以可以在錄制之前實現預覽,決定什麼時間開始錄制,這個其實可以先開啟照相機進行預覽即可然後,需要錄制時調用Camera.unlock(),然後按流程接入MediaRecorder進行錄制。現在考慮第一種情況,直接開始錄制。     權限要求已經貼出來了,再貼個布局文件,recordvideo.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:background="#ffffff"  6     android:orientation="vertical" >  7   8     <SurfaceView  9         android:id="@+id/surfaceView" 10         android:layout_width="fill_parent" 11         android:layout_height="220dip" /> 12  13     <LinearLayout 14         android:layout_width="fill_parent" 15         android:layout_height="wrap_content" 16         android:layout_marginLeft="5dp" 17         android:layout_marginRight="5dp" 18         android:layout_marginTop="20dp" 19         android:gravity="right" 20         android:orientation="horizontal" > 21  22         <EditText 23             android:id="@+id/rv_testusername" 24             android:layout_width="156dp" 25             android:layout_height="wrap_content" 26             android:layout_weight="0.27" 27             android:ems="10" 28             android:hint="輸入姓名或標識" /> 29  30         <Button 31             android:id="@+id/rv_record" 32             style="@style/mainactivitybtnstyle" 33             android:layout_width="wrap_content" 34             android:layout_height="wrap_content" 35             android:minHeight="40dp" 36             android:minWidth="70dp" 37             android:text="錄制" /> 38  39         <Button 40             android:id="@+id/rv_stop" 41             style="@style/mainactivitybtnstyle" 42             android:layout_width="wrap_content" 43             android:layout_height="wrap_content" 44             android:layout_marginLeft="10dip" 45             android:minHeight="40dp" 46             android:minWidth="70dp" 47             android:text="停止" /> 48     </LinearLayout> 49  50     <LinearLayout 51         android:layout_width="fill_parent" 52         android:layout_height="fill_parent" 53         android:gravity="center_horizontal" 54         android:orientation="vertical" > 55  56         <ProgressBar 57             android:id="@+id/rv_schedule" 58             style="?android:attr/progressBarStyleHorizontal" 59             android:layout_width="fill_parent" 60             android:layout_height="wrap_content" /> 61  62         <TextView 63             android:id="@+id/rv_record_time" 64             android:layout_width="fill_parent" 65             android:layout_height="wrap_content" 66             android:gravity="center" 67             android:text="00:00:000" 68             android:textColor="#FF750000" 69             android:textSize="24sp" 70             android:textStyle="bold" /> 71     </LinearLayout> 72  73 </LinearLayout> 復制代碼        Activity代碼,因為非常簡單,就沒有封裝多線程什麼的。     復制代碼   1 package com.ict.phonedoctor.camerasign;   2    3 import java.io.File;   4 import java.text.SimpleDateFormat;   5    6 import android.content.Context;   7 import android.content.pm.FeatureInfo;   8 import android.content.pm.PackageManager;   9 import android.hardware.Camera;  10 import android.media.MediaRecorder;  11 import android.os.Bundle;  12 import android.os.Environment;  13 import android.os.Handler;  14 import android.os.Message;  15 import android.support.v7.app.ActionBarActivity;  16 import android.util.Log;  17 import android.view.SurfaceHolder;  18 import android.view.SurfaceView;  19 import android.view.View;  20 import android.widget.Button;  21 import android.widget.EditText;  22 import android.widget.ProgressBar;  23 import android.widget.TextView;  24 import android.widget.Toast;  25   26 import com.ict.phonedoctor.R;  27 import com.ict.util.IOUtil;  28   29 public class RecordVideoActivity extends ActionBarActivity {  30     private static final String TAG = "RecordVideo";  31     private SurfaceView surfaceView;  32     private MediaRecorder mediaRecorder;  33     private boolean record;      34     private TextView testusername;  35     private Camera camera;  36       37     // 計時器相關  38     private MyChronograph myChronograph;  39     private TextView chronograph = null;  40       41     private ProgressBar schedule;  42     private boolean recordOver = false;  43       44     @Override  45     protected void onCreate(Bundle savedInstanceState) {  46         // TODO Auto-generated method stub  47         super.onCreate(savedInstanceState);  48         setContentView(R.layout.recordvideo);  49         setTitle("錄制視頻");  50         mediaRecorder = new MediaRecorder();  51         surfaceView = (SurfaceView) this.findViewById(R.id.surfaceView);  52         this.surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  53         this.surfaceView.getHolder().setFixedSize(320, 240);//設置分辨率  54   55         testusername = (EditText)findViewById(R.id.rv_testusername);  56         chronograph = (TextView)findViewById(R.id.rv_record_time);  57         schedule = (ProgressBar)findViewById(R.id.rv_schedule);  58         schedule.setMax(60);  59         ButtonClickListener listener = new ButtonClickListener();  60         Button stopButton = (Button) this.findViewById(R.id.rv_stop);  61         Button recordButton = (Button) this.findViewById(R.id.rv_record);  62         stopButton.setOnClickListener(listener);  63         recordButton.setOnClickListener(listener);             64     }  65   66     @Override  67     protected void onDestroy() {  68         // TODO Auto-generated method stub  69         if(mediaRecorder!=null)  70             mediaRecorder.release();  71         super.onDestroy();  72     }  73   74     @Override  75     protected void onPause() {  76         // TODO Auto-generated method stub  77         super.onPause();  78     }  79   80     @Override  81     protected void onResume() {  82         // TODO Auto-generated method stub  83         super.onResume();  84     }  85     private final class ButtonClickListener implements View.OnClickListener{  86         @Override  87         public void onClick(View v) {  88             if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){  89                 Toast.makeText(RecordVideoActivity.this, "木有檢測到SD擴展卡", 1).show();  90                 return ;  91             }  92             try {  93                 switch (v.getId()) {  94                 case R.id.rv_record:  95                     // 要求輸入用戶名  96                     String testuser;  97                     if(testusername.getText()==null || testusername.getText().toString().equals("")){  98                         Toast.makeText(RecordVideoActivity.this, "請輸入測試者姓名", Toast.LENGTH_LONG).show();  99                         return; 100                     } 101                     Log.i(TAG,"檢測通過"); 102                     recordOver = false; 103                     testuser = testusername.getText().toString(); 104                     testuser = android.os.Build.MODEL + "-" + testuser; 105                     mediaRecorder.reset(); 106                     if(isSurportFlashlight(RecordVideoActivity.this)){ 107                         if (camera == null) 108                             camera = Camera.open(); 109                         Camera.Parameters myParameters = camera.getParameters(); 110                         myParameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); 111                         camera.setParameters(myParameters); 112                         camera.startPreview(); 113                         camera.unlock(); 114                         mediaRecorder.setCamera(camera); 115                     }                     116                     mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 117                     //mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);  118                     mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 119                     mediaRecorder.setVideoSize(320, 240); 120                     mediaRecorder.setVideoFrameRate(30); //每秒30幀 121                     mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);  122                     //mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 123                     SimpleDateFormat ff = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); 124                     String recordTimeString = String.valueOf(ff.format(System.currentTimeMillis()));                     125                     File videoFile = IOUtil.CreateNewFile(Environment.getExternalStorageDirectory().getPath()+"/phonedoctor/video", 126                             testuser + "-" + recordTimeString+".3gp",null); 127                     mediaRecorder.setOutputFile(videoFile.getAbsolutePath()); 128                     mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface()); 129                     mediaRecorder.prepare(); 130                     mediaRecorder.start();    //    開始錄制 131                     // 開啟計時線程 132                     myChronograph = new MyChronograph(mHandler,60000); 133                     myChronograph.start(); 134                     Toast.makeText(RecordVideoActivity.this, "開始錄制視頻!", Toast.LENGTH_SHORT).show(); 135                     record = true; 136                     ((Button)findViewById(R.id.rv_record)).setEnabled(false); 137                     break; 138  139                 case R.id.rv_stop: 140                     if(record){ 141                         record = false; 142                         mediaRecorder.stop(); 143                         mediaRecorder.reset(); 144                         Log.i(TAG,"TAG-1"); 145                         if(camera!=null){ 146                             camera.lock(); 147                             camera.stopPreview(); 148                             Camera.Parameters myParameters = camera.getParameters(); 149                             myParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); 150                             camera.setParameters(myParameters); 151                             camera.release(); 152                             camera = null; 153                         } 154                         // 秒表線程控制         155                         if(myChronograph!=null){ 156                             myChronograph.exit(); 157                             myChronograph = null; 158                         } 159                         ((Button)findViewById(R.id.rv_record)).setEnabled(true); 160                     } 161                     break; 162                 } 163             } catch (Exception e) { 164                 Toast.makeText(RecordVideoActivity.this, "發生異常", 1).show(); 165                 e.printStackTrace(); 166             } 167         } 168          169     } 170      171     private Handler mHandler = new Handler(){ 172  173         @Override 174         public void handleMessage(Message msg) { 175             String[] strMsg; 176             switch (msg.what) { 177             case MsgNumber.UPTIME_UI: 178                 strMsg = (String[]) msg.obj; 179                 chronograph.setText(strMsg[0]); 180                 if(!recordOver){ 181                     int percent = Integer.parseInt(strMsg[1]); 182                     if(percent==-1){ 183                         recordOver = true; 184                         schedule.setProgress(60); 185                         Toast.makeText(RecordVideoActivity.this, "已錄制一分鐘!", Toast.LENGTH_SHORT).show(); 186                         return; 187                     } 188                     percent = percent>60?60:percent; 189                     schedule.setProgress(percent); 190                 } 191                 break; 192  193             default: 194                 break; 195             } 196         } 197          198     }; 199      200     // 閃光燈判斷 201     public boolean isSurportFlashlight(Context context) { 202         boolean flag = false; 203         PackageManager pm = context.getPackageManager(); 204         FeatureInfo[] features = pm.getSystemAvailableFeatures(); 205         for (FeatureInfo f : features) { 206             if (PackageManager.FEATURE_CAMERA_FLASH.equals(f.name)) { 207                 flag = true; 208                 break; 209             } 210         } 211         return flag; 212     } 213 }
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved