Android 高速录像(1)
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)的更多相关文章
- Android 高速录像(2)
private void startRecordVideo() { if (index == VIDEO_1080) { if (!supported1080P120Fps) { showToast( ...
- Bmob移动后端云服务平台--Android从零開始--(二)android高速入门
Bmob移动后端云服务平台--Android从零開始--(二)android高速入门 上一篇博文我们简介何为Bmob移动后端服务平台,以及其相关功能和优势. 本文将利用Bmob高速实现简单样例,进一步 ...
- android Camera 录像时旋转角度
录像保存时,旋转角度要与所拍录像时的角度保持一致,否则,看起来就会出现角度不度,巅倒等问题. 一般在开始录像之前会先去初始化录像 initializeRecorder 中会去读取当前的录像或拍照的旋转 ...
- 看大师解说Android高速开发框架EasyAndroid
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u010966622/article/details/37601789 前几天做了小应用.感觉小有成就 ...
- EasyPlayer实现Android MediaMuxer录像MP4(支持G711/AAC/G726音频)
本文转自EasyDarwin开源团队John的博客:http://blog.csdn.net/jyt0551/article/details/72787095 Android平台的MediaMuxer ...
- android高速开发框架xUtils
xUtils简单介绍 xUtils 包括了非常多有用的android工具. xUtils 支持大文件上传,更全面的http请求协议支持(10种谓词).拥有更加灵活的ORM,很多其它的事件注解支持且不受 ...
- 官方Android Camera2 录像示例--停止录像时崩溃修正
官方Android 使用Camera2示例项目地址:https://github.com/android/camera-samples 视频录像示例:https://github.com/androi ...
- 5.3、Android Studio录像
Android Monitor允许你从设备中录制一段MP4格式的视频,最长允许3分钟. 录制视频 在硬件设备中录制视频: 1. 打开一个项目 2. 在设备中运行应用 3. 显示Android Moni ...
- android高速上手(三)经常使用控件使用
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/wangpeifeng669/article/details/26288387 完毕了android的 ...
随机推荐
- jenkins 重置构建历史
item = Jenkins.instance.getItemByFullName("98")//THIS WILL REMOVE ALL BUILD HISTORYitem.bu ...
- django 中的聚合和分组 F查询 Q查询 事务cookies和sessions 066
1 聚合和分组 聚合:对一些数据进行整理分析 进而得到结果(mysql中的聚合函数) 1aggregate(*args,**kwargs) : 通过对QuerySet进行计算 ,返回一个聚合值的字典. ...
- Git学习系列之 Git 、CVS、SVN的比较
Git .CVS.SVN比较 项目源代码的版本管理工具中,比较常用的主要有:CVS.SVN.Git 和 Mercurial (其中,关于SVN,请参见我的博客:SVN学习系列) 目前Google C ...
- spring-boot启动后在浏览器打开指定页面
来自:https://stackoverflow.com/questions/27378292/launch-browser-automatically-after-spring-boot-webap ...
- 【c++】访问控制
1. 类内的访问控制 在基类中,public和private具有普通的含义:用户(即基类的对象)可以访问public成员(包括函数.数据),而不能访问private成员.private只能被基类的成 ...
- C运算符总结
算术运算符 加减 + - 自左向右 +-同级 乘除取模 * % / 自左向右 高于+ - 自加自减 ++ -- 右结合性 高于基本算术运算符 正负 -+ 自右向左 跟++ --同级 赋值运算符 赋值 ...
- StrangeIoc框架学习
StrangeIoc是一款基于MVCS的一种框架,是对MVC思想的扩展,是专门针对Unity3D开发的一款框架,非常好用. 一.MVCS分别代表什么 MVCS框架是一种模块的分离,一种写代码的规则,目 ...
- Java并发编程之volatile关键字解析
一内存模型的相关概念 二并发编程中的三个概念 三Java内存模型 四深入剖析volatile关键字 五使用volatile关键字的场景 volatile这个关键字可能很多朋友都听说过,或许也都用过.在 ...
- sql语句将数字转为汉字展示
select [表字段Name] , ( case [表字段OrderState] when 1 then '已核销' when 2 then '确认前的移动端取消'when 3 then '已完成' ...
- flight学习笔记
Flight::db()-> getOne("select 1"); 返回结果:1 Flight::db()-> getRow ("select 1, 2 f ...