国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android仿微信錄制小視頻

2019-10-22 18:11:54
字體:
來源:轉載
供稿:網友

本文實例為大家分享了Android仿微信錄制小視頻的具體代碼,供大家參考,具體內容如下

先上張圖片看看效果

Android,微信,錄制,小視頻

簡單敘述下

  • 首先通過Camera類調用系統相機
  • 通過surfaceview繪制出來
  • 通過MediaRecorder來錄制視頻
  • 閃光燈 和 切換攝像頭 需要重新配置Camera的參數
  • Camera預覽界面畫面拉升的原因是因為Surfaceview的大小與設定的比例不一致的

**本次版本更新了 切換前置攝像頭錄制視頻問題
Android部分手機錄制視頻適配IOS手機問題 (OPPO手機部分不適配 目前啟用的H264格式)**

完整的代碼

 

import android.app.Activity;import android.content.Intent;import android.graphics.Bitmap;import android.hardware.Camera;import android.media.MediaMetadataRetriever;import android.media.MediaRecorder;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.view.KeyEvent;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.view.ViewGroup;import android.widget.Button;import android.widget.ImageView;import android.widget.ProgressBar;import android.widget.TextView;import android.widget.Toast;import com.tongxun.atongmu.dialog.CommonDialog;import java.io.File;import java.io.IOException;import java.util.List;import java.util.Timer;import java.util.TimerTask;public class CircleViedoActivity extends Activity implements View.OnClickListener,MediaRecorder.OnErrorListener { private SurfaceView mSurfaceView; private SurfaceHolder mSurfaceHolder; private ProgressBar mProgressBar; private Button shoot_button; private ImageView circle_light_btn; private ImageView circle_change_camera_btn; private TextView circle_camera_time; private MediaRecorder mMediaRecorder; private Camera mCamera; private Timer mTimer;// 計時器 private OnRecordFinishListener mOnRecordFinishListener;// 錄制完成回調接口 private int mWidth;// 視頻分辨率寬度 private int mHeight;// 視頻分辨率高度 private boolean isOpenCamera;// 是否一開始就打開攝像頭 private int mRecordMaxTime;// 一次拍攝最長時間 private int mTimeCount;// 時間計數 private int mNumberOfCameras=0;//手機攝像頭的數量 Bitmap bitmap;//圖片縮略圖 private int screenWidth; public static File mVecordFile = null;// 文件 private boolean isOpenFlash=false; private boolean isBackCamera=true; private int mbackCamera; private int mfrontCamera; private CommonDialog commonDialog; private static final int MOVICE_SUCCESS=1000;//錄制完成 private static final int MOVICE_FILE=1001;//錄制失敗 @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_super_video);  init_datas();  init_view();  set_datas();  init_event(); } private void init_datas() {  isOpenCamera=true;//默認一開始就打開相機  mRecordMaxTime=10;//設置錄制的時間  //獲取手機攝像頭的數量  Camera.CameraInfo cameraInfo=new Camera.CameraInfo();  mNumberOfCameras=Camera.getNumberOfCameras();  for(int camidx=0;camidx<mNumberOfCameras;camidx++){   Camera.getCameraInfo(camidx, cameraInfo);   if(cameraInfo.facing==Camera.CameraInfo.CAMERA_FACING_BACK){    mbackCamera=camidx;   }else if(cameraInfo.facing==Camera.CameraInfo.CAMERA_FACING_FRONT){    mfrontCamera=camidx;   }  } } private void init_view() {  mWidth=640;  mHeight=480;  //獲取屏幕的寬度  screenWidth = getWindowManager().getDefaultDisplay().getWidth();  mSurfaceView = (SurfaceView) findViewById(R.id.surfaceview);//預覽界面  mProgressBar = (ProgressBar) findViewById(R.id.progressBar);//進度條  shoot_button = (Button) findViewById(R.id.shoot_button);//拍攝按鈕  circle_camera_time= (TextView) findViewById(R.id.circle_camera_time);  circle_change_camera_btn= (ImageView) findViewById(R.id.circle_change_camera_btn);//切換攝像頭  circle_light_btn= (ImageView) findViewById(R.id.circle_light_btn);//開啟閃光燈  ViewGroup.LayoutParams params=mSurfaceView.getLayoutParams();  params.height=(screenWidth*4)/3;  params.width=screenWidth;  mSurfaceView.setLayoutParams(params);  top_model2_left_img= (ImageView)findViewById(R.id.top_model2_left_img);  top_model2_left_img.setOnClickListener(this);  top_model2_right_img= (ImageView)findViewById(R.id.top_model2_right_img);  top_model2_right_img.setVisibility(View.INVISIBLE);  top_model2_txt= (TextView)findViewById(R.id.top_model2_txt);  top_model2_txt.setText("視頻錄制"); } private void set_datas() {  mSurfaceHolder = mSurfaceView.getHolder();  mProgressBar.setMax(mRecordMaxTime);// 設置進度條最大量  mSurfaceHolder.setKeepScreenOn(true);//設置屏幕常亮  mSurfaceHolder.addCallback(new CustomCallBack());  mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  circle_camera_time.setText(""); } private void init_event() {  circle_light_btn.setOnClickListener(this);  circle_change_camera_btn.setOnClickListener(this);  shoot_button.setOnTouchListener(new View.OnTouchListener() {   @Override   public boolean onTouch(View v, MotionEvent event) {    if (event.getAction() == MotionEvent.ACTION_DOWN) {     record(new OnRecordFinishListener() {      @Override      public void onRecordFinish() {       //錄制時間達到最大值       handler.sendEmptyMessage(MOVICE_SUCCESS);      }     });    } else if (event.getAction() == MotionEvent.ACTION_UP) {     if (mTimeCount > 1 && mTimeCount<10) { //防止達到最大值up事件      //錄制時間大于一秒      handler.sendEmptyMessage(MOVICE_SUCCESS);     } else if(mTimeCount<=1) {      //刪除小于一秒的視頻      if (getmVecordFile() != null) {       getmVecordFile().delete();      }      handler.sendEmptyMessage(MOVICE_FILE);     }    }    return true;   }  }); } @Override protected void onResume() {  super.onResume();  if(mCamera!=null){   freeCameraResource();  }  try {   initCamera();  } catch (IOException e) {   e.printStackTrace();  } } @Override public void onSaveInstanceState(Bundle outState) {  super.onSaveInstanceState(outState);  // mRecorderView.stop(); } private Handler handler = new Handler() {  @Override  public void handleMessage(Message msg) {   //停止拍攝   stopRecord();   switch (msg.what){    case MOVICE_SUCCESS:     String msgs = "確認上傳嗎?";     commonDialog = new CommonDialog(CircleViedoActivity.this, new CommonDialog.GoCommonDialog() {      @Override      public void go() {       finishActivity();       commonDialog.dismiss();      }      @Override      public void cancel() {       //刪除沒有上傳的視頻       if (getmVecordFile() != null) {        getmVecordFile().delete();       }       commonDialog.dismiss();      }     }, msgs, "確定", "取消");     commonDialog.show();     break;    case MOVICE_FILE:     Toast.makeText(CircleViedoActivity.this, "視頻錄制時間太短", Toast.LENGTH_SHORT).show();     break;   }  } }; private void finishActivity() {  stop();  Bitmap bitmap = null;  if (getmVecordFile() != null) {   //得到文件 File類型   File mfile = getmVecordFile();   bitmap = getVideoThumbnail(mfile.toString());  } /**  * 部分Android手機縮略圖拉不到,找到一種解決辦法不是太滿意 有沒有大神提供思路  */  // VideoPlayerActivity.startActivity(this, mRecorderView.getVecordFile().toString());  Intent intent = new Intent();  intent.putExtra("bitmap",bitmap);  setResult(RESULT_OK,intent);  finish(); } @Override public void onError(MediaRecorder mr, int what, int extra) {  try {   if (mr != null)    mr.reset();  } catch (IllegalStateException e) {   e.printStackTrace();  } catch (Exception e) {   e.printStackTrace();  } } @Override public void onClick(View v) {  switch (v.getId()){   case R.id.circle_light_btn:    //開啟關閉閃光燈 默認關閉    if(isOpenFlash){     isOpenFlash=false;     circle_light_btn.setImageResource(R.drawable.camera_light);    }else {     isOpenFlash=true;     circle_light_btn.setImageResource(R.drawable.camera_no_light);    }    try {     initCamera();    } catch (IOException e) {     e.printStackTrace();    }    break;   case R.id.circle_change_camera_btn:    if(isBackCamera){     isBackCamera=false;    }else {     isBackCamera=true;    }    try {     initCamera();    } catch (IOException e) {     e.printStackTrace();    }    break;   case R.id.top_model2_left_img:    stop();    finish();    break;  } } private class CustomCallBack implements SurfaceHolder.Callback {  @Override  public void surfaceCreated(SurfaceHolder holder) {   if (!isOpenCamera)    return;   try {    initCamera();   } catch (IOException e) {    e.printStackTrace();   }  }  @Override  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {  }  @Override  public void surfaceDestroyed(SurfaceHolder holder) {  } } /**  * 初始化攝像頭  */ private void initCamera() throws IOException {  if (mCamera != null) {   freeCameraResource();  }  try {   if(isBackCamera){    mCamera = Camera.open(mbackCamera);//打開后攝像頭    setCameraParams(isOpenFlash);   }else {    mCamera=Camera.open(mfrontCamera);//打開前攝像頭   }  } catch (Exception e) {   e.printStackTrace();   freeCameraResource();  }  if (mCamera == null)   return;  mCamera.setDisplayOrientation(90);  mCamera.setPreviewDisplay(mSurfaceHolder);  mCamera.startPreview();  mCamera.unlock(); } /**  * 設置攝像頭為豎屏  */ private void setCameraParams(Boolean isOpenFlash) {  if (mCamera != null) {   Camera.Parameters params = mCamera.getParameters();   //獲取預覽的各種分辨率   List<Camera.Size> supportedPreviewSizes = params.getSupportedPreviewSizes();   params.set("orientation", "portrait");//豎屏錄制   params.setPreviewSize(mWidth, mHeight);//默認640*480   params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);//持續對焦   if(isBackCamera){    if(isOpenFlash){     //開啟閃光燈     params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);    }else {     //關閉閃光燈     params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);    }   }else {   }   mCamera.setParameters(params);  } } /**  * 釋放攝像頭資源  */ private void freeCameraResource() {  if (mCamera != null) {   mCamera.setPreviewCallback(null);   mCamera.stopPreview();   mCamera.lock();   mCamera.release();   mCamera = null;  } } private void createRecordDir() {  File sampleDir = new File(Environment.getExternalStorageDirectory() + File.separator + "ATOMImg/video/");  if (!sampleDir.exists()) {   sampleDir.mkdirs();  }  File vecordDir = sampleDir;  // 創建文件  try {   mVecordFile = File.createTempFile("recording", ".mp4", vecordDir);//mp4格式  } catch (IOException e) {  } } /**  * 初始化  */ private void initRecord() throws IOException {  mMediaRecorder = new MediaRecorder();  mMediaRecorder.reset();  if (mCamera != null)   mMediaRecorder.setCamera(mCamera);  mMediaRecorder.setOnErrorListener(this);  mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());  mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);// 視頻源  mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 音頻源  mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// 視頻輸出格式  mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);// 音頻格式  mMediaRecorder.setVideoSize(mWidth, mHeight);// 設置分辨率:  // mMediaRecorder.setVideoFrameRate(16);// 這個我把它去掉了,感覺沒什么用  mMediaRecorder.setVideoEncodingBitRate(1 * 1024 * 1024);// 設置幀頻率,然后就清晰了  if(isBackCamera) {   mMediaRecorder.setOrientationHint(90);// 輸出旋轉90度,保持豎屏錄制  }else {   mMediaRecorder.setOrientationHint(270);  }mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);// 視頻錄制格式----------/**  這里是配置攝像頭的重點 因為我們錄制視頻需要適配IOS開發和Android不同版本的手機 而IOS和Android通配的視頻格式不多 我們這里采用H264格式 它的兼容范圍更廣闊 主要解決的就是部分OPPO手機不適配問題*/----------  // mediaRecorder.setMaxDuration(Constant.MAXVEDIOTIME * 1000);  mMediaRecorder.setOutputFile(mVecordFile.getAbsolutePath());  mMediaRecorder.prepare();  try {   mMediaRecorder.start();  } catch (IllegalStateException e) {   e.printStackTrace();  } catch (RuntimeException e) {   e.printStackTrace();  } catch (Exception e) {   e.printStackTrace();  } } /**  * 錄制完成回調接口  */ public interface OnRecordFinishListener {  public void onRecordFinish(); } /**  * 錄制  * @param onRecordFinishListener  */ public void record(final OnRecordFinishListener onRecordFinishListener) {  this.mOnRecordFinishListener = onRecordFinishListener;  createRecordDir();//創建目錄  try {   if (!isOpenCamera)// 如果未打開攝像頭,則打開    initCamera();//初始化攝像頭   initRecord();//初始化錄制參數   mTimeCount = 0;// 時間計數器重新賦值   mTimer = new Timer();//創建一個定時器   mTimer.schedule(new TimerTask() {    @Override    public void run() {     // TODO Auto-generated method stub     mTimeCount++;     mProgressBar.setProgress(mTimeCount);// 設置進度條     // handler.sendEmptyMessage(TIME_CHANGW);     runOnUiThread(new Runnable() {      @Override      public void run() {       circle_camera_time.setText(mTimeCount + "″");      }     });     if (mTimeCount == mRecordMaxTime) {// 達到指定時間,停止拍攝      //錄制完成調用錄制回調接口      if (mOnRecordFinishListener != null)       mOnRecordFinishListener.onRecordFinish();     }    }   }, 0, 1000);  } catch (IOException e) {   e.printStackTrace();  } } /**  * 停止拍攝  */ public void stop() {  stopRecord();  releaseRecord();  freeCameraResource(); } /**  * 停止錄制  */ public void stopRecord() {  mProgressBar.setProgress(0);  circle_camera_time.setText("");  if (mTimer != null)   mTimer.cancel();  if (mMediaRecorder != null) {   // 設置后不會崩   mMediaRecorder.setOnErrorListener(null);   mMediaRecorder.setPreviewDisplay(null);   try {    mMediaRecorder.stop();   } catch (IllegalStateException e) {    e.printStackTrace();   } catch (RuntimeException e) {    e.printStackTrace();   } catch (Exception e) {    e.printStackTrace();   }  } } /**  * 獲取的視頻的位置  * @return  */ public File getmVecordFile() {  return mVecordFile; } /**  * 釋放資源  */ private void releaseRecord() {  if (mMediaRecorder != null) {   mMediaRecorder.setOnErrorListener(null);   try {    mMediaRecorder.release();   } catch (IllegalStateException e) {    e.printStackTrace();   } catch (Exception e) {    e.printStackTrace();   }  }  mMediaRecorder = null; } @Override public boolean onKeyDown(int keyCode, KeyEvent event) {  if ((keyCode == KeyEvent.KEYCODE_BACK)) {   stop();   finish();   return false;  }else {   return super.onKeyDown(keyCode, event);  } } /**  * 獲取視頻縮略圖  * @param filePath  * @return  */ public Bitmap getVideoThumbnail(String filePath) {  Bitmap bitmap = null;  MediaMetadataRetriever retriever = new MediaMetadataRetriever();  try {   retriever.setDataSource(filePath);   bitmap = retriever.getFrameAtTime();  }  catch(IllegalArgumentException e) {   e.printStackTrace();  }  catch (RuntimeException e) {   e.printStackTrace();  }  finally {   try {    retriever.release();   }   catch (RuntimeException e) {    e.printStackTrace();   }  }  return bitmap; } @Override protected void onDestroy() {  super.onDestroy();  if(bitmap!=null){   try {    bitmap.recycle();   } catch (Exception e) {    e.printStackTrace();   }   bitmap=null;  } }}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 祁东县| 凤冈县| 荣昌县| 高清| 宝丰县| 惠州市| 通许县| 五指山市| 芦溪县| 汶川县| 曲松县| 搜索| 沙河市| 林西县| 马山县| 沛县| 普洱| 陵川县| 平谷区| 开封县| 大同市| 昌平区| 石首市| 康平县| 佛坪县| 张家港市| 景谷| 海口市| 福海县| 民县| 莱芜市| 商水县| 鄂尔多斯市| 陵川县| 巫山县| 伊川县| 金溪县| 红安县| 辽阳市| 衢州市| 威远县|