Android仿微信长按录制视频并播放功能

作者:志尊宝 时间:2023-02-16 23:26:33 

本文实例为大家分享了Android仿微信长按录制视频并播放功能的具体代码,供大家参考,具体内容如下

一、点击按钮进行录制

首先要获取摄像拍照的权限和读取权限


<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

布局文件如下:


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@+id/activity_main"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   tools:context="com.yus.videorecording.MainActivity">

<Button
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:id="@+id/open"
       android:text="开始录制"
       />
</RelativeLayout>

二、录制时的主要代码,录制完成保存到本地,在进行播放:


public class VideoRecordActivity extends Activity implements MediaRecorder.OnErrorListener, View.OnClickListener {
   private ImageView iv_cancel,iv_save;
   private SurfaceView mSurfaceView;
   private SurfaceHolder mSurfaceHolder;
   private MediaRecorder mMediaRecorder;
   private Camera mCamera;

private CircleButtonView cbv_record;
   private File mRecordFile = null;// 文件
   private int mRotationRecord=90;//视频输出角度 0横屏  90竖屏  180反横屏
   private boolean isRecording;//正在录制
   private float mWindowW;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
       //全屏无标题
       requestWindowFeature(Window.FEATURE_NO_TITLE);
       getWindow().setFlags(WindowManager.LayoutParams. FLAG_FULLSCREEN ,
               WindowManager.LayoutParams. FLAG_FULLSCREEN);
       super.onCreate(savedInstanceState);
       setContentView(R.layout.video_record_activity);
       initView();
       initData();
       setListener();
   }

private void initData() {
       DisplayMetrics metric = new DisplayMetrics();
       getWindowManager().getDefaultDisplay().getMetrics(metric);
       mWindowW = metric.widthPixels;     // 屏幕宽度(像素)

}

@Override
   protected void onResume() {
       super.onResume();
       cbv_record.setVisibility(View.VISIBLE);
       iv_cancel.setVisibility(View.GONE);
       iv_save.setVisibility(View.GONE);
       if(mRecordFile!=null){
           mRecordFile.getAbsoluteFile().delete();
       }
   }

private void setListener() {
       cbv_record.setOnLongClickListener(new CircleButtonView.OnLongClickListener() {
           @Override
           public void onLongClick() {
               isRecording=true;
               startRecord();
           }

@Override
           public void onNoMinRecord(int currentTime) {
               isRecording=false;
               Toast.makeText(VideoRecordActivity.this, "录制视频太短", Toast.LENGTH_SHORT).show();
               if(mRecordFile.getAbsoluteFile()!=null){
                   mRecordFile.getAbsoluteFile().delete();
               }
           }

@Override
           public void onRecordFinishedListener() {
               Log.e("yufs","视频录制完成:path=="+mRecordFile.getAbsolutePath());
               isRecording=false;
               stopRecord();
               cbv_record.setVisibility(View.GONE);
               iv_cancel.setVisibility(View.VISIBLE);
               iv_save.setVisibility(View.VISIBLE);
           }
       });

//手机旋转监听
       OrientationEventListener orientationEventListener=new OrientationEventListener(this) {
           @Override
           public void onOrientationChanged(int rotation) {
               //录制的过程不改变
               if(isRecording){
                   return;
               }
               if (((rotation >= 0) && (rotation <= 30)) || (rotation >= 330)) {
                   // 竖屏拍摄
                   mRotationRecord=90;
               } else if (((rotation >= 230) && (rotation <= 310))) {
                   // 横屏拍摄
                   mRotationRecord=0;
               } else if (rotation > 30 && rotation < 95) {
                   // 反横屏拍摄
                   mRotationRecord=180;
               }
           }
       };
       orientationEventListener.enable();

iv_cancel.setOnClickListener(this);
       iv_save.setOnClickListener(this);
   }

private void startRecord() {
       //初始录制视频保存路径
       createRecordDir();
       try {
           initCamera();
           initRecord();
       }catch (Exception e){
           e.printStackTrace();
       }
   }

private void initView() {
       iv_cancel= (ImageView) findViewById(R.id.iv_cancel);
       iv_save= (ImageView) findViewById(R.id.iv_save);
       mSurfaceView= (SurfaceView) findViewById(R.id.sv_video);
       cbv_record= (CircleButtonView) findViewById(R.id.cbv_record);
       mSurfaceHolder = mSurfaceView.getHolder();
       mSurfaceHolder.addCallback(new CustomCallBack());
       mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
   }

@Override
   public void onClick(View v) {
       switch (v.getId()){
           case R.id.iv_cancel:
               cbv_record.setVisibility(View.VISIBLE);
               mRecordFile.getAbsoluteFile().delete();
               iv_cancel.setVisibility(View.GONE);
               iv_save.setVisibility(View.GONE);
               break;
           case R.id.iv_save:
               Intent intent=new Intent(this,VideoPlayActivity.class);
               intent.putExtra("source",mRecordFile.getAbsolutePath());
               startActivity(intent);
               break;
       }
   }

private class CustomCallBack implements SurfaceHolder.Callback {

@Override
       public void surfaceCreated(SurfaceHolder holder) {

try {
               initCamera();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }

@Override
       public void surfaceChanged(SurfaceHolder holder, int format, int width,
                                  int height) {

}

@Override
       public void surfaceDestroyed(SurfaceHolder holder) {
           freeCamera();
       }

}

/**
    * 初始化
    * @throws IOException
    */
   @SuppressLint("NewApi")
   private void initRecord() throws IOException {
       mMediaRecorder = new MediaRecorder();
       mMediaRecorder.reset();
       if (mCamera != null)
           mMediaRecorder.setCamera(mCamera);
       mMediaRecorder.setOnErrorListener(this);
       mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
       mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);// 视频源
       mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 音频源

//注释掉的代码官方说这样的配置方法是Android2.2以下使用
//  mMediaRecorder.setOutputFormat(OutputFormat.MPEG_4);// 视频输出格式
//  mMediaRecorder.setAudioEncoder(AudioEncoder.AAC);// 音频格式:AAC兼容会高点
//      mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);//设置视频编码:h264在常见的网页上都可播放
//  mMediaRecorder.setVideoSize(mWidth, mHeight);// 设置分辨率:
//  mMediaRecorder.setVideoEncodingBitRate(1 * 1024 * 1024*100);// 设置帧频率

//Android2.2以上直接用MediaRecorder.setProfile得到统一的配置
       mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_720P));
       mMediaRecorder.setOrientationHint(mRotationRecord);// 输出旋转90度,保持竖屏录制
       mMediaRecorder.setOutputFile(mRecordFile.getAbsolutePath());
       try {
           mMediaRecorder.prepare();
           mMediaRecorder.start();
       } catch (IllegalStateException e) {
           e.printStackTrace();
       } catch (RuntimeException e) {
           e.printStackTrace();
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

/**
    * 初始化摄像头
    */
   private void initCamera() throws IOException {
       if (mCamera != null) {
           freeCamera();
       }
       try {
           mCamera = Camera.open();
       } catch (Exception e) {
           e.printStackTrace();
           freeCamera();
       }
       if (mCamera == null)
           return;
       mCamera.setDisplayOrientation(90);
       mCamera.setPreviewDisplay(mSurfaceHolder);
       mCamera.startPreview();
       mCamera.unlock();
   }

/**
    * 视屏录制保存地方
    */
   private void createRecordDir() {
       File videoFolder = new File(Environment.getExternalStorageDirectory()
               + File.separator + "yufs/");//录制视频的保存地址
       if (!videoFolder.exists()) {
           videoFolder.mkdirs();
       }
       File recordDir = videoFolder;
       try {
           // mp4格式的录制的视频文件
           mRecordFile = File.createTempFile("recording", ".mp4", recordDir);
       } catch (IOException e) {
           e.printStackTrace();
       }
   }

/**
    * 释放摄像头资源
    */
   private void freeCamera() {
       try {
           if (mCamera != null) {
               mCamera.setPreviewCallback(null);
               mCamera.stopPreview();
               mCamera.lock();
               mCamera.release();
               mCamera = null;
           }
       }catch (Exception e){
           //视频成功录制了,资源回收的时候偶尔会崩溃
       }
   }

/**
    * 停止录制
    */
   public void stopRecord() {
       if (mMediaRecorder != null) {
           // 设置后不会崩
           mMediaRecorder.setOnErrorListener(null);
           mMediaRecorder.setPreviewDisplay(null);
           try {
               mMediaRecorder.stop();
               mMediaRecorder.release();
           } catch (IllegalStateException e) {
               e.printStackTrace();
           } catch (RuntimeException e) {
               e.printStackTrace();
           } catch (Exception e) {
               e.printStackTrace();
           }
       }
   }

@Override
   public void onError(MediaRecorder mr, int what, int extra) {
       try {
           if (mr != null)
               mr.reset();
       } catch (IllegalStateException e) {
           e.printStackTrace();
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

/**
    * @param v
    */
   private void startAnimator(View v){

AnimatorSet animatorSet = new AnimatorSet();//组合动画
       ObjectAnimator scaleX = ObjectAnimator.ofFloat(v, "scaleX", 0, 1f);
       ObjectAnimator scaleY = ObjectAnimator.ofFloat(v, "scaleY", 0, 1f);

animatorSet.setDuration(1000);
       animatorSet.setInterpolator(new DecelerateInterpolator());
       animatorSet.play(scaleX).with(scaleY);//两个动画同时开始
       animatorSet.start();
   }
}

三、录制完成,获取录制的视频并播放

代码如下:


public class VideoPlayActivity extends Activity implements MediaPlayer.OnPreparedListener, TextureVideoView.OnPlayStateListener, MediaPlayer.OnInfoListener, MediaPlayer.OnVideoSizeChangedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnSeekCompleteListener {
   private VideoViewTouch mVideoView;
   private RelativeLayout rl_loading;
   private Context mContext;
   /** 播放路径 */
   private String mSourcePath;
   private Intent uploadService;//视频上传服务

@Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_video_preview);
       initView();
       setListener();
       initData();
   }

private void initData() {
       //本地视频路径
       mSourcePath=getIntent().getStringExtra("source");
       //播放视屏
       parseIntentUrl(getIntent());
   }

private void parseIntentUrl(Intent intent) {
       mVideoView.setVideoPath(mSourcePath);
   }

private void setListener() {

mVideoView.setOnPreparedListener(this);
       mVideoView.setOnPlayStateListener(this);
       mVideoView.setOnTouchEventListener(mOnVideoTouchListener);
       mVideoView.setOnInfoListener(this);
       mVideoView.setOnVideoSizeChangedListener(this);
       mVideoView.setOnErrorListener(this);
       mVideoView.setOnSeekCompleteListener(this);

}

private void initView() {
       mVideoView= (VideoViewTouch) findViewById(R.id.preview);
       rl_loading= (RelativeLayout) findViewById(R.id.video_loading);

View preview_layout = findViewById(R.id.preview_layout);
       preview_layout.setVisibility(View.VISIBLE);
   }

private VideoViewTouch.OnTouchEventListener mOnVideoTouchListener = new VideoViewTouch.OnTouchEventListener() {

@Override
       public boolean onClick() {

if (mVideoView.isPlaying()) {
               mVideoView.pauseClearDelayed();
           } else {
               mVideoView.start();
           }
           return true;
       }

@Override
       public void onVideoViewDown() {
       }

@Override
       public void onVideoViewUp() {

}
   };

@Override
   public void onPrepared(MediaPlayer mp) {
       //获取视频的宽和高
       int videoWidth = mp.getVideoWidth();
       int videoHeight = mp.getVideoHeight();
       Log.e("yufs","视频的宽:"+videoWidth+",视频的高:"+videoHeight);
       //重新设置TextureView宽和高
       mVideoView.resize();
       //开始播放
       rl_loading.setVisibility(View.GONE);
       mVideoView.start();
   }

@Override
   public void onStateChanged(boolean isPlaying) {

}

@Override
   public boolean onInfo(MediaPlayer mp, int what, int extra) {
       return false;
   }

@Override
   public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {

}

@Override
   public boolean onError(MediaPlayer mp, int what, int extra) {
       return false;
   }

@Override
   public void onSeekComplete(MediaPlayer mp) {

}

@Override
   protected void onDestroy() {
       super.onDestroy();
   }
}

来源:https://blog.csdn.net/Chen_xiaobao/article/details/102477393

标签:Android,微信,视频
0
投稿

猜你喜欢

  • 算法证明每一位都相同十进制数不是完全平方数

    2022-06-21 23:00:46
  • ThreadPoolExecutor中的submit()方法详细讲解

    2022-02-18 03:02:39
  • 直接在线预览Word、Excel、TXT文件之ASP.NET

    2021-10-07 15:37:54
  • Java/Web调用Hadoop进行MapReduce示例代码

    2023-09-01 05:05:50
  • java跟踪执行的sql语句示例分享

    2022-07-30 20:13:18
  • Java8中CompletableFuture的用法全解

    2023-09-08 15:08:55
  • Android Studio如何为Activity添加自定义注解信息

    2023-01-06 18:28:04
  • 通过Java修改游戏存档的实现思路

    2023-07-30 20:10:55
  • Spring与Mybatis基于注解整合Redis的方法

    2022-09-19 09:19:56
  • Android中协调滚动布局的实现代码

    2023-11-07 20:37:05
  • Java实现简易俄罗斯方块

    2022-12-18 14:07:58
  • SpringBoot整合activemq的案例代码

    2023-11-06 18:41:37
  • Java中的引用类型和使用场景详细

    2023-11-29 03:58:19
  • Java监听器的作用及用法代码示例

    2023-06-24 06:59:07
  • Android画板开发之添加背景和保存画板内容为图片

    2022-05-30 04:01:37
  • Android App实现监听软键盘按键的三种方式

    2021-09-14 10:39:27
  • C#应用ToolStrip控件使用方法

    2023-05-23 09:10:18
  • C#将Sql数据保存到Excel文件中的方法

    2023-11-11 08:34:26
  • Java基于命令模式实现邮局发信功能详解

    2023-07-03 04:57:25
  • VScode 打造完美java开发环境最新教程

    2023-02-24 16:02:10
  • asp之家 软件编程 m.aspxhome.com