近期比較忙,非常久没更新博客,今天我们仿一个美拍或者糗事百科的录像功能。

首先确认步奏:

1、打开摄像头;

2、開始录制;

3、支持分段录制,并支持分段删除;

4、把分段录制的视频进行合并;

不说废话了先上图:

事实上布局没什么好看的,布局就不看了。直接上代码。

package com.example.shipin;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List; import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnErrorListener;
import android.media.MediaRecorder.OnInfoListener;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.Toast; public class VideoNewActivity extends BaseActivity implements SurfaceHolder.Callback { /** 视频最大支持15秒 */
public static final int VIDEO_TIME_END = 15;
/** 视频最少必须5秒 */
public static final int VIDEO_TIME = 5;
/** 最少得录制多少秒 */
private ImageView img_at_last;
/** 闪现光标图片 */
private ImageView img_shan;
/** 删除录制 */
private ImageView img_delete;
/** 開始录制 */
private ImageButton img_start;
/** 确认 */
private ImageView img_enter;
/** 闪光灯切换 */
private ImageView img_flashlight;
/** 摄像头切换 */
private ImageView img_camera;
/** 选择录像 */
private ImageView img_video;
/** 返回button */
private ImageView img_back;
/** 计时器 */
private TimeCount timeCount;
/** 录制了多少秒 */
private int now;
/** 每次录制结束时是多少秒 */
private int old; /** 录制进度控件 */
private LinearLayout linear_seekbar;
/** 屏幕宽度 */
private int width;
/** 偶数才运行 */
private int even;
/** 是否点击删除了一次 */
private boolean isOnclick = false;
/** 录制视频集合 */
private ArrayList<VideoNewBean> list;
/** 录制bean */
private VideoNewBean bean;
/** 为了能保存到bundler 录制bean */
private VideoNewParentBean parent_bean;
/** 录制视频保存文件 */
private String vedioPath;
/** 合并之后的视频文件 */
private String videoPath_merge;
/** 是否满足视频的最少播放时长 */
private boolean isMeet = false; /** 录制视频的类 */
private MediaRecorder mMediaRecorder;
/** 摄像头对象 */
private Camera mCamera;
/** 显示的view */
private SurfaceView surfaceView;
/** 摄像头參数 */
private Parameters mParameters;
// /** 视频输出质量 */
private CamcorderProfile mProfile;
/** 文本属性获取器 */
private SharedPreferences mPreferences;
/** 刷新界面的回调 */
private SurfaceHolder mHolder;
/** 1表示后置,0表示前置 */
private int cameraPosition = 1;
/** 路径 */
private String Ppath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/videoTest/"; // /** 压缩jni */
// private LoadJNI vk; @Override
protected int getContentViewId() {
return R.layout.activity_video_new;
} @SuppressWarnings("deprecation")
@Override
protected void findViews() {
img_camera = (ImageView) findViewById(R.id.video_new_img_right);
img_flashlight = (ImageView) findViewById(R.id.video_new_img_flashlight);
surfaceView = (SurfaceView) findViewById(R.id.video_new_surfaceview);
img_at_last = (ImageView) findViewById(R.id.video_new_img_time_atlast);
img_shan = (ImageView) findViewById(R.id.video_new_img_time_start);
img_delete = (ImageView) findViewById(R.id.video_new_img_delete);
img_start = (ImageButton) findViewById(R.id.video_new_img_start);
img_enter = (ImageView) findViewById(R.id.video_new_img_enter);
img_back = (ImageView) findViewById(R.id.video_new_img_back);
img_video = (ImageView) findViewById(R.id.video_new_img_video);
linear_seekbar = (LinearLayout) findViewById(R.id.video_new_seekbar); width = getWindowManager().getDefaultDisplay().getWidth(); LayoutParams layoutParam = (LayoutParams) surfaceView.getLayoutParams();
// 高:宽 4 : 3
layoutParam.height = width / 3 * 4;
// 隐藏多少dp才干让屏幕显示正常像素
layoutParam.topMargin = -(width / 3 * 4 - width - DisplayUtil.dip2px(VideoNewActivity.this, 44));
surfaceView.setLayoutParams(layoutParam); LayoutParams layoutParams = (LayoutParams) img_at_last.getLayoutParams();
layoutParams.leftMargin = width / VIDEO_TIME_END * VIDEO_TIME;
img_at_last.setLayoutParams(layoutParams);
} @Override
protected void onSaveInstanceState(Bundle outState) {
parent_bean.setList(list);
outState.putSerializable("parent_bean", parent_bean); super.onSaveInstanceState(outState);
} @Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
parent_bean = (VideoNewParentBean) savedInstanceState.getSerializable("parent_bean");
list = parent_bean.getList(); super.onRestoreInstanceState(savedInstanceState);
} @SuppressWarnings("deprecation")
@Override
protected void init() {
handler.postDelayed(runnable, 0);
even = 0;
old = 0;
// 创建目录
File file = new File(Ppath);
if (!file.exists()) {
file.mkdir();
}
list = new ArrayList<VideoNewBean>();
parent_bean = new VideoNewParentBean();
// 安装一个SurfaceHolder.Callback
mHolder = surfaceView.getHolder();
mHolder.addCallback(this);
// 针对低于3.0的Android
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
readVideoPreferences(); } @Override
protected void onStart() {
super.onStart();
// 获取Camera实例
mCamera = getCamera();
if (mCamera != null) {
// 因为android不支持竖屏录制,所以须要顺时针转90度。让其游览器显示正常
mCamera.setDisplayOrientation(90);
mCamera.lock();
initCameraParameters();
}
} @Override
protected void onPause() {
super.onPause();
releaseCamera();
} /**
* 获取摄像头实例
*
* @version 1.0
* @createTime 2015年6月16日,上午10:44:11
* @updateTime 2015年6月16日,上午10:44:11
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
* @return
*/
private Camera getCamera() {
Camera camera = null;
try {
camera = Camera.open();
} catch (Exception e) {
camera = null;
}
return camera;
} private Handler handler = new Handler(); private Runnable runnable = new Runnable() { @Override
public void run() {
if (img_shan.isShown()) {
img_shan.setVisibility(View.GONE);
} else {
img_shan.setVisibility(View.VISIBLE);
}
handler.postDelayed(runnable, 500);
}
}; @SuppressLint("ClickableViewAccessibility")
@Override
protected void widgetListener() {
img_start.setOnTouchListener(new OnTouchListener() { @Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: if (isOnclick) {
((ImageView) linear_seekbar.getChildAt(linear_seekbar.getChildCount() - 2)).setBackgroundColor(getResources().getColor(
R.color.ff1f8fe4));
} even = 1; img_delete.setVisibility(View.VISIBLE);
img_enter.setVisibility(View.VISIBLE);
img_video.setVisibility(View.GONE);
img_camera.setVisibility(View.GONE); addView_Red(); // 构造CountDownTimer对象
timeCount = new TimeCount(30000 - old, 50);
timeCount.start();// 開始计时 startRecord(); break;
case MotionEvent.ACTION_UP:
old = now + old; if (old >= VIDEO_TIME * 1000) {
isMeet = true;
} timeCount.cancel(); addView_black(); stopRecord(); break;
}
return false;
}
});
/** 删除button */
img_delete.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
isOnclick = false;
if (even % 2 == 0) {
if (linear_seekbar.getChildCount() > 1) {
linear_seekbar.removeViewAt(linear_seekbar.getChildCount() - 1);
linear_seekbar.removeViewAt(linear_seekbar.getChildCount() - 1);
}
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
File file = new File(list.get(list.size() - 1).getPath());
if (file.exists()) {
file.delete();
}
}
old -= list.get(list.size() - 1).getTime();
list.remove(list.size() - 1);
if (old < VIDEO_TIME * 1000) {
isMeet = false;
}
if (list.size() <= 0) {
img_delete.setVisibility(View.GONE);
img_enter.setVisibility(View.GONE);
img_video.setVisibility(View.VISIBLE);
img_camera.setVisibility(View.VISIBLE);
}
}
} else {
if (linear_seekbar.getChildCount() > 1) {
isOnclick = true;
((ImageView) linear_seekbar.getChildAt(linear_seekbar.getChildCount() - 2)).setBackgroundColor(getResources().getColor(
R.color.ff135689));
}
}
even++;
}
});
/** 开启或关闭闪光灯 */
img_flashlight.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
if (cameraPosition != 0) {// 前置摄像头的时候不能切换闪光灯
if (mParameters != null) {
if (mParameters.getFlashMode() != null && mParameters.getFlashMode().equals(Parameters.FLASH_MODE_TORCH)) {
mParameters.setFlashMode(Parameters.FLASH_MODE_OFF);
img_flashlight.setImageResource(R.drawable.img_video_new_flashlight_close);
} else if (mParameters.getFlashMode() != null && mParameters.getFlashMode().equals(Parameters.FLASH_MODE_OFF)) {
mParameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
img_flashlight.setImageResource(R.drawable.img_video_new_flashlight_open);
}
if (mCamera != null) {
mCamera.setParameters(mParameters);
}
}
}
}
});
/** 摄像头切换 */
img_camera.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
switchCamera();
}
}); /** 确认button */
img_enter.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
if (isMeet) { int size = list.size();
String[] strs = new String[size];
videoPath_merge = Ppath + System.currentTimeMillis() + ".mp4";
for (int i = 0; i < size; i++) {
strs[i] = list.get(i).getPath();
}
try {
FUckTest.appendVideo(strs, videoPath_merge); for (int i = size - 1; i >= 0; i--) {
File file = new File(list.get(i).getPath());
if (file.exists()) {
file.delete();
}
list.remove(i);
} Intent it = new Intent(VideoNewActivity.this,VideoActivity.class);
it.putExtra("path", videoPath_merge);
startActivity(it); } catch (IOException e) {
e.printStackTrace();
}
} else {
Toast.makeText(VideoNewActivity.this, "视频最少必须录制5秒以上才干用!", Toast.LENGTH_LONG).show();
}
}
});
/** 选择录像button */
img_video.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
//下一篇博客将会加进来
}
}); img_back.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
if (list.size() > 0) {
exitVideoNewDialog();
} else {
releaseCamera();
finish();
}
}
}); surfaceView.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
if (mParameters != null && mCamera != null) {
mParameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
try {
mCamera.setParameters(mParameters);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
} @Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
if (list.size() > 0) {
exitVideoNewDialog();
} else {
releaseCamera();
finish();
}
}
return true;
}
return super.dispatchKeyEvent(event);
} /**
* 弹出对话框
*
* @version 1.0
* @createTime 2015年6月16日,下午3:45:35
* @updateTime 2015年6月16日,下午3:45:35
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
*/
private void exitVideoNewDialog() { AlertDialog.Builder builder = new Builder(VideoNewActivity.this);
builder.setMessage("确定放弃这段视频吗?");
builder.setTitle("温馨提示");
builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
for (int i = 0; i < list.size(); i++) {
File file = new File(list.get(i).getPath());
if (file.exists()) {
file.delete();
}
}
finish();
} });
builder.create().show();
} /**
* 切换摄像头
*
* @version 1.0
* @createTime 2015年6月16日,上午10:40:17
* @updateTime 2015年6月16日,上午10:40:17
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
*/
@SuppressLint("NewApi")
private void switchCamera() {
// 切换前后摄像头
int cameraCount = 0;
CameraInfo cameraInfo = new CameraInfo();
cameraCount = Camera.getNumberOfCameras();// 得到摄像头的个数 for (int i = 0; i < cameraCount; i++) {
Camera.getCameraInfo(i, cameraInfo);// 得到每个摄像头的信息
if (cameraPosition == 1) {
// 如今是后置。变更为前置
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {// 代表摄像头的方位。CAMERA_FACING_FRONT前置
// CAMERA_FACING_BACK后置
// 前置摄像头时必须关闭闪光灯。不然会报错
if (mParameters != null) {
if (mParameters.getFlashMode() != null && mParameters.getFlashMode().equals(Parameters.FLASH_MODE_TORCH)) {
mParameters.setFlashMode(Parameters.FLASH_MODE_OFF);
img_flashlight.setImageResource(R.drawable.img_video_new_flashlight_close);
}
if (mCamera != null) {
mCamera.setParameters(mParameters);
}
} // 释放Camera
releaseCamera(); // 打开当前选中的摄像头
mCamera = Camera.open(i);
mCamera.setDisplayOrientation(90);
mCamera.lock(); // 通过surfaceview显示取景画面
setStartPreview(mHolder); cameraPosition = 0; break;
}
} else {
// 如今是前置, 变更为后置
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {// 代表摄像头的方位,CAMERA_FACING_FRONT前置
// CAMERA_FACING_BACK后置
// 释放Camera
releaseCamera();
// 打开当前选中的摄像头
mCamera = Camera.open(i);
mCamera.setDisplayOrientation(90);
mCamera.lock(); // 通过surfaceview显示取景画面
setStartPreview(mHolder); cameraPosition = 1; break;
}
} }
} /**
* 定义一个倒计时的内部类
*
* @Description
* @author
* @version 1.0
* @date 2015-5-25
* @Copyright: Copyright (c) 2015 Shenzhen Utoow Technology Co., Ltd.
* All rights reserved.
*/
private class TimeCount extends CountDownTimer {
public TimeCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);// 參数依次为总时长,和计时的时间间隔
} @Override
public void onFinish() {// 计时完成时触发 } @Override
public void onTick(long millisUntilFinished) {// 计时过程显示
now = (int) (30000 - millisUntilFinished - old);
if ((old > 0 && old > VIDEO_TIME * 1000) || (old == 0 && now > VIDEO_TIME * 1000)) {
img_enter.setEnabled(true);
}
if (linear_seekbar.getChildCount() > 0) {
ImageView img = (ImageView) linear_seekbar.getChildAt(linear_seekbar.getChildCount() - 1);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) img.getLayoutParams();
layoutParams.width = (int) (((float) now / 1000f) * (width / VIDEO_TIME_END)) + 1;
img.setLayoutParams(layoutParams);
}
}
} /**
* 初始化摄像头參数
*
* @version 1.0
* @createTime 2015年6月15日,下午4:53:41
* @updateTime 2015年6月15日,下午4:53:41
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
*/
@SuppressWarnings("deprecation")
private void initCameraParameters() {
// 初始化摄像头參数
mParameters = mCamera.getParameters(); mParameters.setPreviewSize(mProfile.videoFrameWidth, mProfile.videoFrameHeight);
mParameters.setPreviewFrameRate(mProfile.videoFrameRate); mParameters.setFocusMode(Parameters.FOCUS_MODE_AUTO); // 设置白平衡參数。 String whiteBalance = mPreferences.getString("pref_camera_whitebalance_key", "auto");
if (isSupported(whiteBalance, mParameters.getSupportedWhiteBalance())) {
mParameters.setWhiteBalance(whiteBalance);
} // 參数设置颜色效果。
String colorEffect = mPreferences.getString("pref_camera_coloreffect_key", "none");
if (isSupported(colorEffect, mParameters.getSupportedColorEffects())) {
mParameters.setColorEffect(colorEffect);
} try {
mCamera.setParameters(mParameters);
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 開始录制
*
* @version 1.0
* @createTime 2015年6月15日,下午4:48:49
* @updateTime 2015年6月15日,下午4:48:49
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
*/
@SuppressLint("NewApi")
private void startRecord() {
try {
bean = new VideoNewBean();
vedioPath = Ppath + System.currentTimeMillis() + ".mp4";
bean.setPath(vedioPath); mCamera.unlock();
mMediaRecorder = new MediaRecorder();// 创建mediaRecorder对象
mMediaRecorder.setCamera(mCamera);
// 设置录制视频源为Camera(相机)
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setProfile(mProfile); // mMediaRecorder.setVideoSize(560,560);//设置视频大小(分辨率) mMediaRecorder.setVideoEncodingBitRate(1024 * 1024);// 设置视频一次写多少字节(可调节视频空间大小) // 最大期限
mMediaRecorder.setMaxDuration(35 * 1000); // 第4步:指定输出文件 , 设置视频文件输出的路径 mMediaRecorder.setOutputFile(vedioPath); mMediaRecorder.setPreviewDisplay(mHolder.getSurface()); // // 设置保存录像方向
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
if (cameraPosition == 1) {
//因为不支持竖屏录制。后置摄像头须要把视频顺时针旋转90度、、可是视频本身在电脑上看还是逆时针旋转了90度
mMediaRecorder.setOrientationHint(90);
} else if (cameraPosition == 0) {
//因为不支持竖屏录制,前置摄像头须要把视频顺时针旋转270度、、而前置摄像头在电脑上则是顺时针旋转了90度
mMediaRecorder.setOrientationHint(270);
}
} mMediaRecorder.setOnInfoListener(new OnInfoListener() { @Override
public void onInfo(MediaRecorder mr, int what, int extra) { }
}); mMediaRecorder.setOnErrorListener(new OnErrorListener() { @Override
public void onError(MediaRecorder mr, int what, int extra) {
recodError();
}
}); // 第6步:依据以上配置准备MediaRecorder mMediaRecorder.prepare();
mMediaRecorder.start();
} catch (IllegalStateException e) {
e.printStackTrace();
recodError();
} catch (IOException e) {
e.printStackTrace();
recodError();
} catch (RuntimeException e) {
e.printStackTrace();
recodError();
} } /**
* 异常处理
*
* @version 1.0
* @createTime 2015年6月16日,上午10:49:18
* @updateTime 2015年6月16日,上午10:49:18
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
*/
private void recodError() {
AlertDialog.Builder builder = new Builder(VideoNewActivity.this);
builder.setMessage("该设备暂不支持视频录制");
builder.setTitle("出错啦");
builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
} });
builder.create().show(); } /**
* 结束录制
*
* @version 1.0
* @createTime 2015年6月15日,下午4:48:53
* @updateTime 2015年6月15日,下午4:48:53
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
*/
private void stopRecord() { if (bean != null) {
if (list.size() > 0) {
bean.setTime(now - list.get(list.size() - 1).getTime());
} else {
bean.setTime(now);
}
bean.setCameraPosition(cameraPosition);
list.add(bean);
} if (mMediaRecorder != null) {
try {
// 停止录像,释放camera
mMediaRecorder.setOnErrorListener(null);
mMediaRecorder.setOnInfoListener(null);
mMediaRecorder.stop();
// 清除recorder配置
mMediaRecorder.reset();
// 释放recorder对象
mMediaRecorder.release();
mMediaRecorder = null;
// 没超过3秒就删除录制全部数据
if (old < 3000) {
clearList();
}
} catch (Exception e) {
clearList();
}
}
} /**
* 清楚数据
*
* @version 1.0
* @createTime 2015年6月25日,下午6:04:28
* @updateTime 2015年6月25日,下午6:04:28
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
*/
private void clearList() {
Toast.makeText(VideoNewActivity.this, "单次录制视频最少3秒", Toast.LENGTH_LONG).show();
if (linear_seekbar.getChildCount() > 1) {
linear_seekbar.removeViewAt(linear_seekbar.getChildCount() - 1);
linear_seekbar.removeViewAt(linear_seekbar.getChildCount() - 1);
}
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
File file = new File(list.get(list.size() - 1).getPath());
if (file.exists()) {
file.delete();
}
}
list.remove(list.size() - 1);
if (list.size() <= 0) {
img_delete.setVisibility(View.GONE);
img_enter.setVisibility(View.GONE);
img_video.setVisibility(View.VISIBLE);
img_camera.setVisibility(View.VISIBLE);
}
}
} private static boolean isSupported(String value, List<String> supported) {
return supported == null ? false : supported.indexOf(value) >= 0;
} public static boolean getVideoQuality(String quality) {
return "youtube".equals(quality) || "high".equals(quality);
} /**
* 设置摄像头參数
*
* @version 1.0
* @createTime 2015年6月15日,下午5:12:31
* @updateTime 2015年6月15日,下午5:12:31
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
*/
private void readVideoPreferences() {
String quality = mPreferences.getString("pref_video_quality_key", "high"); boolean videoQualityHigh = getVideoQuality(quality); // 设置视频质量。
Intent intent = getIntent();
if (intent.hasExtra(MediaStore.EXTRA_VIDEO_QUALITY)) {
int extraVideoQuality = intent.getIntExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
videoQualityHigh = (extraVideoQuality > 0);
} videoQualityHigh = false;
mProfile = CamcorderProfile.get(videoQualityHigh ? CamcorderProfile.QUALITY_HIGH : CamcorderProfile.QUALITY_LOW);
mProfile.videoFrameWidth = (int) (mProfile.videoFrameWidth * 2.0f);
mProfile.videoFrameHeight = (int) (mProfile.videoFrameHeight * 2.0f);
mProfile.videoBitRate = 256000 * 3; CamcorderProfile highProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
mProfile.videoCodec = highProfile.videoCodec;
mProfile.audioCodec = highProfile.audioCodec;
mProfile.fileFormat = MediaRecorder.OutputFormat.MPEG_4;
} /**
* 加入红色进度条
*
* @version 1.0
* @createTime 2015年6月15日,下午3:04:21
* @updateTime 2015年6月15日,下午3:04:21
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
*/
private void addView_Red() {
ImageView img = new ImageView(VideoNewActivity.this);
img.setBackgroundColor(getResources().getColor(R.color.ff1f8fe4));
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(DisplayUtil.dip2px(VideoNewActivity.this, 1), LinearLayout.LayoutParams.MATCH_PARENT);
img.setLayoutParams(layoutParams);
linear_seekbar.addView(img);
} /**
* 加入黑色断条
*
* @version 1.0
* @createTime 2015年6月15日,下午3:03:52
* @updateTime 2015年6月15日,下午3:03:52
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
*/
private void addView_black() {
ImageView img = new ImageView(VideoNewActivity.this);
img.setBackgroundColor(Color.BLACK);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(DisplayUtil.dip2px(VideoNewActivity.this, 2), LinearLayout.LayoutParams.MATCH_PARENT);
img.setLayoutParams(layoutParams);
linear_seekbar.addView(img);
} @Override
public void surfaceCreated(SurfaceHolder holder) {
setStartPreview(holder); } @Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // 先开启在关闭 先开启录制在关闭能够 解决游览的时候比較卡顿的现象,可是会有视频开启时声音。打开这个功能时较慢
// startRecord();
// stopRecord();
} @Override
public void surfaceDestroyed(SurfaceHolder holder) {
releaseCamera();
} /**
* 设置camera显示取景画面,并预览
*
* @version 1.0
* @createTime 2015年6月16日,上午10:48:15
* @updateTime 2015年6月16日,上午10:48:15
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
* @param holder
*/
private void setStartPreview(SurfaceHolder holder) {
try {
if (mCamera != null) {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
} catch (IOException e) { }
} /**
* 释放Camera
*
* @version 1.0
* @createTime 2015年6月16日,上午10:38:08
* @updateTime 2015年6月16日,上午10:38:08
* @createAuthor WangYuWen
* @updateAuthor WangYuWen
* @updateInfo (此处输入改动内容,若无改动可不写.)
*
*/
private void releaseCamera() {
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCamera.stopPreview();// 停掉原来摄像头的预览
mCamera.release();
mCamera = null;
}
} }

核心代码就这么点。bean之类的其它工具类的没贴出来,假设须要看效果的朋友能够去下载demo;

希望大家多多关注我的博客。多多支持我。

如有好意见或更好的方式欢迎留言谈论。

尊重原创转载请注明:(http://blog.csdn.net/u013895206) 。

以下是地址传送门:

http://download.csdn.net/detail/u013895206/8850751

android 视频开发2分之1(仿美拍,糗百)的更多相关文章

  1. android 视频开发2分之2(仿美拍,糗百)

    上一篇写了分段录制和合并视频.这一篇则是选择视频,然后截断视频. 1.从sdcard中找到视频资源: 2.分析视频,拿到你须要的帧数当你的图片.(我的是依据參数来算的多少秒1帧的图片,通常是1秒1帧来 ...

  2. Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

  3. Android IOS WebRTC 音视频开发总结(八十三)-- 使用WebRTC广播网络摄像头视频(上)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

  4. 本人讲课时录制的Android应用开发技术教学视频

    网盘地址:http://yun.baidu.com/pcloud/album/info?query_uk=1963923831&album_id=3523786484935252365 本人讲 ...

  5. 移动开发 android 入门开发 阶段视频

    一直想把 android 的开发学习录制成视频,这里录制了一部分供大家学习. http://www.chuanke.com/s5402069.html 到这里,文档,源码,视频基本就全了,祝愿大家能够 ...

  6. Android IOS WebRTC 音视频开发总结(四六)-- 从另一个角度看国内首届WebRTC大会

    文章主要从开发者角度谈国内首届WebRTC大会,支持原创,文章来自博客园RTC.Blacker,支持原创,转载必须说明出处,更多详见www.rtc.help. -------------------- ...

  7. Android IOS WebRTC 音视频开发总结(六)-- iOS开发之含泪经验

    前段时间在搞webrtc iOS开发,所以将标题改为了Android IOS WebRTC 音视频开发总结, 下面都是开发过程中的经验总结,转载请说明出处(博客园RTC.Blacker): 1. IO ...

  8. Android 音视频开发学习思路

    Android 音视频开发这块目前的确没有比较系统的教程或者书籍,网上的博客文章也都是比较零散的.只能通过一点点的学习和积累把这块的知识串联积累起来. 初级入门篇: Android 音视频开发(一) ...

  9. Android 音视频开发(一) : 通过三种方式绘制图片

    版权声明:转载请说明出处:http://www.cnblogs.com/renhui/p/7456956.html 在 Android 音视频开发学习思路 里面,我们写到了,想要逐步入门音视频开发,就 ...

随机推荐

  1. 通过创建元素从而实现三个下拉框的联动效果(create.Element("option"))和提交表单时的验证p.match("请选择")

    <html> <head> <meta charset="utf-8"> <title>下拉框</title> < ...

  2. 图灵机(转自wiki)

    图灵机(英语:Turing machine),又称确定型图灵机,是英国数学家艾伦·图灵于1936年提出的一种抽象计算模型,其更抽象的意义为一种数学逻辑机,可以看作等价于任何有限逻辑数学过程的终极强大逻 ...

  3. Ubuntu下查看服务器cpu是否支持VT

    http://blog.51cto.com/zhangmingqian/1249522 Ubuntu下查看服务器cpu是否支持VT 原创wazjajl 2013-07-15 16:25评论(0)119 ...

  4. Android Error:Failed to resolve: com.afollestad:material-dialogs:

    背景: 同事把Android项目直接考给了我...我在Android Studio上运行,然后提示: Error:Failed to resolve: com.afollestad:material- ...

  5. React组件的防呆机制(propTypes)

    Prop验证 随着应用不断变大,为了保证组件被正确使用变得越来越重要.为此我们引入propsTypes.React.PropTypes提供很多验证器(valodator)来验证传入的数据的有效性.当向 ...

  6. list.sort结果是None

    错误原因:  list.sort()功能是针对列表自己内部进行排序, 不会有返回值, 因此返回为None.  举例说明: In [19]: a=["a","c" ...

  7. 手机中快速看图,浏览编辑DWG 梦想极光CAD

    梦想极光CAD6.0(2016.3.1) 手机版最新更新 1.增加手机上,图纸浏览时预览功能 2.增加直接从手机,QQ接收目录下加载文件功能 3.手机交互界面优化 4.增加新建图纸功能 5.增加缓存功 ...

  8. 梦想CAD控件COM接口光栅图处理

    在CAD操作过程中,我们在设计绘图时,光栅图像也就是我们常说的图片,应用非常广泛,在CAD中可以直接插入光栅图像,并且可以对光栅图像进行裁剪.透明度调整等一些操作,在网页可以快速实现我们所需功能. 一 ...

  9. Result(ActionResult、JsonResult、JavaScriptResult等)

    一丶ActionResult 应用于Action方法前面的类型,它是Action的返回值,代表Action的执行结果. public ActionResult Index() { return Vie ...

  10. 散列--P1047 校门外的树

    题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,-,L,都种有 ...