激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - java制作仿微信錄制小視頻控件

java制作仿微信錄制小視頻控件

2019-12-15 14:16hebedich JAVA教程

這篇文章主要介紹了java制作仿微信錄制小視頻控件的代碼,錄制小視頻非常方便,有需要的小伙伴可以參考下。

本文為用 MediaRecorder 錄制小視頻的控件,可以設置視頻錄制的時間、空間大小、初始時是否打開攝像頭等。 此控件為組合控件,繼承自 LinearLayout ,為防止出錯,需實現 android.media.MediaRecorder.OnErrorListener 接口。

小視頻錄制界面

java制作仿微信錄制小視頻控件

MovieRecorderView.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
import java.io.File;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
 
import android.content.Context;
import android.content.res.TypedArray;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.media.MediaRecorder;
import android.media.MediaRecorder.AudioEncoder;
import android.media.MediaRecorder.AudioSource;
import android.media.MediaRecorder.OnErrorListener;
import android.media.MediaRecorder.OutputFormat;
import android.media.MediaRecorder.VideoEncoder;
import android.media.MediaRecorder.VideoSource;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
 
import com.contron.dgyj.R;
import com.contron.dgyj.common.Globals;
import com.contron.dgyj.im.ImGlobal;
import com.lidroid.xutils.util.LogUtils;
 
/**
 * 視頻播放控件
 *
 * @author liuyinjun
 *
 * @date 2015-2-5
 */
public class MovieRecorderView extends LinearLayout implements OnErrorListener {
 
  private SurfaceView mSurfaceView;
  private SurfaceHolder mSurfaceHolder;
  private ProgressBar mProgressBar;
 
  private MediaRecorder mMediaRecorder;
  private Camera mCamera;
  private Timer mTimer;// 計時器
  private OnRecordFinishListener mOnRecordFinishListener;// 錄制完成回調接口
 
  private int mWidth;// 視頻分辨率寬度
  private int mHeight;// 視頻分辨率高度
  private boolean isOpenCamera;// 是否一開始就打開攝像頭
  private int mRecordMaxTime;// 一次拍攝最長時間
  private int mTimeCount;// 時間計數
  private File mVecordFile = null;// 文件
 
  public MovieRecorderView(Context context) {
    this(context, null);
  }
 
  public MovieRecorderView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }
 
  public MovieRecorderView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
 
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MovieRecorderView, defStyle, 0);
    mWidth = a.getInteger(R.styleable.MovieRecorderView_width, 320);// 默認320
    mHeight = a.getInteger(R.styleable.MovieRecorderView_height, 240);// 默認240
 
    isOpenCamera = a.getBoolean(R.styleable.MovieRecorderView_is_open_camera, true);// 默認打開
    mRecordMaxTime = a.getInteger(R.styleable.MovieRecorderView_record_max_time, 10);// 默認為10
 
    LayoutInflater.from(context).inflate(R.layout.movie_recorder_view, this);
    mSurfaceView = (SurfaceView) findViewById(R.id.surfaceview);
    mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
    mProgressBar.setMax(mRecordMaxTime);// 設置進度條最大量
 
    mSurfaceHolder = mSurfaceView.getHolder();
    mSurfaceHolder.addCallback(new CustomCallBack());
    mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
 
    a.recycle();
  }
 
  /**
   *
   * @author liuyinjun
   *
   * @date 2015-2-5
   */
  private class CustomCallBack implements Callback {
 
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
      if (!isOpenCamera)
        return;
      try {
        initCamera();
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
 
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
 
    }
 
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
      if (!isOpenCamera)
        return;
      freeCameraResource();
    }
 
  }
 
  /**
   * 初始化攝像頭
   *
   * @author liuyinjun
   * @date 2015-2-5
   * @throws IOException
   */
  private void initCamera() throws IOException {
    if (mCamera != null) {
      freeCameraResource();
    }
    try {
      mCamera = Camera.open();
    } catch (Exception e) {
      e.printStackTrace();
      freeCameraResource();
    }
    if (mCamera == null)
      return;
 
    setCameraParams();
    mCamera.setDisplayOrientation(90);
    mCamera.setPreviewDisplay(mSurfaceHolder);
    mCamera.startPreview();
    mCamera.unlock();
  }
 
  /**
   * 設置攝像頭為豎屏
   *
   * @author liuyinjun
   * @date 2015-2-5
   */
  private void setCameraParams() {
    if (mCamera != null) {
      Parameters params = mCamera.getParameters();
      params.set("orientation", "portrait");
      mCamera.setParameters(params);
    }
  }
 
  /**
   * 釋放攝像頭資源
   *
   * @author liuyinjun
   * @date 2015-2-5
   */
  private void freeCameraResource() {
    if (mCamera != null) {
      mCamera.setPreviewCallback(null);
      mCamera.stopPreview();
      mCamera.lock();
      mCamera.release();
      mCamera = null;
    }
  }
 
  private void createRecordDir() {
    File sampleDir = new File(Environment.getExternalStorageDirectory() + File.separator + "im/video/");
    if (!sampleDir.exists()) {
      sampleDir.mkdirs();
    }
    File vecordDir = sampleDir;
    // 創建文件
    try {
      mVecordFile = File.createTempFile("recording", ".mp4", vecordDir);//mp4格式
      LogUtils.i(mVecordFile.getAbsolutePath());
    } catch (IOException e) {
    }
  }
 
  /**
   * 初始化
   *
   * @author liuyinjun
   * @date 2015-2-5
   * @throws IOException
   */
  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(VideoSource.CAMERA);// 視頻源
    mMediaRecorder.setAudioSource(AudioSource.MIC);// 音頻源
    mMediaRecorder.setOutputFormat(OutputFormat.MPEG_4);// 視頻輸出格式
    mMediaRecorder.setAudioEncoder(AudioEncoder.AMR_NB);// 音頻格式
    mMediaRecorder.setVideoSize(mWidth, mHeight);// 設置分辨率:
    // mMediaRecorder.setVideoFrameRate(16);// 這個我把它去掉了,感覺沒什么用
    mMediaRecorder.setVideoEncodingBitRate(1 * 1024 * 512);// 設置幀頻率,然后就清晰了
    mMediaRecorder.setOrientationHint(90);// 輸出旋轉90度,保持豎屏錄制
    mMediaRecorder.setVideoEncoder(VideoEncoder.MPEG_4_SP);// 視頻錄制格式
    // mediaRecorder.setMaxDuration(Constant.MAXVEDIOTIME * 1000);
    mMediaRecorder.setOutputFile(mVecordFile.getAbsolutePath());
    mMediaRecorder.prepare();
    try {
      mMediaRecorder.start();
    } catch (IllegalStateException e) {
      e.printStackTrace();
    } catch (RuntimeException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
 
  /**
   * 開始錄制視頻
   *
   * @author liuyinjun
   * @date 2015-2-5
   * @param fileName
   *      視頻儲存位置
   * @param onRecordFinishListener
   *      達到指定時間之后回調接口
   */
  public void record(final OnRecordFinishListener onRecordFinishListener) {
    this.mOnRecordFinishListener = onRecordFinishListener;
    createRecordDir();
    try {
      if (!isOpenCamera)// 如果未打開攝像頭,則打開
        initCamera();
      initRecord();
      mTimeCount = 0;// 時間計數器重新賦值
      mTimer = new Timer();
      mTimer.schedule(new TimerTask() {
 
        @Override
        public void run() {
          // TODO Auto-generated method stub
          mTimeCount++;
          mProgressBar.setProgress(mTimeCount);// 設置進度條
          if (mTimeCount == mRecordMaxTime) {// 達到指定時間,停止拍攝
            stop();
            if (mOnRecordFinishListener != null)
              mOnRecordFinishListener.onRecordFinish();
          }
        }
      }, 0, 1000);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
 
  /**
   * 停止拍攝
   *
   * @author liuyinjun
   * @date 2015-2-5
   */
  public void stop() {
    stopRecord();
    releaseRecord();
    freeCameraResource();
  }
 
  /**
   * 停止錄制
   *
   * @author liuyinjun
   * @date 2015-2-5
   */
  public void stopRecord() {
    mProgressBar.setProgress(0);
    if (mTimer != null)
      mTimer.cancel();
    if (mMediaRecorder != null) {
      // 設置后不會崩
      mMediaRecorder.setOnErrorListener(null);
      mMediaRecorder.setPreviewDisplay(null);
      try {
        mMediaRecorder.stop();
      } catch (IllegalStateException e) {
        e.printStackTrace();
      } catch (RuntimeException e) {
        e.printStackTrace();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }
 
  /**
   * 釋放資源
   *
   * @author liuyinjun
   * @date 2015-2-5
   */
  private void releaseRecord() {
    if (mMediaRecorder != null) {
      mMediaRecorder.setOnErrorListener(null);
      try {
        mMediaRecorder.release();
      } catch (IllegalStateException e) {
        e.printStackTrace();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    mMediaRecorder = null;
  }
 
  public int getTimeCount() {
    return mTimeCount;
  }
 
  /**
   * @return the mVecordFile
   */
  public File getmVecordFile() {
    return mVecordFile;
  }
 
  /**
   * 錄制完成回調接口
   *
   * @author liuyinjun
   *
   * @date 2015-2-5
   */
  public interface OnRecordFinishListener {
    public void onRecordFinish();
  }
 
  @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();
    }
  }
}

movie_recorder_view.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="@android:color/background_dark"
  android:orientation="vertical">
 
  <SurfaceView
     android:id="@+id/surfaceview"
     android:layout_width="fill_parent"
     android:layout_height="0dp"
     android:layout_weight="1"
     />
 
  <ProgressBar
    android:id="@+id/progressBar"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="match_parent"
    android:layout_height="2dp"
    />
   
</LinearLayout>

attrs.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="@android:color/background_dark"
  android:orientation="vertical">
 
  <SurfaceView
     android:id="@+id/surfaceview"
     android:layout_width="fill_parent"
     android:layout_height="0dp"
     android:layout_weight="1"
     />
 
  <ProgressBar
    android:id="@+id/progressBar"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="match_parent"
    android:layout_height="2dp"
    />
   
</LinearLayout>

以上所述就是本文的全部內容了,希望大家能夠喜歡。

延伸 · 閱讀

精彩推薦
  • JAVA教程Java中的數組排序方式(快速排序、冒泡排序、選擇排序)

    Java中的數組排序方式(快速排序、冒泡排序、選擇排序)

    這篇文章主要介紹了Java中的數組排序方式(快速排序、冒泡排序、選擇排序),需要的朋友可以參考下 ...

    java教程網4232019-11-07
  • JAVA教程java線程并發semaphore類示例

    java線程并發semaphore類示例

    Java 5.0里新加了4個協調線程間進程的同步裝置,它們分別是Semaphore, CountDownLatch, CyclicBarrier和Exchanger,本例主要介紹Semaphore,Semaphore是用來管理一個資源池的工...

    java教程網4632019-10-31
  • JAVA教程java Mail郵件接收工具類

    java Mail郵件接收工具類

    這篇文章主要介紹了java Mail郵件接收工具類,本文直接給出類實現代碼和使用示例,需要的朋友可以參考下 ...

    junjie3522019-12-10
  • JAVA教程java實現收藏名言語句臺詞的app

    java實現收藏名言語句臺詞的app

    本文給大家分享的是使用java制作的記錄名人名言臺詞等等讓你難忘的語句的APP的代碼,非常的實用,有需要的小伙伴可以參考下。 ...

    hebedich4662019-12-14
  • JAVA教程scala 操作數據庫的方法

    scala 操作數據庫的方法

    這篇文章主要介紹了scala 操作數據庫的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著...

    張樂19933062019-06-29
  • JAVA教程你真的了解java單例模式了嗎?

    你真的了解java單例模式了嗎?

    這篇文章主要介紹了你真的了解java單例模式了嗎?實際上單例模式有著好幾個變種,并且多線程中涉及到線程安全問題,,需要的朋友可以參考下...

    阿豪聊干貨3792019-07-04
  • JAVA教程java正則表達式驗證工具類

    java正則表達式驗證工具類

    這篇文章主要介紹了java正則表達式驗證工具類,可以校驗電話號碼,身份證號碼,日期格式,URL,email等等,需要的小伙伴參考下吧。 ...

    hebedich1282019-12-12
  • JAVA教程java實現漢字轉unicode與漢字轉16進制實例

    java實現漢字轉unicode與漢字轉16進制實例

    這篇文章主要介紹了java實現漢字轉unicode與漢字轉16進制的實現方法,是Java操作漢字編碼轉換的一個典型應用,非常具有實用價值,需要的朋友可以參考下 ...

    shichen20143832019-12-03
主站蜘蛛池模板: 黄色影院av | 色网站在线免费观看 | 欧美aⅴ视频| 日日噜噜噜夜夜狠狠久久蜜桃 | 黑人一区二区 | 国产电影精品久久 | 毛片大全在线观看 | 看一级毛片 | 国产无限资源在线观看 | 久久精品日产第一区二区三区 | 成年免费看 | 色猫av| 欧美日韩免费一区二区三区 | av噜噜在线| 免费国产在线观看 | bt 自拍 另类 综合 欧美 | 亚洲午夜久久久精品一区二区三区 | 国产精品久久久久久久久久久久久久久久 | 久久精品电影网 | 久久亚洲美女视频 | 密室逃脱第一季免费观看完整在线 | 毛片免费观看视频 | 久久免费观看一级毛片 | 免费a级黄色片 | 欧美国产永久免费看片 | 美女黄色毛片免费看 | 海外中文字幕在线观看 | 欧美 中文字幕 | 午夜视频你懂的 | 日本在线观看视频网站 | 九九精品在线观看视频 | chinesehdxxxx实拍 日韩电影视频 | 欧美精品一区二区三区在线播放 | 91福利社在线| 久久毛片免费观看 | 亚洲人成电影在线 | 神秘电影91 | 最新精品在线 | 免费a级片在线观看 | h视频免费在线 | 国产成人自拍视频在线 |