package com.kirin.voltage.activity;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import com.kirin.voltage.R;
import com.kirin.voltage.util.CompareSizesByArea;
import com.kirin.voltage.util.LogUtil;
import com.kirin.voltage.util.SharedPreferencesUtils;
import com.kirin.voltage.view.AutoFitTextureView;

import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCaptureSession.StateCallback;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureRequest.Builder;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Range;
import android.util.Size;
import android.util.SparseIntArray;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.TextureView;
import android.view.TextureView.SurfaceTextureListener;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.PopupWindow;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.Toast;

public class RecordActivity extends Activity implements View.OnClickListener {
private static final int VIDEO_1080 = 0x0;
private static final int VIDEO_4K = 0x1;
private static final int VIDEO_NORMAL = 0x2;
private static final String INDEX = "INDEX";
private static final String TAG = RecordActivity.class.getSimpleName();

private static final SparseIntArray DEFAULT_ORIENTATION = new SparseIntArray();

static {
DEFAULT_ORIENTATION.append(Surface.ROTATION_0, 90);
DEFAULT_ORIENTATION.append(Surface.ROTATION_90, 0);
DEFAULT_ORIENTATION.append(Surface.ROTATION_180, 270);
DEFAULT_ORIENTATION.append(Surface.ROTATION_270, 180);
}

private CameraCaptureSession mPreviewSession;
private CaptureRequest.Builder mPreviewBuilder;
private CameraConstrainedHighSpeedCaptureSession mPreviewSessionHighSpeed;

private String mFilePath;

private boolean supportedNormal;
private boolean supported4K;
private boolean supported1080P120Fps;
private boolean isRecording = false;

private int index;
private Size size4K, size1080P, size320x240, videoSize, mPreviewSize;;

private AutoFitTextureView mTextureView;
private Button btn_record;
private ImageButton ibtn_info;

private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {

@Override
public void onOpened(CameraDevice camera) {
mCameraDevice = camera;
startPreview();
// mCameraOpenCloseLock.release();
if (null != mTextureView) {
configureTransform(mTextureView.getWidth(), mTextureView.getHeight());
}
}

@Override
public void onError(CameraDevice camera, int error) {
// mCameraOpenCloseLock.release();
camera.close();
mCameraDevice = null;
}

@Override
public void onDisconnected(CameraDevice camera) {
// mCameraOpenCloseLock.release();
camera.close();
mCameraDevice = null;
}
};

private TextureView.SurfaceTextureListener textureListener = new SurfaceTextureListener() {

@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {

}

@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
configureTransform(width, height);
}

@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return true;
}

@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
openCamera(width, height);
}
};

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

mTextureView = (AutoFitTextureView) findViewById(R.id.textureview);
btn_record = (Button) findViewById(R.id.btn_record);
ibtn_info = (ImageButton) findViewById(R.id.ibtn_info);

btn_record.setOnClickListener(this);
ibtn_info.setOnClickListener(this);

index = SharedPreferencesUtils.getInt(this, INDEX, VIDEO_NORMAL);
size1080P = new Size(1920, 1080);
size320x240 = new Size(320, 240);
size4K = new Size(3840, 2160);
switch (index) {
case VIDEO_1080:
videoSize = size1080P;
break;
case VIDEO_4K:
videoSize = size4K;
break;
case VIDEO_NORMAL:
videoSize = size320x240;
break;
}
}

@Override
protected void onResume() {

super.onResume();
startBackgroundThread();
if (mTextureView.isAvailable()) {
openCamera(mTextureView.getWidth(), mTextureView.getHeight());
} else {
mTextureView.setSurfaceTextureListener(textureListener);
}
}

private void openCamera(int width, int height) {
CameraManager manager = (CameraManager) getSystemService(CAMERA_SERVICE);
try {
String cameraId = manager.getCameraIdList()[0];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);

StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);

assert map != null;

availableFpsRange = map.getHighSpeedVideoFpsRangesFor(size1080P);

Size[] highSpeedVideoSizes = map.getHighSpeedVideoSizes();
if (highSpeedVideoSizes != null) {
if (Arrays.asList(highSpeedVideoSizes).contains(size1080P)) {
Range<Integer>[] ranges = map.getHighSpeedVideoFpsRangesFor(size1080P);
if (ranges != null) {
for (Range<Integer> r : ranges) {
if (r.contains(120)) {
supported1080P120Fps = true;
break;
}
}
}
}
}

Size[] outputSizes = map.getOutputSizes(MediaRecorder.class);
if (outputSizes != null) {
for (Size s : outputSizes) {
if (s.equals(size320x240)) {
supportedNormal = true;
} else if (s.equals(size4K)) {
supported4K = true;
}
}
}

mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), width, height, videoSize);

int orientation = getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
mTextureView.setAspectRatio(mPreviewSize.getWidth(), mPreviewSize.getHeight());
} else {
mTextureView.setAspectRatio(mPreviewSize.getHeight(), mPreviewSize.getWidth());
}
configureTransform(width, height);
mMediaRecorder = new MediaRecorder();
manager.openCamera(cameraId, mStateCallback, null);

} catch (CameraAccessException e) {

e.printStackTrace();
LogUtil.e(TAG, "openCamera : " + e);
}
}

private static Size chooseOptimalSize(Size[] choices, int width, int height, Size aspectRatio) {
List<Size> bigEnough = new ArrayList<Size>();
int w = aspectRatio.getWidth();
int h = aspectRatio.getHeight();
for (Size option : choices) {
if (option.getHeight() == option.getWidth() * h / w && option.getWidth() <= width
&& option.getHeight() <= height) {
bigEnough.add(option);
}
}

if (bigEnough.size() > 0) {
return Collections.max(bigEnough, new CompareSizesByArea());
} else {
LogUtil.e(TAG, "Couldn't find any suitable preview size");
return choices[0];
}
}

protected void onDestroy() {
if (mCameraDevice != null) {
mCameraDevice.close();
mCameraDevice = null;
}
if (mMediaRecorder != null) {
mMediaRecorder.release();
mMediaRecorder.reset();
mMediaRecorder = null;
}
super.onDestroy();
};

private void configureTransform(int width, int height) {
if (null == mTextureView) {
return;
}
int rotation = getWindowManager().getDefaultDisplay().getRotation();
Matrix matrix = new Matrix();
RectF viewRect = new RectF(0, 0, width, height);
RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());
float centerX = viewRect.centerX();
float centerY = viewRect.centerY();
if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
float scale = Math.max((float) height / mPreviewSize.getHeight(), (float) height / mPreviewSize.getWidth());
matrix.postScale(scale, scale, centerX, centerY);
matrix.postRotate(90 * (rotation - 2), centerX, centerY);
}
mTextureView.setTransform(matrix);
}

@Override
protected void onPause() {
// 处理界面,停止录制
if (isRecording) {
stopRecordingVideoOnPause();
}
closeCamera();
stopBackgroundThread();
super.onPause();
}

@Override
public void onClick(View v) {
// 处理点击事件
switch (v.getId()) {
case R.id.btn_record:
if (isRecording) {
stopRecordVideo();
} else {
startRecordVideo();
}
break;
case R.id.ibtn_info:
showChoices();
break;
default:
break;
}
}

Android 高速录像(1)的更多相关文章

  1. Android 高速录像(2)

    private void startRecordVideo() { if (index == VIDEO_1080) { if (!supported1080P120Fps) { showToast( ...

  2. Bmob移动后端云服务平台--Android从零開始--(二)android高速入门

    Bmob移动后端云服务平台--Android从零開始--(二)android高速入门 上一篇博文我们简介何为Bmob移动后端服务平台,以及其相关功能和优势. 本文将利用Bmob高速实现简单样例,进一步 ...

  3. android Camera 录像时旋转角度

    录像保存时,旋转角度要与所拍录像时的角度保持一致,否则,看起来就会出现角度不度,巅倒等问题. 一般在开始录像之前会先去初始化录像 initializeRecorder 中会去读取当前的录像或拍照的旋转 ...

  4. 看大师解说Android高速开发框架EasyAndroid

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u010966622/article/details/37601789 前几天做了小应用.感觉小有成就 ...

  5. EasyPlayer实现Android MediaMuxer录像MP4(支持G711/AAC/G726音频)

    本文转自EasyDarwin开源团队John的博客:http://blog.csdn.net/jyt0551/article/details/72787095 Android平台的MediaMuxer ...

  6. android高速开发框架xUtils

    xUtils简单介绍 xUtils 包括了非常多有用的android工具. xUtils 支持大文件上传,更全面的http请求协议支持(10种谓词).拥有更加灵活的ORM,很多其它的事件注解支持且不受 ...

  7. 官方Android Camera2 录像示例--停止录像时崩溃修正

    官方Android 使用Camera2示例项目地址:https://github.com/android/camera-samples 视频录像示例:https://github.com/androi ...

  8. 5.3、Android Studio录像

    Android Monitor允许你从设备中录制一段MP4格式的视频,最长允许3分钟. 录制视频 在硬件设备中录制视频: 1. 打开一个项目 2. 在设备中运行应用 3. 显示Android Moni ...

  9. android高速上手(三)经常使用控件使用

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/wangpeifeng669/article/details/26288387 完毕了android的 ...

随机推荐

  1. [转] AKKA简介

    [From] https://blog.csdn.net/linuxarmsummary/article/details/79399602 Akka in JAVA(一) AKKA简介 什么是AKKA ...

  2. Yii2 PHPExcel在linux环境下导出报500错误

    断点调试后发现是因为这句报错 header('Content-Type : application/vnd.ms-excel');删除后正常输出下载

  3. mysql出现 Unknown column 'bname' in 'where clause'和Unknown column 'bid' in 'field list'

    在用mysql数据库建表和修改数据库数据时,出现  Unknown column 'bname' in 'where clause'和Unknown column 'bid' in 'field li ...

  4. 如何让一个div居于页面正中间

    如何让一个div居于页面正中间 如何让一个div居于页面中间,我今天说的是让一个div水平居中同时垂直居中,而不是简单的top:50%,left:50%.当然,我们就按一开始的思路写一下:top,le ...

  5. oracle--dump块信息操作

    01, 查看表 SQL> select * from tab where TNAME='T'; TNAME TABTYPE ----------------------------------- ...

  6. RocketMQ 安装

    RocketMQ 安装 1.进入目录 cd /usr 2.下载 wget http://mirrors.tuna.tsinghua.edu.cn/apache/rocketmq/4.3.0/rocke ...

  7. Linux 命令 -- chown

    chown命令改变某个文件或目录的所有者和所属的组,该命令可以向某个用户授权,使该用户变成指定文件的所有者或者改变文件所属的组.用户可以是用户或者是用户D,用户组可以是组名或组id.文件名可以使由空格 ...

  8. plpgsql insert 性能 测试

    有时需要执行一些sql脚本,带逻辑控制语句,又不想用高级语言C#.Java之类的,可以直接用plpgsql,类似于Oracle的plsql. do language 'plpgsql' $$ decl ...

  9. 总结—angularjs项目

    我毕业了-------有点期待生活,又点害怕生活. 总结下最近一个月做的这个项目,项目的开发形式也比较新颖,采用的是前后端分离的形式.我负责前端的管理系统开发,另一个哥们负责利用ABP创建接口,整合后 ...

  10. nodejs图片裁剪、缩放、水印

    关于nodejs下图片的裁剪.水印,网上的模块很多,主要如下: gm:https://github.com/aheckmann/gm node-canvas:https://github.com/Au ...