android录制视屏(预览,倒计时)

  android用mediarecord录制视屏,可以设置视屏格式,大小,还有拍摄前预览,倒计时功能要自己用hander做。

  1,CameraPreview.java

//预览class

public class CameraPreview extends SurfaceView implements Callback {

private static final String TAG = "TAG-CameraPreview";

private SurfaceHolder mHolder;
private Camera mCamera;

public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;

// 安装一个SurfaceHolder.Callback
mHolder = getHolder();
mHolder.addCallback(this);

// 针对低于3.0的Android
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public void surfaceCreated(SurfaceHolder holder) {
// 把预览画面的位置通知摄像头
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}

public void surfaceDestroyed(SurfaceHolder holder) {
// TODO
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

if (mHolder.getSurface() == null){
// 预览surface不存在
return;
}

// 更改时停止预览
try {
mCamera.stopPreview();
} catch (Exception e){

}

// 在此进行缩放、旋转和重新组织格式
// 以新的设置启动预览
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}

}

  2,RecordMp4.java

public class RecordMp4 extends Activity implements SurfaceHolder.Callback {

private Button mStopButton;

// private SurfaceView mSurfaceView;

private SurfaceHolder mSurfaceHolder;

private MediaRecorder mMediaRecorder;

private String path, pid, uid;

private CheckBox playOrStop;

private Camera mCamera;

private CameraPreview mSurfaceView;

private TextView recor_mp4_left_time;

private int second = 20;

Handler handler;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// 去掉标题栏

requestWindowFeature(Window.FEATURE_NO_TITLE);

// 设置全屏

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,

WindowManager.LayoutParams.FLAG_FULLSCREEN);

// 设置横屏显示

setContentView(R.layout.record_mp4);

handler = new Handler();

pid = getIntent().getStringExtra("pid");

uid = getIntent().getStringExtra("uid");

init();

}

private void init() {

playOrStop = (CheckBox) findViewById(R.id.etsound_playstop);

playOrStop.setOnClickListener(new ClickListenerImpl());

recor_mp4_left_time = (TextView) findViewById(R.id.recor_mp4_left_time);

mCamera = getCameraInstance();

// 创建Preview view并将其设为activity中的内容

mSurfaceView = new CameraPreview(this, mCamera);

FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);

preview.addView(mSurfaceView);

mSurfaceHolder = mSurfaceView.getHolder();

mSurfaceHolder.addCallback(this);

mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

}

Runnable runnable = new Runnable() {

@Override

public void run() {

second--;

if (second <= 0) {

handler.removeCallbacks(this);

} else {

recor_mp4_left_time.setText("还剩" + second + "s");

handler.postDelayed(this, 1000);

}

}

};

private Camera getCameraInstance() {

Camera c = null;

try {

// 获取Camera实例

c = Camera.open();

c.setDisplayOrientation(90);

} catch (Exception e) {

// 摄像头不可用(正被占用或不存在)

}

// 不可用则返回null

return c;

}

@SuppressLint("NewApi")

private void initMediaRecorder() {

// next codes is right for 2.3 and 4.0

mMediaRecorder = new MediaRecorder();

// mCamera = Camera.open();

// mCamera.setDisplayOrientation(90);

mCamera.unlock();

mMediaRecorder.setCamera(mCamera);

// 设置视频源

mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

mMediaRecorder.setOrientationHint(90);// 视频旋转90度

// 设置音频源

mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);

// 设置文件输出格式

mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

// 设置视频编码方式

mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

// 设置音频编码方式

mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

// 设置视频高和宽,注意文档的说明:

// Must be called after setVideoSource().

// Call this after setOutFormat() but before prepare().

// 设置录制的视频帧率,注意文档的说明:

// Must be called after setVideoSource().

// Call this after setOutFormat() but before prepare().

mMediaRecorder.setVideoFrameRate(16);

// 设置预览画面

mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());

// 设置输出路径

path =  this.getFilesDir().getAbsolutePath()+File.separator+System.currentTimeMillis()+".mp4";

mMediaRecorder.setOutputFile(path);

mMediaRecorder.setVideoSize(640, 480);

// 设置视频的最大持续时间

mMediaRecorder.setMaxDuration(20000);

// 为MediaRecorder设置监听

mMediaRecorder.setOnInfoListener(new OnInfoListener() {

public void onInfo(MediaRecorder mr, int what, int extra) {

if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {

TCommUtil.showToast(RecordMp4.this, "已经达到最长录制时间", true);

System.out.println("已经达到最长录制时间");

if (mMediaRecorder != null) {

mMediaRecorder.stop();

mMediaRecorder.release();

mMediaRecorder = null;

}

}

}

});

}

private class ClickListenerImpl implements OnClickListener {

public void onClick(View v) {

CheckBox checkBox = (CheckBox) v;

if (checkBox.getId() == R.id.etsound_playstop) {

if (mMediaRecorder == null) {

try {

initMediaRecorder();

mMediaRecorder.prepare();

mMediaRecorder.start();

handler.postDelayed(runnable, 0);

} catch (IllegalStateException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

} else {

if (mMediaRecorder != null) {

mMediaRecorder.stop();

releaseMediaRecorder();

mCamera.lock();

}

}

}

}

}

@Override

protected void onPause() {

super.onPause();

handler.removeCallbacks(runnable);

// 如果正在使用MediaRecorder,首先需要释放它。

releaseMediaRecorder();

// 在暂停事件中立即释放摄像头

releaseCamera();

}

private void releaseMediaRecorder() {

if (mMediaRecorder != null) {

// 清除recorder配置

handler.removeCallbacks(runnable);

mMediaRecorder.reset();

// 释放recorder对象

mMediaRecorder.release();

mMediaRecorder = null;

// 为后续使用锁定摄像头

mCamera.lock();

}

}

private void releaseCamera() {

if (mCamera != null) {

// 为其它应用释放摄像头

mCamera.release();

mCamera = null;

}

}

// SurfaceHolder.Callback接口

public void surfaceCreated(SurfaceHolder holder) {

try {

} catch (IllegalStateException e) {

e.printStackTrace();

}

}

//  在 surfaceChanged以后,才在 initMediaRecorder()方法里 MediaRecorder 变量设置参数,不然 会在

//mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 出报错。

public void surfaceChanged(SurfaceHolder holder, int format, int width,

int height) {

System.out.println("SurfaceView---->Changed");

}

public void surfaceDestroyed(SurfaceHolder holder) {

System.out.println("SurfaceView---->Destroyed");

if (mMediaRecorder != null) {

mMediaRecorder.stop();

mMediaRecorder.release();

mMediaRecorder = null;

}

}

}

  3,record_mp4.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"

android:background="@color/solid_white" >

<FrameLayout

android:id="@+id/camera_preview"

android:layout_width="match_parent"

android:layout_height="match_parent" >

</FrameLayout>

<RelativeLayout

android:id="@+id/etsound_rlcontent"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_alignParentBottom="true"

android:background="@color/transparent"

android:clickable="true"

android:focusable="true"

android:focusableInTouchMode="true"

android:visibility="visible" >

<TextView

android:id="@+id/recor_mp4_left_time"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentTop="true"

android:layout_centerHorizontal="true"

android:layout_marginTop="10dp"

android:textColor="@color/titlebar_bg"

android:text="20s"

android:textSize="25sp" />

<FrameLayout

android:id="@+id/etsound_playstop_fl"

android:layout_width="100dp"

android:layout_height="100dp"

android:layout_alignParentBottom="true"

android:layout_centerHorizontal="true"

android:background="@drawable/round_video" >

<CheckBox

android:id="@+id/etsound_playstop"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:background="@drawable/play_video_stop_selector"

android:button="@null"

android:padding="10dp" />

</FrameLayout>

</RelativeLayout>

</RelativeLayout>

android录制视屏(预览,倒计时),布布扣,bubuko.com

时间: 2024-12-30 15:31:03

android录制视屏(预览,倒计时)的相关文章

Android中用Bitmap画图预览,视频图像分辨率是320x240(4:3),手机分辨率是540x960(9:16),图像被拉伸怎么办?

问题描述 使用V4L2进行视频采集,采集到的视频数据分辨率为320x240(4:3),使用Canvas,drawBitmap方式在Android设备上预览图像 Android设备分辨率为 540x960(9:16),所以全屏预览时图像被拉伸,这种问题如何解决? 没思路啊,哪位大神指导指导!! 下面是画图像的代码,大神们帮忙看看 public void run() { //获取屏幕信息 DisplayMetrics dm = new DisplayMetrics(); getWindowManag

玩转Android Camera开发(四):预览界面四周暗中间亮,只拍摄矩形区域图片(附完整源码)

杂家前文曾写过一篇关于只拍摄特定区域图片的demo,只是比较简陋,在坐标的换算上不是很严谨,而且没有完成预览界面四周暗中间亮的效果,深以为憾,今天把这个补齐了. 在上代码之前首先交代下,这里面存在着换算的两种模式.第一种,是以屏幕上的矩形区域为基准进行换算.举个例子,屏幕中间一个 矩形框为100dip*100dip.这里一定要使用dip为单位,否则在不同的手机上屏幕呈现的矩形框大小不一样.先将这个dip换算成px,然后根据屏幕的宽和高的像素计算出矩形区域,传给Surfaceview上铺的一层Vi

eclipse创建android项目无法正常预览布局文件

eclipse创建android项目时,预览layout.xml文件时提示: This version of the rendering library is more recent than your version of ADT plug-in. Please update ADT plug-in,导致无法正常预览布局文件.问题根源:SDK版本过高,ADT版本过低.解决方法如下. 工具/原料 eclipse ADT插件 方法/步骤 1 找到eclipse文件夹,打开eclipse软件,创建a

js 实现全屏预览(F11功能)--转

js代码 1 function fullScreen(el) { 2 var rfs = el.requestFullScreen || el.webkitRequestFullScreen || el.mozRequestFullScreen || el.msRequestFullScreen, 3 wscript; 4 5 if(typeof rfs != "undefined" && rfs) { 6 rfs.call(el); 7 return; 8 } 9 1

Android开发中遇到的问题(三)——eclipse创建android项目无法正常预览布局文件

一.问题描述 今天使用SDK Manager将Android SDK的版本更新到了Android 5.1的版本,eclipse创建android项目时,预览activity_main.xml文件时提示: This version of the rendering library is more recent than your version of ADT plug-in. Please update ADT plug-in,导致无法正常预览布局文件,现象如下图所示: 上网查了一下原因,问题根源

图片无损放大软件PhotoZoom分屏预览功能 ,简直好用!

PhotoZoom是一款智能放大图片软件,很多用户在初次使用PhotoZoom,发现图片所处的区域上方有四个不同方式的预览选项.因为很多初学者使用时不明白这四个按钮有什么作用,所以小编接下来讲解一下PhotoZoom的分屏预览功能. 使用分屏按钮可将预览窗口分成不同部分.每个部分可以单独更改不同的调整大小方法.这样您就可以同时预览不同调整方法的结果,进行实时对比.例如,您可以对比 S-Spline XL 方法与双立方插值方法的异同,或选择两种 S-Spline XL 预设互相对比. 您可以使用以

玩转Android Camera开发(四):预览界面四周暗中间亮,仅仅拍摄矩形区域图片(附完整源代码)

杂家前文曾写过一篇关于仅仅拍摄特定区域图片的demo.仅仅是比較简陋.在坐标的换算上不是非常严谨,并且没有完毕预览界面四周暗中间亮的效果,深以为憾.今天把这个补齐了. 在上代码之前首先交代下,这里面存在着换算的两种模式.第一种,是以屏幕上的矩形区域为基准进行换算.举个样例.屏幕中间一个 矩形框为100dip*100dip.这里一定要使用dip为单位,否则在不同的手机上屏幕呈现的矩形框大小不一样. 先将这个dip换算成px.然后依据屏幕的宽和高的像素计算出矩形区域,传给Surfaceview上铺的

Android - 关于Fragment的预览问题

关于Fragment的预览问题 本文地址:http://blog.csdn.net/caroline_wendy 在Activity中,添加Fragment,因为是动态加载,所以无法预览,会产生Rendering Problem: 但是可以选择一个预览Fragment,使用:tools:layout="@layout/fragment_status",就可以预览: 代码: <?xml version="1.0" encoding="utf-8&quo

android 图片选择器 图片预览

需求:近段时间公司有要求写一个类似于微信发送图片时,用来选择照片的一个图片浏览器,本来想在网上找一个直接拿来用,找寻无果,只能自己写了.相信有很多网页也有这样的需求,这里我将写好的源码打包成library工程分享给大家!! 转载请注明出处:http://blog.csdn.net/a740169405/article/details/41622025 说明: ①本来打算自己写图片异步加载代码,后来因为赶时间,就改成直接引用开源框架universal-image-loader,一个