1,功能说明:模仿QQ录制视频界面,可以传入路径播放(一定要在surfaceChanged);也可以录制视频并播放
,或者发送(通过setResult返回值)
2,遇到的坑:通过传入路径播放的话,一定要让surfaceview在图层上显示出来,不能被其他view遮挡,否则会出现有声音无图像的现象
java代码
import java.io.File;
import java.util.Calendar;
import com.dami.student.MyApplication;
import com.dami.student.R;
import android.app.Activity;
import android.hardware.Camera;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Bundle;
import android.content.Intent;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.content.Context;
import android.view.MotionEvent;
import com.dami.student.ui.chatui.widget.CircleImageView;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.view.View;
import android.view.View.OnClickListener;
import com.dami.student.net.utils.LogUtil;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class ShootingActivity extends Activity implements
SurfaceHolder.Callback,OnClickListener,OnTouchListener{
private static final String TAG = "MainActivity";
private final int RESULT_SHOOTNG = 4;
private LinearLayout LL_top;
private LinearLayout LL_bottom;
private SurfaceView mSurfaceview;
private Button mBtnsend;
private Button mBtnResetShooting;
private CircleImageView mCircleImageView;
private boolean mIsPlay = false;// 是否正在播放录像
private MediaRecorder mRecorder;
private SurfaceHolder mSurfaceHolder;
private ImageView mExitShootingIM;
private Camera camera;
private MediaPlayer mediaPlayer;
private String path = null;
private String videoPath;
private TextView mTimeTV;
private int time = 0;
private android.os.Handler handler = new android.os.Handler();
private Runnable runnable = new Runnable() {
@Override
public void run() {
time++;
mTimeTV.setText(time + "");
handler.postDelayed(this, 1000);
}
};
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_shooting);
inIt();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btnsend:
Intent intent = new Intent();
intent.putExtra("data", path);
setResult(-1, intent);
finish();
break;
case R.id.exit_shooting_IM:
finish();
break;
case R.id.btn_reset_shooting:
resetShooting();
break;
case R.id.surfaceview:
finish();
break;
default:
break;
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.start_shooting:
if (event.getAction() == MotionEvent.ACTION_DOWN) {
startShooting();
}else if (event.getAction() == MotionEvent.ACTION_UP) {
StopShooting();
playVideo(path);
}
break;
default:
break;
}
return true;
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
mSurfaceHolder = surfaceHolder;
LogUtil.i(TAG, "wdh surfaceCreated path "+path);
if (null == videoPath) {
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
if (camera != null) {
try {
camera.setPreviewDisplay(mSurfaceHolder);
camera.setDisplayOrientation(90);
camera.startPreview();
} catch (Exception e) {
// TODO: handle exception
LogUtil.i(TAG, "wdh surfaceCreated"+e);
}
}
}
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1,
int i2) {
// 将holder,这个holder为开始在onCreate里面取得的holder,将它赋给mSurfaceHolder
LogUtil.i(TAG, "wdh -----------------surfaceChanged");
mSurfaceHolder = surfaceHolder;
if (null != videoPath) {//传进来路径播放
playVideo(videoPath);
}
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
mSurfaceview = null;
mSurfaceHolder = null;
handler.removeCallbacks(runnable);
if (mRecorder != null) {
mRecorder.release();
mRecorder = null;
Log.d(TAG, "surfaceDestroyed release mRecorder");
}
if (camera != null) {
camera.release();
camera = null;
}
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
}
private void inIt() {
// TODO Auto-generated method stub
LL_top = (LinearLayout)findViewById(R.id.LL_top);
LL_bottom = (LinearLayout)findViewById(R.id.LL_bottom);
mSurfaceview = (SurfaceView) findViewById(R.id.surfaceview);
mExitShootingIM = (ImageView) findViewById(R.id.exit_shooting_IM);
mExitShootingIM.setOnClickListener(this);
mBtnResetShooting = (Button) findViewById(R.id.btn_reset_shooting);
mBtnResetShooting.setOnClickListener(this);
mBtnsend = (Button) findViewById(R.id.btnsend);
mBtnsend.setOnClickListener(this);
mTimeTV = (TextView) findViewById(R.id.time_TV);
mCircleImageView = (CircleImageView)findViewById(R.id.start_shooting);
mCircleImageView.setOnTouchListener(this);
videoPath = getIntent().getStringExtra("videoPath");
LogUtil.i(TAG, "wdh videoPath"+videoPath);
if (null != videoPath) {
LL_top.setVisibility(View.GONE);
LL_bottom.setVisibility(View.GONE);
mSurfaceview.setOnClickListener(this);
}else {
LL_top.setVisibility(View.VISIBLE);
LL_bottom.setVisibility(View.VISIBLE);
}
SurfaceHolder holder = mSurfaceview.getHolder();
holder.addCallback(this);
// setType必须设置,要不出错.
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
/**
* 开始播放
* */
private void playVideo(String videoPath){
LogUtil.i(TAG, "wdh -----------------playVideo");
mIsPlay = true;
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
}
mediaPlayer.reset();
Uri uri = Uri.parse(videoPath);
mediaPlayer = MediaPlayer.create(ShootingActivity.this, uri);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDisplay(mSurfaceHolder);
try {
mediaPlayer.prepare();
} catch (Exception e) {
e.printStackTrace();
}
mediaPlayer.start();
mediaPlayer.setLooping(true);//设置重复播放
}
/**
* 获取系统时间
*
* @return
*/
public static String getDate() {
Calendar ca = Calendar.getInstance();
int year = ca.get(Calendar.YEAR); // 获取年份
int month = ca.get(Calendar.MONTH); // 获取月份
int day = ca.get(Calendar.DATE); // 获取日
int minute = ca.get(Calendar.MINUTE); // 分
int hour = ca.get(Calendar.HOUR); // 小时
int second = ca.get(Calendar.SECOND); // 秒
String date = "" + year + (month + 1) + day + hour + minute + second;
Log.d(TAG, "date:" + date);
return date;
}
/**
* 开始录制
* */
private void startShooting(){
mTimeTV.setVisibility(View.VISIBLE);
mCircleImageView.setVisibility(View.VISIBLE);
mBtnsend.setVisibility(View.INVISIBLE);
mBtnResetShooting.setVisibility(View.INVISIBLE);
if (mIsPlay) {
if (mediaPlayer != null) {
mIsPlay = false;
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer = null;
}
}
handler.postDelayed(runnable, 1000);
if (mRecorder == null) {
mRecorder = new MediaRecorder();
}
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
if (camera != null) {
camera.setDisplayOrientation(90);
camera.unlock();
mRecorder.setCamera(camera);
}
try {
// 这两项需要放在setOutputFormat之前
mRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Set output file format
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
// 这两项需要放在setOutputFormat之后
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mRecorder.setVideoSize(640, 480);
mRecorder.setVideoFrameRate(30);
mRecorder.setVideoEncodingBitRate(3 * 1024 * 1024);
mRecorder.setOrientationHint(90);
// 设置记录会话的最大持续时间(毫秒)
mRecorder.setMaxDuration(10 * 1000);
mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
path = MyApplication.LOCAL_FILE_PATH;
if (path != null) {
File dir = new File(path + "/recordtest");
if (!dir.exists()) {
dir.mkdir();
}
path = dir + "/" + getDate() + ".mp4";
mRecorder.setOutputFile(path);
mRecorder.prepare();
mRecorder.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 停止录制
* */
private void StopShooting(){
mTimeTV.setVisibility(View.INVISIBLE);
mBtnsend.setVisibility(View.VISIBLE);
mBtnResetShooting.setVisibility(View.VISIBLE);
mCircleImageView.setVisibility(View.INVISIBLE);
// stop
try {
handler.removeCallbacks(runnable);
mRecorder.stop();
mRecorder.reset();
mRecorder.release();
mRecorder = null;
time = 0;
if (camera != null) {
camera.release();
camera = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 重新录制
* */
private void resetShooting(){
time = 0;
mTimeTV.setText(time + "");
mTimeTV.setVisibility(View.VISIBLE);
mCircleImageView.setVisibility(View.VISIBLE);
mBtnsend.setVisibility(View.INVISIBLE);
mBtnResetShooting.setVisibility(View.INVISIBLE);
if (mIsPlay) {
if (mediaPlayer != null) {
mIsPlay = false;
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer = null;
}
}
if (mRecorder != null) {
mRecorder.release();
mRecorder = null;
}
if (null == camera) {
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
}
if (camera != null) {
try {
camera.setPreviewDisplay(mSurfaceHolder);
camera.setDisplayOrientation(90);
camera.startPreview();
} catch (Exception e) {
// TODO: handle exception
LogUtil.i(TAG, "wdh surfaceCreated"+e);
}
}
}
}
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<SurfaceView
android:id="@+id/surfaceview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/imageview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="60dp"
android:visibility="gone"
android:src="@drawable/ic_launcher"/>
<Button
android:id="@+id/btnStartStop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:text="@string/shooting_start"/>
<Button
android:id="@+id/btnPlayVideo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toLeftOf="@id/btnStartStop"
android:text="@string/play"
android:layout_marginRight="20dp"/>
<Button
android:id="@+id/btnsend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toRightOf="@id/btnStartStop"
android:text="@string/send"
android:layout_marginLeft="20dp"/>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:textColor="@color/white"
android:text="@string/time_start"
android:layout_alignParentTop="true"
android:layout_marginTop="12dp"
android:layout_marginLeft="20dp"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
原文地址:http://blog.csdn.net/woshizisezise/article/details/51878566