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

本文实例为大家分享了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();
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android采用消息推送实现类似微信视频接听

    本文实例为大家分享了Android实现类似微信视频接听的具体代码,供大家参考,具体内容如下 1.背景需求:业务需要接入视频审核功能,在PC 端发起视频通话,移动端显示通话界面点击接听后进行1对1视频通话. 2.解决方案:因为项目没有IM功能.只集成了极光消息推送(极光消息推送接入参考官方文档,经过跟需求沟通,采用消息推送调起通话接听界面.再集成腾讯实时音视频SDK(具体集成方式参考官方文档).最终实现类似微信1对1通话功能. 3.技术实现: A:编写一个广播接收器,并且在 AndroidMani

  • Android仿微信录制小视频

    本文实例为大家分享了Android仿微信录制小视频的具体代码,供大家参考,具体内容如下 先上张图片看看效果 简单叙述下 首先通过Camera类调用系统相机 通过surfaceview绘制出来 通过MediaRecorder来录制视频 闪光灯 和 切换摄像头 需要重新配置Camera的参数 Camera预览界面画面拉升的原因是因为Surfaceview的大小与设定的比例不一致的 **本次版本更新了 切换前置摄像头录制视频问题 Android部分手机录制视频适配IOS手机问题 (OPPO手机部分不适

  • 微信小程序实现点击拍照长按录像功能的实现代码

    代码里面注释写的都很详细,直接上代码.官方的组件属性中有触摸开始和触摸结束属性.本功能依靠这些属性实现. .wxml代码: <!-- 相机 pages/camera/camera.wxml--> <!-- 相机 --> <camera wx:if="{{!videoSrc}}" device-position="back" flash="off" binderror="error" style=&

  • Android基于腾讯云实时音视频仿微信视频通话最小化悬浮

    最近项目中有需要语音.视频通话需求,看到这个像环信.融云等SDK都有具体Demo实现,但咋的领导对腾讯情有独钟啊,IM要用腾讯云IM,不妙的是腾讯云IM并不包含有音视频通话都要自己实现,没办法深入了解腾讯云产品后,决定自己基于腾讯云实时音视频做去语音.视频通话功能.在这里把实现过程记录下为以后用到便于查阅,另一方面也给有需要的人提供一个思路,让大家少走弯路,有可能我的实现的方法不是最好,但是这或许是一个可行的方案,大家不喜勿喷.基于腾讯云实时音视频SDK 6.5.7272版本,腾讯DEMO下载地

  • Android实现微信朋友圈发本地视频功能

    一.前言 前一篇文章已经详细介绍了如何使用Xposed框架编写第一个微信插件:摇骰子和猜拳作弊器 本文继续来介绍如何使用Xposed框架编写第二个微信插件,可以将本地小视频发布到朋友圈的功能.在这之前我们还是要有老套路,准备工作要做好,这里还是使用微信6.3.9版本进行操作,准备工作: 1.使用apktool工具进行反编译,微信没有做加固防护,所以这个版本的微信包反编译是没有任何问题的. 2.借助于可视化反编译工具Jadx打开微信包,后续几乎重要分析都是借助这个工具来操作的. 二.猜想与假设 做

  • Android实现微信朋友圈图片和视频播放

    本文实例为大家分享了Android实现微信朋友圈图片和视频播放的具体代码,供大家参考,具体内容如下 1.效果图: 2.源码地址:链接 3.参数控制,是否显示播放按钮 holder.layout.setIsShowAll(mList.get(position).isShowAll); holder.layout.setIsVideo(true); //true :video, false :img holder.layout.setUrlList(mList.get(position).urlLi

  • Android 微信小视频录制功能实现详细介绍

    Android 微信小视频录制功能 开发之前 这几天接触了一下和视频相关的控件, 所以, 继之前的微信摇一摇, 我想到了来实现一下微信小视频录制的功能, 它的功能点比较多, 我每天都抽出点时间来写写, 说实话, 有些东西还是比较费劲, 希望大家认真看看, 说得不对的地方还请大家在评论中指正. 废话不多说, 进入正题. 开发环境 最近刚更新的, 没更新的小伙伴们抓紧了 Android Studio 2.2.2 JDK1.7 API 24 Gradle 2.2.2 相关知识点 视频录制界面 Surf

  • Android仿微信拍摄短视频

    近期做项目需要添加上传短视频功能,功能设置为类似于微信,点击开始拍摄,设置最长拍摄时间,经过研究最终实现了这个功能,下面就和大家分享一下,希望对你有帮助. 1.视频录制自定义控件: /** * 视频播放控件 */ public class MovieRecorderView extends LinearLayout implements OnErrorListener { private SurfaceView mSurfaceView; private SurfaceHolder mSurfa

  • Android仿微信多人音视频通话界面

    工作中需要实现一个类似微信多人视频通话功能的界面,分别使用自定义viewgroup和自定义layoutManager的方式进行了实现.最终工作中采用了layoutManager,因为可以使用payload更新单个布局控件,效率更好.下面放出两种具体的实现效果代码. 1.使用自定义ViewGroup方式实现 下面是三个人通话时候的效果,其他的可以参考微信多人音视频通话界面. package com.dnaer.android.telephone.widgets; import android.co

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

    本文实例为大家分享了Android仿微信长按录制视频并播放功能的具体代码,供大家参考,具体内容如下 一.点击按钮进行录制 首先要获取摄像拍照的权限和读取权限 <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <use

  • Android仿微信长按菜单效果

    本文实例为大家分享了Android仿微信长按菜单展示的具体代码,供大家参考,具体内容如下 FloatMenu A menu style pop-up window that mimics WeChat.仿微信的长按菜单. 效果如下 引入方法: Github地址:https://github.com/JavaNoober/FloatMenu dependencies { .... compile 'com.noober.floatmenu:common:1.0.2' } 使用说明 使用方法1: A

  • Android仿微信加号菜单模式

    在模仿微信过程中有一个加号菜单启动着实让我有点费心,因为我去掉了自带的标题栏,想通过OnCreateOptionMenu这段代码来实现传统的Menu显示显然是不可能了.所以在自定义创建的状态栏里添加了一个加号的ImageView,想通过监听ImageView的Onclick来触发Popumenu的创建.基本效果与微信相似,细节方面还需多多考究. 看具体代码如下: 1.监听之后创建Popumenu的java代码: menuView.setOnClickListener(new View.OnCli

  • iOS仿微信相机拍照、视频录制功能

    网上有很多自定义相机的例子,这里只是我临时写的一个iOS自定义相机(仿微信)拍照.视频录制demo,仅供参考: 用到了下面几个库: #import <AVFoundation/AVFoundation.h> #import <AssetsLibrary/AssetsLibrary.h> 在使用的时候需要在Info.plist中把相关权限写进去: Privacy - Microphone Usage Description Privacy - Photo Library Usage

  • Android仿微信语音消息的录制和播放功能

    一.简述 效果: 实现功能: 长按Button时改变Button显示文字,弹出Dialog(动态更新音量),动态生成录音文件,开始录音: 监听手指动作,规定区域.录音状态下手指划出规定区域取消录音,删除生成的录音文件: 监听手指动作.当手指抬起时,判断是否开始录音,录音时长是否过短,符合条件则提示录音时长过短:正常结束时通过回调返回该次录音的文件路径和时长. 4.点击录音列表的item时,播放动画,播放对应的音频文件. 主要用到4个核心类: 自定义录音按钮(AudioRecordButton):

  • Android仿微信单击拍照长按录像功能实例代码

    此文章是看郭神公众号发的一篇,仅作学习. 在modlue gradle中添加 compile 'cjt.library.wheel:camera:0.0.7' 在project gradle中添加 compile 'cjt.library.wheel:camera:0.0.7' 添加的地方是 allprojects { repositories { jcenter() /*在此处添加*/ } } 使用起来很方便,只需在xml布局中 <com.cjt2325.cameralibrary.JCame

  • Android仿微信录制语音功能

    本文实例为大家分享了Android仿微信录制语音的具体代码,供大家参考,具体内容如下 前言 我把录音分成了两部分 1.UI界面,弹窗读秒 2.一个类(包含开始.停止.创建文件名功能) 第一部分 由于6.0权限问题,点击按钮申请权限通过则弹窗,如何申请权限 弹窗布局popw_record.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http:

  • Android仿微信主界面的实现方法

    本文实例为大家分享了Android模仿微信主界面展示的具体代码,供大家参考,具体内容如下 先看一下效果图 实现的原理: ViewPager+FragmentPagerAdapter 主界面可分为三部分: top标题栏就是一个TextView 中间的ViewPager作为显示的容器,填充Fragment bottom是一个RadioGroup 这里为了布局的优化,将top和bottom抽取出来 ,然后用include将其导入主布局,如下 <LinearLayout xmlns:android=&quo

  • Android仿微信语音对讲录音功能

    自微信出现以来取得了很好的成绩,语音对讲的实现更加方便了人与人之间的交流.今天来实践一下微信的语音对讲的录音实现,这个也比较容易实现.在此,我将该按钮封装成为一个控件,并通过策略模式的方式实现录音和界面的解耦合,以方便我们在实际情况中对录音方法的不同需求(例如想要实现wav格式的编码时我们也就不能再使用MediaRecorder,而只能使用AudioRecord进行处理). 效果图: 实现思路: 1.在微信中我们可以看到实现语音对讲的是通过点按按钮来完成的,因此在这里我选择重新自己的控件使其继承

随机推荐