最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android使用MediaRecorder實(shí)現(xiàn)錄像功能

 更新時(shí)間:2017年06月16日 15:06:51   作者:gavanwanggw  
這篇文章主要為大家詳細(xì)介紹了Android使用MediaRecorder實(shí)現(xiàn)錄像功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

用MediaRecorder實(shí)現(xiàn)簡(jiǎn)單的錄像功能

思路:定義一個(gè)SurfaceView用來(lái)顯示預(yù)覽,在SurfaceHolder的回調(diào)中用Camera對(duì)象啟動(dòng)預(yù)覽。然后調(diào)用MediaRecorder來(lái)錄像。僅僅是實(shí)現(xiàn)了簡(jiǎn)單的錄像開(kāi)始和停止功能。頂部能顯示顯示錄像的時(shí)間,還有待完好。

代碼例如以下:

在AndroidManifest.xml加入以下的權(quán)限:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 硬件支持 -->
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent" >

 <SurfaceView
 android:id="@+id/camera_preview"
 android:layout_width="match_parent"
 android:layout_height="match_parent" />

 <LinearLayout
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_alignParentTop="true"
 android:layout_centerHorizontal="true"
 android:orientation="horizontal">

 <TextView
  android:id="@+id/timestamp_minute_prefix"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:textColor="#7F00FF"
  android:textSize="30sp"
  android:text="0"/>

 <TextView
  android:id="@+id/timestamp_minute_text"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:textColor="#7F00FF"
  android:textSize="30sp"
  android:text="0"/>

 <TextView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:textColor="#7F00FF"
  android:textSize="30sp"
  android:text=":"/>

 <TextView
  android:id="@+id/timestamp_second_prefix"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:textColor="#7F00FF"
  android:textSize="30sp"
  android:text="0"/>

 <TextView
  android:id="@+id/timestamp_second_text"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:textColor="#7F00FF"
  android:textSize="30sp"
  android:text="0"/>
 </LinearLayout>

 <ImageButton
 android:id="@+id/record_shutter"
 android:layout_width="64dp"
 android:layout_height="64dp"
 android:layout_alignParentBottom="true"
 android:layout_centerHorizontal="true"
 android:layout_marginBottom="15dp"
 android:background="@android:color/transparent"
 android:scaleType="centerCrop"
 android:src="@drawable/recording_shutter" />

</RelativeLayout>

MainActivity.java

package com.jackie.videorecorder;

import java.io.File;

import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.TextView;

import org.w3c.dom.Text;

public class MainActivity extends Activity implements OnClickListener {
 private SurfaceView mCameraPreview;
 private SurfaceHolder mSurfaceHolder;
 private ImageButton mShutter;
 private TextView mMinutePrefix;
 private TextView mMinuteText;
 private TextView mSecondPrefix;
 private TextView mSecondText;

 private Camera mCamera;
 private MediaRecorder mRecorder;

 private final static int CAMERA_ID = 0;

 private boolean mIsRecording = false;
 private boolean mIsSufaceCreated = false;

 private static final String TAG = "Jackie";

 private Handler mHandler = new Handler();

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);

 mCameraPreview = (SurfaceView) findViewById(R.id.camera_preview);
 mMinutePrefix = (TextView) findViewById(R.id.timestamp_minute_prefix);
 mMinuteText = (TextView) findViewById(R.id.timestamp_minute_text);
 mSecondPrefix = (TextView) findViewById(R.id.timestamp_second_prefix);
 mSecondText = (TextView) findViewById(R.id.timestamp_second_text);

 mSurfaceHolder = mCameraPreview.getHolder();
 mSurfaceHolder.addCallback(mSurfaceCallback);
 mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

 mShutter = (ImageButton) findViewById(R.id.record_shutter);
 mShutter.setOnClickListener(this);
 }

 @Override
 protected void onPause() {
 super.onPause();
 if (mIsRecording) {
  stopRecording();
 }
 stopPreview();
 }

 private SurfaceHolder.Callback mSurfaceCallback = new SurfaceHolder.Callback() {

 @Override
 public void surfaceDestroyed(SurfaceHolder holder) {
  mIsSufaceCreated = false;
 }

 @Override
 public void surfaceCreated(SurfaceHolder holder) {
  mIsSufaceCreated = true;
 }

 @Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  startPreview();
 }
 };

 //啟動(dòng)預(yù)覽
 private void startPreview() {
 //保證僅僅有一個(gè)Camera對(duì)象
 if (mCamera != null || !mIsSufaceCreated) {
  Log.d(TAG, "startPreview will return");
  return;
 }

 mCamera = Camera.open(CAMERA_ID);

 Parameters parameters = mCamera.getParameters();
 Size size = getBestPreviewSize(CameraUtils.PREVIEW_WIDTH, CameraUtils.PREVIEW_HEIGHT, parameters);
 if (size != null) {
  parameters.setPreviewSize(size.width, size.height);
 }

 parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
 parameters.setPreviewFrameRate(20);

 //設(shè)置相機(jī)預(yù)覽方向
 mCamera.setDisplayOrientation(90);

 mCamera.setParameters(parameters);

 try {
  mCamera.setPreviewDisplay(mSurfaceHolder);
// mCamera.setPreviewCallback(mPreviewCallback);
 } catch (Exception e) {
  Log.d(TAG, e.getMessage());
 }

 mCamera.startPreview();
 }

 private void stopPreview() {
 //釋放Camera對(duì)象
 if (mCamera != null) {
  try {
  mCamera.setPreviewDisplay(null);
  } catch (Exception e) {
  Log.e(TAG, e.getMessage());
  }

  mCamera.stopPreview();
  mCamera.release();
  mCamera = null;
 }
 }

 private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) {
 Camera.Size result = null;

 for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
  if (size.width <= width && size.height <= height) {
  if (result == null) {
   result = size;
  } else {
   int resultArea = result.width * result.height;
   int newArea = size.width * size.height;

   if (newArea > resultArea) {
   result = size;
   }
  }
  }
 }

 return result;
 }

 @Override
 public void onClick(View v) {
 if (mIsRecording) {
  stopRecording();
 } else {
  initMediaRecorder();
  startRecording();

  //開(kāi)始錄像后,每隔1s去更新錄像的時(shí)間戳
  mHandler.postDelayed(mTimestampRunnable, 1000);
 }
 }

 private void initMediaRecorder() {
 mRecorder = new MediaRecorder();//實(shí)例化
 mCamera.unlock();
 //給Recorder設(shè)置Camera對(duì)象,保證錄像跟預(yù)覽的方向保持一致
 mRecorder.setCamera(mCamera);
 mRecorder.setOrientationHint(90); //改變保存后的視頻文件播放時(shí)是否橫屏(不加這句。視頻文件播放的時(shí)候角度是反的)
 mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 設(shè)置從麥克風(fēng)採(cǎi)集聲音
 mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 設(shè)置從攝像頭採(cǎi)集圖像
 mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); // 設(shè)置視頻的輸出格式 為MP4
 mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); // 設(shè)置音頻的編碼格式
 mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); // 設(shè)置視頻的編碼格式
 mRecorder.setVideoSize(176, 144); // 設(shè)置視頻大小
 mRecorder.setVideoFrameRate(20); // 設(shè)置幀率
// mRecorder.setMaxDuration(10000); //設(shè)置最大錄像時(shí)間為10s
 mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());

 //設(shè)置視頻存儲(chǔ)路徑
 File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + File.separator + "VideoRecorder");
 if (!file.exists()) {
  //多級(jí)目錄的創(chuàng)建
  file.mkdirs();
 }
 mRecorder.setOutputFile(file.getPath() + File.separator + "VID_" + System.currentTimeMillis() + ".mp4");
 }

 private void startRecording() {
 if (mRecorder != null) {
  try {
  mRecorder.prepare();
  mRecorder.start();
  } catch (Exception e) {
  mIsRecording = false;
  Log.e(TAG, e.getMessage());
  }
 }

 mShutter.setImageDrawable(getResources().getDrawable(R.drawable.recording_shutter_hl));
 mIsRecording = true;
 }

 private void stopRecording() {
 if (mCamera != null) {
  mCamera.lock();
 }

 if (mRecorder != null) {
  mRecorder.stop();
  mRecorder.release();
  mRecorder = null;
 }

 mShutter.setImageDrawable(getResources().getDrawable(R.drawable.recording_shutter));
 mIsRecording = false;

 mHandler.removeCallbacks(mTimestampRunnable);

 //將錄像時(shí)間還原
 mMinutePrefix.setVisibility(View.VISIBLE);
 mMinuteText.setText("0");
 mSecondPrefix.setVisibility(View.VISIBLE);
 mSecondText.setText("0");

 //重新啟動(dòng)預(yù)覽
 startPreview();
 }

 private Runnable mTimestampRunnable = new Runnable() {
 @Override
 public void run() {
  updateTimestamp();
  mHandler.postDelayed(this, 1000);
 }
 };

 private void updateTimestamp() {
 int second = Integer.parseInt(mSecondText.getText().toString());
 int minute = Integer.parseInt(mMinuteText.getText().toString());
 second++;
 Log.d(TAG, "second: " + second);

 if (second < 10) {
  mSecondText.setText(String.valueOf(second));
 } else if (second >= 10 && second < 60) {
  mSecondPrefix.setVisibility(View.GONE);
  mSecondText.setText(String.valueOf(second));
 } else if (second >= 60) {
  mSecondPrefix.setVisibility(View.VISIBLE);
  mSecondText.setText("0");

  minute++;
  mMinuteText.setText(String.valueOf(minute));
 } else if (minute >= 60) {
  mMinutePrefix.setVisibility(View.GONE);
 }
 }
}

效果例如以下:

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android實(shí)現(xiàn)底部導(dǎo)航欄功能(選項(xiàng)卡)

    Android實(shí)現(xiàn)底部導(dǎo)航欄功能(選項(xiàng)卡)

    這篇文章主要介紹了Android實(shí)現(xiàn)底部導(dǎo)航欄功能,可以隨意切換不同的頁(yè)面,實(shí)現(xiàn)選項(xiàng)卡功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2015-12-12
  • 揭秘雙十一手機(jī)淘寶圖標(biāo)如何被動(dòng)態(tài)更換

    揭秘雙十一手機(jī)淘寶圖標(biāo)如何被動(dòng)態(tài)更換

    這篇文章主要介紹了每到雙十一十二的時(shí)候Android手機(jī)動(dòng)態(tài)更換手機(jī)圖標(biāo)的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • Android如何監(jiān)聽(tīng)屏幕旋轉(zhuǎn)

    Android如何監(jiān)聽(tīng)屏幕旋轉(zhuǎn)

    這篇文章主要介紹了如何監(jiān)聽(tīng)Android屏幕旋轉(zhuǎn),幫助大家更好的理解和學(xué)習(xí)使用Android開(kāi)發(fā),感興趣的朋友可以了解下
    2021-03-03
  • Android實(shí)現(xiàn)全局右滑返回

    Android實(shí)現(xiàn)全局右滑返回

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)全局右滑返回,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • 讓IjkPlayer支持插入自定義的GPU濾鏡方法

    讓IjkPlayer支持插入自定義的GPU濾鏡方法

    下面小編就為大家分享一篇讓IjkPlayer支持插入自定義的GPU濾鏡方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • 詳細(xì)講解AsyncTask使用說(shuō)明(值得收藏)

    詳細(xì)講解AsyncTask使用說(shuō)明(值得收藏)

    AsyncTask就相當(dāng)于Android給我們提供了一個(gè)多線程編程的一個(gè)框架,其介于Thread和Handler之間,我們?nèi)绻x一個(gè)AsyncTask,就需要定義一個(gè)類來(lái)繼承AsyncTask這個(gè)抽象類,并實(shí)現(xiàn)其唯一的一doInBackgroud 抽象方法,這篇文章主要介紹了AsyncTask詳解,需要的朋友可以參考下
    2024-01-01
  • 使用android隱藏api實(shí)現(xiàn)亮度調(diào)節(jié)的方法

    使用android隱藏api實(shí)現(xiàn)亮度調(diào)節(jié)的方法

    使用android隱藏api實(shí)現(xiàn)亮度調(diào)節(jié)的方法,需要的朋友可以參考一下
    2013-05-05
  • Android studio實(shí)現(xiàn)簡(jiǎn)易計(jì)算器App功能

    Android studio實(shí)現(xiàn)簡(jiǎn)易計(jì)算器App功能

    這篇文章主要為大家詳細(xì)介紹了Android studio實(shí)現(xiàn)簡(jiǎn)易計(jì)算器App功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • Android實(shí)現(xiàn)簡(jiǎn)易的鬧鐘功能

    Android實(shí)現(xiàn)簡(jiǎn)易的鬧鐘功能

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)簡(jiǎn)易的鬧鐘功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • Android開(kāi)發(fā)實(shí)現(xiàn)日期時(shí)間控件選擇

    Android開(kāi)發(fā)實(shí)現(xiàn)日期時(shí)間控件選擇

    這篇文章主要為大家詳細(xì)介紹了Android開(kāi)發(fā)實(shí)現(xiàn)日期時(shí)間控件選擇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09

最新評(píng)論

韶关市| 文安县| 增城市| 嘉善县| 基隆市| 广汉市| 开远市| 尖扎县| 梁平县| 华蓥市| 罗定市| 扎囊县| 兴宁市| 获嘉县| 清水河县| 乐平市| 竹溪县| 通化市| 隆尧县| 延川县| 高陵县| 井冈山市| 东台市| 中西区| 禹城市| 房产| 白河县| 嘉兴市| 普兰县| 永吉县| 刚察县| 星子县| 崇信县| 敦化市| 弥勒县| 金门县| 剑川县| 南陵县| 玉林市| 华亭县| 隆尧县|