您的位置:首页 > 移动开发 > 微信开发

安卓微信小视频录制功能实现

2016-10-29 15:53 666 查看


版权声明:本文为博主原创文章,未经博主允许不得转载。

目录(?)[+]
开发之前
开发环境
相关知识点

开始开发
案例预览
案例分析
搭建布局
视频预览的实现
自定义双向缩减的进度条
录制事件的处理
长按录制
抬起保存
上滑取消
双击放大变焦

实现视频的录制
实现视频的停止

完整代码
总结

目录

开发之前

开发环境
相关知识点

开始开发

案例预览
案例分析
搭建布局
视频预览的实现
自定义双向缩减的进度条
录制事件的处理

长按录制
抬起保存
上滑取消
双击放大(变焦)

实现视频的录制
实现视频的停止

完整代码
总结

开发之前

这几天接触了一下和视频相关的控件, 所以, 继之前的微信摇一摇, 我想到了来实现一下微信小视频录制的功能,
它的功能点比较多, 我每天都抽出点时间来写写, 说实话, 有些东西还是比较费劲, 希望大家认真看看, 说得不对的地方还请大家在评论中指正. 废话不多说, 进入正题.

开发环境

最近刚更新的, 没更新的小伙伴们抓紧了

Android Studio 2.2.2
JDK1.7
API 24
Gradle 2.2.2

相关知识点

视频录制界面 SurfaceView 的使用

Camera的使用

相机的对焦, 变焦

视频录制控件MediaRecorder的使用

简单自定义View

GestureDetector(手势检测)的使用

用到的东西真不少, 不过别着急, 咱们一个一个来.

开始开发

案例预览

请原谅Gif图的粗糙

案例分析

大家可以打开自己微信里面的小视频, 一块简单的分析一下它的功能点有哪些 ?

基本的视频预览功能

长按 “按住拍” 实现视频的录制

录制过程中的进度条从两侧向中间变短

当松手或者进度条走到尽头视频停止录制 并保存

从 “按住拍” 上滑取消视频的录制

双击屏幕 变焦 放大

根据上述的分析, 我们一步一步的完成

搭建布局

布局界面的实现还可以, 难度不大

<code class="language-xml hljs  has-numbering">
<span class="hljs-pi"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-title">FrameLayout
</span>    <span class="hljs-attribute">xmlns:android</span>=<span class="hljs-value">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
<span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span>></span>
<span class="hljs-tag"><<span class="hljs-title">TextView
</span>        <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/main_tv_tip"</span>
<span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"wrap_content"</span>
<span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span>
<span class="hljs-attribute">android:layout_gravity</span>=<span class="hljs-value">"bottom|center_horizontal"</span>
<span class="hljs-attribute">android:layout_marginBottom</span>=<span class="hljs-value">"150dp"</span>
<span class="hljs-attribute">android:elevation</span>=<span class="hljs-value">"1dp"</span>
<span class="hljs-attribute">android:text</span>=<span class="hljs-value">"双击放大"</span>
<span class="hljs-attribute">android:textColor</span>=<span class="hljs-value">"#FFFFFF"</span>/></span>
<span class="hljs-tag"><<span class="hljs-title">LinearLayout
</span>        <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
<span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span>
<span class="hljs-attribute">android:orientation</span>=<span class="hljs-value">"vertical"</span>></span>
<span class="hljs-tag"><<span class="hljs-title">SurfaceView
</span>            <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/main_surface_view"</span>
<span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
<span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"0dp"</span>
<span class="hljs-attribute">android:layout_weight</span>=<span class="hljs-value">"3"</span>/></span>
<span class="hljs-tag"><<span class="hljs-title">LinearLayout
</span>            <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
<span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"0dp"</span>
<span class="hljs-attribute">android:layout_weight</span>=<span class="hljs-value">"1"</span>
<span class="hljs-attribute">android:background</span>=<span class="hljs-value">"@color/colorApp"</span>
<span class="hljs-attribute">android:orientation</span>=<span class="hljs-value">"vertical"</span>></span>
<span class="hljs-tag"><<span class="hljs-title">RelativeLayout
</span>                <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/main_press_control"</span>
<span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
<span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span>></span>
<span class="hljs-tag"><<span class="hljs-title">com.lulu.weichatsamplevideo.BothWayProgressBar
</span>                    <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/main_progress_bar"</span>
<span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
<span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"2dp"</span>
<span class="hljs-attribute">android:background</span>=<span class="hljs-value">"#000"</span>/></span>
<span class="hljs-tag"><<span class="hljs-title">TextView
</span>                    <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"wrap_content"</span>
<span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span>
<span class="hljs-attribute">android:layout_centerInParent</span>=<span class="hljs-value">"true"</span>
<span class="hljs-attribute">android:text</span>=<span class="hljs-value">"按住拍"</span>
<span class="hljs-attribute">android:textAppearance</span>=<span class="hljs-value">"@style/TextAppearance.AppCompat.Large"</span>
<span class="hljs-attribute">android:textColor</span>=<span class="hljs-value">"#00ff00"</span>/></span>
<span class="hljs-tag"></<span class="hljs-title">RelativeLayout</span>></span>
<span class="hljs-tag"></<span class="hljs-title">LinearLayout</span>></span>
<span class="hljs-tag"></<span class="hljs-title">LinearLayout</span>></span>
<span class="hljs-tag"></<span class="hljs-title">FrameLayout</span>></span>
</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li></ul><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li></ul>

视频预览的实现

step1: 得到SufaceView控件, 设置基本属性和相应监听(该控件的创建是异步的, 只有在真正”准备”好之后才能调用)

<code class="language-java hljs  has-numbering">
mSurfaceView = (SurfaceView) findViewById(R.id.main_surface_view);
<span class="hljs-comment">//设置屏幕分辨率</span>
mSurfaceHolder.setFixedSize(videoWidth, videoHeight);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mSurfaceHolder.addCallback(<span class="hljs-keyword">this</span>);
</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul>


step2: 实现接口的方法, surfaceCreated方法中开启视频的预览, 在surfaceDestroyed中销毁

<code class="language-java hljs  has-numbering">
<span class="hljs-comment">//////////////////////////////////////////////</span>
<span class="hljs-comment">// SurfaceView回调</span>
<span class="hljs-comment">/////////////////////////////////////////////</span>
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">surfaceCreated</span>(SurfaceHolder holder) {
mSurfaceHolder = holder;
startPreView(holder);
}
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">surfaceChanged</span>(SurfaceHolder holder, <span class="hljs-keyword">int</span> format, <span class="hljs-keyword">int</span> width, <span class="hljs-keyword">int</span> height) {

}

<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">surfaceDestroyed</span>(SurfaceHolder holder) {
<span class="hljs-keyword">if</span> (mCamera != <span class="hljs-keyword">null</span>) {
Log.d(TAG, <span class="hljs-string">"surfaceDestroyed: "</span>);
<span class="hljs-comment">//停止预览并释放摄像头资源</span>
mCamera.stopPreview();
mCamera.release();
mCamera = <span class="hljs-keyword">null</span>;
}
<span class="hljs-keyword">if</span> (mMediaRecorder != <span class="hljs-keyword">null</span>) {
mMediaRecorder.release();
mMediaRecorder = <span class="hljs-keyword">null</span>;
}
}
</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li></ul>


step3: 实现视频预览的方法

<code class="language-java hljs  has-numbering">
<span class="hljs-javadoc">/**
* 开启预览
*
*<span class="hljs-javadoctag"> @param</span> holder
*/</span>
<span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">startPreView</span>(SurfaceHolder holder) {
Log.d(TAG, <span class="hljs-string">"startPreView: "</span>);

<span class="hljs-keyword">if</span> (mCamera == <span class="hljs-keyword">null</span>) {
mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
}
<span class="hljs-keyword">if</span> (mMediaRecorder == <span class="hljs-keyword">null</span>) {
mMediaRecorder = <span class="hljs-keyword">new</span> MediaRecorder();
}
<span class="hljs-keyword">if</span> (mCamera != <span class="hljs-keyword">null</span>) {
mCamera.setDisplayOrientation(<span class="hljs-number">90</span>);
<span class="hljs-keyword">try</span> {
mCamera.setPreviewDisplay(holder);
Camera.Parameters parameters = mCamera.getParameters();
<span class="hljs-comment">//实现Camera自动对焦</span>
List<String> focusModes = parameters.getSupportedFocusModes();
<span class="hljs-keyword">if</span> (focusModes != <span class="hljs-keyword">null</span>) {
<span class="hljs-keyword">for</span> (String mode : focusModes) {
mode.contains(<span class="hljs-string">"continuous-video"</span>);
parameters.setFocusMode(<span class="hljs-string">"continuous-video"</span>);
}
}
mCamera.setParameters(parameters);
mCamera.startPreview();
} <span class="hljs-keyword">catch</span> (IOException e) {
e.printStackTrace();
}
}

}
</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li></ul>


Note: 上面添加了自动对焦的代码, 但是部分手机可能不支持

自定义双向缩减的进度条

有些像我一样的初学者一看到自定义某某View, 就觉得比较牛X. 其实呢, Google已经替我们写好了很多代码, 所以我们用就行了.而且咱们的这个进度条也没啥, 不就是一根线, 今天咱就来说说.

step1: 继承View, 完成初始化

<code class="language-java hljs  has-numbering">
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String TAG = <span class="hljs-string">"BothWayProgressBar"</span>;
<span class="hljs-comment">//取消状态为红色bar, 反之为绿色bar</span>
<span class="hljs-keyword">private</span> <span class="hljs-keyword">boolean</span> isCancel = <span class="hljs-keyword">false</span>;
<span class="hljs-keyword">private</span> Context mContext;
<span class="hljs-comment">//正在录制的画笔</span>
<span class="hljs-keyword">private</span> Paint mRecordPaint;
<span class="hljs-comment">//上滑取消时的画笔</span>
<span class="hljs-keyword">private</span> Paint mCancelPaint;
<span class="hljs-comment">//是否显示</span>
<span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> mVisibility;
<span class="hljs-comment">// 当前进度</span>
<span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> progress;
<span class="hljs-comment">//进度条结束的监听</span>
<span class="hljs-keyword">private</span> OnProgressEndListener mOnProgressEndListener;

<span class="hljs-keyword">public</span> <span class="hljs-title">BothWayProgressBar</span>(Context context) {
<span class="hljs-keyword">super</span>(context, <span class="hljs-keyword">null</span>);
}
<span class="hljs-keyword">public</span> <span class="hljs-title">BothWayProgressBar</span>(Context context, AttributeSet attrs) {
<span class="hljs-keyword">super</span>(context, attrs);
mContext = context;
init();
}
<span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">init</span>() {
mVisibility = INVISIBLE;
mRecordPaint = <span class="hljs-keyword">new</span> Paint();
mRecordPaint.setColor(Color.GREEN);
mCancelPaint = <span class="hljs-keyword">new</span> Paint();
mCancelPaint.setColor(Color.RED);
}
</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li></ul>


Note: OnProgressEndListener, 主要用于当进度条走到中间了, 好通知相机停止录制, 接口如下:

<code class="language-java hljs  has-numbering">
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">OnProgressEndListener</span>{</span>
<span class="hljs-keyword">void</span> onProgressEndListener();
}
<span class="hljs-javadoc">/**
* 当进度条结束后的 监听
*<span class="hljs-javadoctag"> @param</span> onProgressEndListener
*/</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setOnProgressEndListener</span>(OnProgressEndListener onProgressEndListener) {
mOnProgressEndListener = onProgressEndListener;
}
</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li></ul>


step2 :设置Setter方法用于通知我们的Progress改变状态

<code class="language-java hljs  has-numbering">

<span class="hljs-javadoc">/**
* 设置进度
*<span class="hljs-javadoctag"> @param</span> progress
*/</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setProgress</span>(<span class="hljs-keyword">int</span> progress) {
<span class="hljs-keyword">this</span>.progress = progress;
invalidate();
}

<span class="hljs-javadoc">/**
* 设置录制状态 是否为取消状态
*<span class="hljs-javadoctag"> @param</span> isCancel
*/</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setCancel</span>(<span class="hljs-keyword">boolean</span> isCancel) {
<span class="hljs-keyword">this</span>.isCancel = isCancel;
invalidate();
}
<span class="hljs-javadoc">/**
* 重写是否可见方法
*<span class="hljs-javadoctag"> @param</span> visibility
*/</span>
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setVisibility</span>(<span class="hljs-keyword">int</span> visibility) {
mVisibility = visibility;
<span class="hljs-comment">//重新绘制</span>
invalidate();
}
</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li></ul>


step3 :最重要的一步, 画出我们的进度条,使用的就是View中的onDraw(Canvas canvas)方法

<code class="language-java hljs  has-numbering"><span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onDraw</span>(Canvas canvas) {
<span class="hljs-keyword">super</span>.onDraw(canvas);
<span class="hljs-keyword">if</span> (mVisibility == View.VISIBLE) {
<span class="hljs-keyword">int</span> height = getHeight();
<span class="hljs-keyword">int</span> width = getWidth();
<span class="hljs-keyword">int</span> mid = width / <span class="hljs-number">2</span>;

<span class="hljs-comment">//画出进度条</span>
<span class="hljs-keyword">if</span> (progress < mid){
canvas.drawRect(progress, <span class="hljs-number">0</span>, width-progress, height, isCancel ? mCancelPaint : mRecordPaint);
} <span class="hljs-keyword">else</span> {
<span class="hljs-keyword">if</span> (mOnProgressEndListener != <span class="hljs-keyword">null</span>) {
mOnProgressEndListener.onProgressEndListener();
}
}
} <span class="hljs-keyword">else</span> {
canvas.drawColor(Color.argb(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>));
}
}
</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li></ul>

录制事件的处理

录制中触发的事件包括四个:

长按录制
抬起保存
上滑取消
双击放大(变焦)

现在对这4个事件逐个分析:

前三这个事件, 我都放在了一个onTouch()回调方法中了

对于第4个, 我们待会谈

我们先把onTouch()中局部变量列举一下:
<code class="language-java hljs  has-numbering">
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">onTouch</span>(View v, MotionEvent event) {
<span class="hljs-keyword">boolean</span> ret = <span class="hljs-keyword">false</span>;
<span class="hljs-keyword">int</span> action = event.getAction();
<span class="hljs-keyword">float</span> ey = event.getY();
<span class="hljs-keyword">float</span> ex = event.getX();
<span class="hljs-comment">//只监听中间的按钮处</span>
<span class="hljs-keyword">int</span> vW = v.getWidth();
<span class="hljs-keyword">int</span> left = LISTENER_START;
<span class="hljs-keyword">int</span> right = vW - LISTENER_START;
<span class="hljs-keyword">float</span> downY = <span class="hljs-number">0</span>;
<span class="hljs-comment">// ...</span>
}</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li></ul>

长按录制

长按录制我们需要监听ACTION_DOWN事件, 使用线程延迟发送Handler来实现进度条的更新

<code class="language-java hljs  has-numbering"><span class="hljs-keyword">switch</span> (action) {
<span class="hljs-keyword">case</span> MotionEvent.ACTION_DOWN:
<span class="hljs-keyword">if</span> (ex > left && ex < right) {
mProgressBar.setCancel(<span class="hljs-keyword">false</span>);
<span class="hljs-comment">//显示上滑取消</span>
mTvTip.setVisibility(View.VISIBLE);
mTvTip.setText(<span class="hljs-string">"↑ 上滑取消"</span>);
<span class="hljs-comment">//记录按下的Y坐标</span>
downY = ey;
<span class="hljs-comment">// TODO: 2016/10/20 开始录制视频, 进度条开始走</span>
mProgressBar.setVisibility(View.VISIBLE);
<span class="hljs-comment">//开始录制</span>
Toast.makeText(<span class="hljs-keyword">this</span>, <span class="hljs-string">"开始录制"</span>, Toast.LENGTH_SHORT).show();
startRecord();
mProgressThread = <span class="hljs-keyword">new</span> Thread() {
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>() {
<span class="hljs-keyword">super</span>.run();
<span class="hljs-keyword">try</span> {
mProgress = <span class="hljs-number">0</span>;
isRunning = <span class="hljs-keyword">true</span>;
<span class="hljs-keyword">while</span> (isRunning) {
mProgress++;
mHandler.obtainMessage(<span class="hljs-number">0</span>).sendToTarget();
Thread.sleep(<span class="hljs-number">20</span>);
}
} <span class="hljs-keyword">catch</span> (InterruptedException e) {
e.printStackTrace();
}
}
};
mProgressThread.start();
ret = <span class="hljs-keyword">true</span>;
}
<span class="hljs-keyword">break</span>;
<span class="hljs-comment">// ...</span>
<span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
}
</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li></ul>


Note: startRecord()这个方法先不说, 我们只需要知道执行了它就可以录制了, 但是Handler事件还是要说的, 它只负责更新进度条的进度

<code class="language-java hljs  has-numbering">

<span class="hljs-comment">////////////////////////////////////////////////////</span>
<span class="hljs-comment">// Handler处理</span>
<span class="hljs-comment">/////////////////////////////////////////////////////</span>
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyHandler</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Handler</span> {</span>
<span class="hljs-keyword">private</span> WeakReference<MainActivity> mReference;
<span class="hljs-keyword">private</span> MainActivity mActivity;

<span class="hljs-keyword">public</span> <span class="hljs-title">MyHandler</span>(MainActivity activity) {
mReference = <span class="hljs-keyword">new</span> WeakReference<MainActivity>(activity);
mActivity = mReference.get();
}

<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">handleMessage</span>(Message msg) {
<span class="hljs-keyword">switch</span> (msg.what) {
<span class="hljs-keyword">case</span> <span class="hljs-number">0</span>:
mActivity.mProgressBar.setProgress(mActivity.mProgress);
<span class="hljs-keyword">break</span>;
}
}
}</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li></ul>

抬起保存

同样我们这儿需要监听ACTION_UP事件, 但是要考虑当用户抬起过快时(录制的时间过短), 不需要保存. 而且, 在这个事件中包含了取消状态的抬起, 解释一下: 就是当上滑取消时抬起的一瞬间取消录制, 大家看代码

<code class="language-java hljs  has-numbering"><span class="hljs-keyword">case</span> MotionEvent.ACTION_UP:
<span class="hljs-keyword">if</span> (ex > left && ex < right) {
mTvTip.setVisibility(View.INVISIBLE);
mProgressBar.setVisibility(View.INVISIBLE);
<span class="hljs-comment">//判断是否为录制结束, 或者为成功录制(时间过短)</span>
<span class="hljs-keyword">if</span> (!isCancel) {
<span class="hljs-keyword">if</span> (mProgress < <span class="hljs-number">50</span>) {
<span class="hljs-comment">//时间太短不保存</span>
stopRecordUnSave();
Toast.makeText(<span class="hljs-keyword">this</span>, <span class="hljs-string">"时间太短"</span>, Toast.LENGTH_SHORT).show();
<span class="hljs-keyword">break</span>;
}
<span class="hljs-comment">//停止录制</span>
stopRecordSave();
} <span class="hljs-keyword">else</span> {
<span class="hljs-comment">//现在是取消状态,不保存</span>
stopRecordUnSave();
isCancel = <span class="hljs-keyword">false</span>;
Toast.makeText(<span class="hljs-keyword">this</span>, <span class="hljs-string">"取消录制"</span>, Toast.LENGTH_SHORT).show();
mProgressBar.setCancel(<span class="hljs-keyword">false</span>);
}

ret = <span class="hljs-keyword">false</span>;
}
<span class="hljs-keyword">break</span>;</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li></ul>


Note: 同样的, 内部的stopRecordUnSave()和stopRecordSave();大家先不要考虑, 我们会在后面介绍, 他俩从名字就能看出 前者用来停止录制但不保存, 后者停止录制并保存

上滑取消

配合上一部分说得抬起取消事件, 实现上滑取消

<code class="language-java hljs  has-numbering">
<span class="hljs-keyword">case</span> MotionEvent.ACTION_MOVE:
<span class="hljs-keyword">if</span> (ex > left && ex < right) {
<span class="hljs-keyword">float</span> currentY = event.getY();
<span class="hljs-keyword">if</span> (downY - currentY > <span class="hljs-number">10</span>) {
isCancel = <span class="hljs-keyword">true</span>;
mProgressBar.setCancel(<span class="hljs-keyword">true</span>);
}
}
<span class="hljs-keyword">break</span>;
</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li></ul>


Note: 主要原理不难, 只要按下并且向上移动一定距离 就会触发,当手抬起时视频录制取消

双击放大(变焦)

这个事件比较特殊, 使用了Google提供的GestureDetector手势检测 来判断双击事件

step1: 对SurfaceView进行单独的Touch事件监听, why? 因为GestureDetector需要Touch事件的完全托管, 如果只给它传部分事件会造成某些事件失效

<code class="language-java hljs  has-numbering">mDetector = <span class="hljs-keyword">new</span> GestureDetector(<span class="hljs-keyword">this</span>, <span class="hljs-keyword">new</span> ZoomGestureListener());
<span class="hljs-javadoc">/**
* 单独处理mSurfaceView的双击事件
*/</span>
mSurfaceView.setOnTouchListener(<span class="hljs-keyword">new</span> View.OnTouchListener() {
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">onTouch</span>(View v, MotionEvent event) {
mDetector.onTouchEvent(event);
<span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
}
});
</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li></ul>


step2: 重写GestureDetector.SimpleOnGestureListener, 实现双击事件

<code class="language-java hljs  has-numbering">
<span class="hljs-comment">///////////////////////////////////////////////////////////////////////////</span>
<span class="hljs-comment">// 变焦手势处理类</span>
<span class="hljs-comment">///////////////////////////////////////////////////////////////////////////</span>
class ZoomGestureListener extends GestureDetector.SimpleOnGestureListener {
<span class="hljs-comment">//双击手势事件</span>
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">onDoubleTap</span>(MotionEvent e) {
<span class="hljs-keyword">super</span>.onDoubleTap(e);
Log.d(TAG, <span class="hljs-string">"onDoubleTap: 双击事件"</span>);
<span class="hljs-keyword">if</span> (mMediaRecorder != <span class="hljs-keyword">null</span>) {
<span class="hljs-keyword">if</span> (!isZoomIn) {
setZoom(<span class="hljs-number">20</span>);
isZoomIn = <span class="hljs-keyword">true</span>;
} <span class="hljs-keyword">else</span> {
setZoom(<span class="hljs-number">0</span>);
isZoomIn = <span class="hljs-keyword">false</span>;
}
}
<span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
}
}
</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li></ul>


step3: 实现相机的变焦的方法

<code class="language-java hljs  has-numbering">
<span class="hljs-javadoc">/**
* 相机变焦
*
*<span class="hljs-javadoctag"> @param</span> zoomValue
*/</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setZoom</span>(<span class="hljs-keyword">int</span> zoomValue) {
<span class="hljs-keyword">if</span> (mCamera != <span class="hljs-keyword">null</span>) {
Camera.Parameters parameters = mCamera.getParameters();
<span class="hljs-keyword">if</span> (parameters.isZoomSupported()) {<span class="hljs-comment">//判断是否支持</span>
<span class="hljs-keyword">int</span> maxZoom = parameters.getMaxZoom();
<span class="hljs-keyword">if</span> (maxZoom == <span class="hljs-number">0</span>) {
<span class="hljs-keyword">return</span>;
}
<span class="hljs-keyword">if</span> (zoomValue > maxZoom) {
zoomValue = maxZoom;
}
parameters.setZoom(zoomValue);
mCamera.setParameters(parameters);
}
}

}
</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li></ul>

Note: 至此我们已经完成了对所有事件的监听, 看到这里大家也许有些疲惫了, 不过不要灰心, 现在完成我们的核心部分, 实现视频的录制

实现视频的录制

说是核心功能, 也只不过是我们不知道某些API方法罢了, 下面代码中我已经加了详细的注释, 部分不能理解的记住就好^v^

<code class="language-java hljs  has-numbering"><span class="hljs-javadoc">/**
* 开始录制
*/</span>
<span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">startRecord</span>() {
<span class="hljs-keyword">if</span> (mMediaRecorder != <span class="hljs-keyword">null</span>) {
<span class="hljs-comment">//没有外置存储, 直接停止录制</span>
<span class="hljs-keyword">if</span> (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
<span class="hljs-keyword">return</span>;
}
<span class="hljs-keyword">try</span> {
<span class="hljs-comment">//mMediaRecorder.reset();</span>
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
<span class="hljs-comment">//从相机采集视频</span>
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
<span class="hljs-comment">// 从麦克采集音频信息</span>
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
<span class="hljs-comment">// TODO: 2016/10/20  设置视频格式</span>
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setVideoSize(videoWidth, videoHeight);
<span class="hljs-comment">//每秒的帧数</span>
mMediaRecorder.setVideoFrameRate(<span class="hljs-number">24</span>);
<span class="hljs-comment">//编码格式</span>
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
<span class="hljs-comment">// 设置帧频率,然后就清晰了</span>
mMediaRecorder.setVideoEncodingBitRate(<span class="hljs-number">1</span> * <span class="hljs-number">1024</span> * <span class="hljs-number">1024</span> * <span class="hljs-number">100</span>);
<span class="hljs-comment">// TODO: 2016/10/20 临时写个文件地址, 稍候该!!!</span>
File targetDir = Environment.
getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
mTargetFile = <span class="hljs-keyword">new</span> File(targetDir,
SystemClock.currentThreadTimeMillis() + <span class="hljs-string">".mp4"</span>);
mMediaRecorder.setOutputFile(mTargetFile.getAbsolutePath());
mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
mMediaRecorder.prepare();
<span class="hljs-comment">//正式录制</span>
mMediaRecorder.start();
isRecording = <span class="hljs-keyword">true</span>;
} <span class="hljs-keyword">catch</span> (Exception e) {
e.printStackTrace();
}

}
}

</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li></ul>

实现视频的停止

大家可能会问, 视频的停止为什么单独抽出来说呢? 仔细的同学看上面代码会看到这两个方法: stopRecordSave和stopRecordUnSave, 一个停止保存, 一个是停止不保存, 接下来我们就补上这个坑

停止并保存

<code class="language-java hljs  has-numbering">
<span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">stopRecordSave</span>() {
<span class="hljs-keyword">if</span> (isRecording) {
isRunning = <span class="hljs-keyword">false</span>;
mMediaRecorder.stop();
isRecording = <span class="hljs-keyword">false</span>;
Toast.makeText(<span class="hljs-keyword">this</span>, <span class="hljs-string">"视频已经放至"</span> + mTargetFile.getAbsolutePath(), Toast.LENGTH_SHORT).show();
}
}</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul>


停止不保存

<code class="language-java hljs  has-numbering">
<span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">stopRecordUnSave</span>() {
<span class="hljs-keyword">if</span> (isRecording) {
isRunning = <span class="hljs-keyword">false</span>;
mMediaRecorder.stop();
isRecording = <span class="hljs-keyword">false</span>;
<span class="hljs-keyword">if</span> (mTargetFile.exists()) {
<span class="hljs-comment">//不保存直接删掉</span>
mTargetFile.delete();
}
}
}
</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li></ul>


Note: 这个停止不保存是我自己的一种想法, 如果大家有更好的想法, 欢迎大家到评论中指出, 不胜感激

完整代码

源码我已经放在了github上了, 写博客真是不易! 写篇像样的博客更是不易, 希望大家多多支持

总结

终于写完了!!! 这是我最想说得话, 从案例一开始到现在已经过去很长时间. 这是我写得最长的一篇博客, 发现能表达清楚自己的想法还是很困难的, 这是我最大的感受!!!

实话说这个案例不是很困难, 但是像我这样的初学者拿来练练手还是非常好的, 在这里还要感谢再见杰克的博客, 也给我提供了很多帮助

最后, 希望大家共同进步!


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: