- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章java制作仿微信录制小视频控件由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文为用 MediaRecorder 录制小视频的控件,可以设置视频录制的时间、空间大小、初始时是否打开摄像头等。 此控件为组合控件,继承自 LinearLayout ,为防止出错,需实现 android.media.MediaRecorder.OnErrorListener 接口.
小视频录制界面 。
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制作仿微信录制小视频控件的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在尝试解决 A/V 同步问题。视频将比音频延迟 1 秒。 (请看我下面的注释) 来自 Android 媒体框架部分, 我可以延迟音频时间戳让它与视频同步,我应该从哪里开始?是音频源吗? MPEG4
我正在使用带有 SignalR 的 MassTransit 请求和响应。该网站向创建文件的 Windows 服务发出请求。创建文件后,Windows 服务会将响应消息发送回网站。该网站将打开该文件并使
我正在尝试创建一个允许用户发出一些声音的应用程序,然后以回放方式使用它。 我想让我的应用程序播放用户将记录的.wav文件。 由于不断出现错误,我在弄清楚如何编写此代码时遇到了麻烦。 ====
有没有办法禁止网页上视频的屏幕共享? 例如,当您尝试录制或屏幕共享(例如通过 Skype)Netflix 视频时,它仅显示黑屏并且没有音频。 我的问题是,他们是如何实现的?我只能想到JavaScrip
我正在尝试使用 html5 .getUserMedia 录制视频,然后在不上传到服务器的情况下再次播放。我尝试了很多教程,我通过使用 canvas 绘制 webp 图像然后使用 Whammy.js 转
我想为我的网站的用户实现屏幕录制功能。这将适用于便士拍卖风格的网站,以便用户可以记录他们的出价,并在拍卖出现问题时提供证据。 这是在线录音机的演示。 http://www.screentoaster.
所以在我的应用程序中,我尝试使用屏幕截图“记录”屏幕。我必须将这些单独的帧作为图像,因为它们稍后会在服务器上进行修改和组合。增加这种复杂性的是,它是在使用 Cocos2D 的慢节奏游戏中。我目前截屏的
是否可以使用单个 ffmpeg 命令同时捕获(记录)RTSP 流和捕获场景变化事件?我几乎可以做我想做的事: ffmpeg -i 'rtsp://mystream' \ -map 0:v -map 0
我是 Objective-c 和 iPhone 编程新手,但我正在开发一个自学应用程序。我一直在尝试弄清楚如何在 iPhone 上录制声音。 Apple 提供了使用 AVAudioRecorder 从
我无法写任何东西来允许这样做,但我希望有人能指出我找到可以做到这一点的代码的正确方向。我擅长 HTML 和 CSS,对 JS 非常陌生。 我需要的是能够使用我的麦克风在单页网站上讲话,并将其流回。这样
想象一下您在浏览器中观看体育赛事直播。这意味着您收到了视频流,对吗?我需要记录这个流并保存到磁盘。问题是我不知道从哪里开始。我对编程并不陌生,但在视频直播方面有一些经验。我看到这个问题分为以下几个部分
我在开始录制时遇到文件未找到异常。此外,我无法在 JMeter 可安装文件夹中找到 RootCA 证书。 最佳答案 根据 TestRecording210 JMeter Wiki 页面当用户(您在其下
我有这个源代码可以在浏览器中录制音频。 Record.js 调用另一个脚本提供录音并将其保存到服务器。 index.html record.js //starts by click on butt
我允许用户按下按钮以通过 SoundPool 播放声音。是否可以录制 SoundPool 正在播放的任何内容,以便用户可以录制一系列声音? 最佳答案 实际上不可能捕捉到播放的声音。我也有同样的愿望,但
我正在尝试使用 xcrun simctl io booted recordVideo recording.mov 录制我的 iOS 11.4 模拟器的屏幕。这将创建一个具有该名称的文件,但不幸的是该文
好的,我将尝试尽可能清楚地说明我的问题,但我很困惑,所以如果我没有传达信息,请告诉我。 我正在尝试使用 getUserMedia 来使用网络摄像头,然后使用这个 http://www.w3.org/T
是否可以使用 html5 录制声音?我已经下载了最新的 canary 版本的 chrome 并使用以下代码: navigator.getUserMedia = navigator.webkitGetU
很多人都在问这个,似乎没有人有答案,所以我也没有。 某些应用程序如何提供记录android系统音频输出的功能?我发现的所有内容都是在 1432 个不同站点上的相同教程,您可以在其中记录 MIC 输入。
不小心撞到了qq而不是 @q ,我的 vim 现在正在记录到寄存器 q . 如果我输入 q再次,它将覆盖以前录制的宏。 有没有办法 取消录制以免覆盖之前的宏或 恢复之前的宏而不从头开始重新录制? 最佳
当我们接到电话时,我们会向来电者播放提示,内容类似于“我们可能会出于质量和培训目的记录通话”。 我们为响应来电而发送的 TWiML 如下所示。 http://domain.tld/may_r
我是一名优秀的程序员,十分优秀!