Android拍摄视频上传服务器及本地预览
最近在项目中遇到了视频的拍摄上传及本地预览功能,特地记录一下
1、基于本地视频的预览采用cardview进行显示,因此需要引入相应的jar包,我这里AS使用的是
compile 'com.android.support:cardview-v7:26.+'
compile 'com.android.support:design:26.+'
2、新建一个录制视频的界面如图
点击拍摄时进行视频拍摄,点击确定则返回相应的视频存储路径。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="match_parent"><FrameLayoutandroid:id="@+id/camera_preview"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_weight="1" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:id="@+id/tv_time"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"/><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:text="注:最多可以录制30秒"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:orientation="horizontal"><Buttonandroid:id="@+id/btn_cancel"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="取消"/><Buttonandroid:id="@+id/btn"android:text="拍摄"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="15dp"/><Buttonandroid:id="@+id/btn_sure"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="确定"android:layout_marginLeft="15dp"/></LinearLayout></LinearLayout>
</LinearLayout>
3、接下来则是代码实现(文末有全部代码)
第一步当然是检查设备是否有摄像头,如果都没有摄像头,还谈什么视频拍摄呢
private boolean checkCameraHardware(Context context){if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {ToastUtils.showToast(context, "successfully detact camera!");return true;}else {ToastUtils.showToast(context, "not detact camera!!!");return false;}}
核心设置如下
/*** 创建MediaRecorder实例,并为之设定基本属性* @return*/private boolean prepareVideoRecorder(){try {recorder = new MediaRecorder();mCamera.unlock();recorder.setCamera(mCamera);recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);// recorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));// Set output file formatrecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// 这两项需要放在setOutputFormat之后recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);recorder.setVideoSize(640, 480);recorder.setVideoFrameRate(30); //这是重点,帧值设置得越大,占内存越大,30基本上是满足了一般的视频要求,60的话上传就费劲了recorder.setVideoEncodingBitRate(3 * 1024 * 1024);recorder.setOrientationHint(90);//设置记录会话的最大持续时间(毫秒)recorder.setMaxDuration(30 * 1000);recorder.setPreviewDisplay(previewView.getHolder().getSurface());result_path = getOutputMediaPath();recorder.setOutputFile(result_path);recorder.prepare();} catch (Exception e) {e.printStackTrace();return false;}return true;}
注:此功能需要的权限有
Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE
完整代码如下
public class Activity_VideoCamera extends Activity {private Camera mCamera;private CameraPreviewView previewView;private MediaRecorder recorder;private boolean isrecording = false;private Button btn, btn_cancel, btn_sure;private TextView tv_time;Handler startTimehandler;private long baseTimer;private Timer timer;private String result_path ;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_video);//动态权限申请Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO,Manifest.permission.WRITE_EXTERNAL_STORAGE// 这个写法有问题,就不贴代码了自己另行写法吧if (Build.VERSION.SDK_INT >= 23){CommonUtils.requestLocPermissions(this);CommonUtils.requestPermissions(this);CommonUtils.requestVideoPermissions(this);}//判断是否有摄像头if (!checkCameraHardware(this)) {return;};mCamera = getCameraInstance();mCamera.setDisplayOrientation(90);previewView = new CameraPreviewView(this, mCamera);FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);preview.addView(previewView);btn = (Button) findViewById(R.id.btn);btn_sure = (Button) findViewById(R.id.btn_sure);btn_cancel = (Button) findViewById(R.id.btn_cancel);tv_time = (TextView) findViewById(R.id.tv_time);initEvent();startTimehandler = new Handler(){public void handleMessage(android.os.Message msg) {if (null != tv_time) {tv_time.setText("录制时间:" + (String) msg.obj);}}};}private void initEvent(){btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (isrecording) {releaseMediaRecoder();//mCamera.lock();btn.setText("拍摄");isrecording = false;timer.cancel();}else {if (prepareVideoRecorder()) {recorder.start();btn.setText("Stop");isrecording = true;tv_time.setText("录制时间:00:00:00");startTimer();}else {releaseMediaRecoder();timer.cancel();}}}});btn_cancel.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {try {File file = new File(result_path);file.delete();finish();}catch (Exception e){e.printStackTrace();}}});btn_sure.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Intent intent = new Intent();intent.putExtra("path", result_path);Activity_VideoCamera.this.setResult(RESULT_OK, intent);Activity_VideoCamera.this.finish();}});}public void startTimer(){baseTimer = SystemClock.elapsedRealtime();timer = new Timer();timer.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {int time = (int)((SystemClock.elapsedRealtime() - baseTimer) / 1000);String hh = new DecimalFormat("00").format(time / 3600);String mm = new DecimalFormat("00").format(time % 3600 / 60);String ss = new DecimalFormat("00").format(time % 60);String timeFormat = new String(hh + ":" + mm + ":" + ss);Message msg = new Message();msg.obj = timeFormat;startTimehandler.sendMessage(msg);}}, 0, 1000L);}@Overrideprotected void onPause() {super.onPause();releaseMediaRecoder();releaseCamera();}private void releaseMediaRecoder(){if (recorder != null) {recorder.reset();recorder.release();recorder = null;mCamera.lock();}}private void releaseCamera(){if (mCamera != null) {mCamera.setPreviewCallback(null);mCamera.release();mCamera = null;}}/*** 创建MediaRecorder实例,并为之设定基本属性* @return*/private boolean prepareVideoRecorder(){try {recorder = new MediaRecorder();mCamera.unlock();recorder.setCamera(mCamera);recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);// recorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));// Set output file formatrecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// 这两项需要放在setOutputFormat之后recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);recorder.setVideoSize(640, 480);recorder.setVideoFrameRate(30);recorder.setVideoEncodingBitRate(3 * 1024 * 1024);recorder.setOrientationHint(90);//设置记录会话的最大持续时间(毫秒)recorder.setMaxDuration(30 * 1000);recorder.setPreviewDisplay(previewView.getHolder().getSurface());result_path = getOutputMediaPath();recorder.setOutputFile(result_path);recorder.prepare();} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** 获取输出video文件目录* @return*/private String getOutputMediaPath() {java.util.Date date = new java.util.Date();String timeTemp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(date.getTime());File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyCameraApp");if (! mediaStorageDir.exists()){if (! mediaStorageDir.mkdirs()){Log.d("MyCameraApp", "failed to create directory");return null;}}Log.e("Error", "getOutputMediaPath file path---"+mediaStorageDir.getPath() + File.separator +"VID_" + timeTemp+ ".mp4");return mediaStorageDir.getPath() + File.separator +"VID_" + timeTemp + ".mp4";}public class CameraPreviewView extends SurfaceView implements SurfaceHolder.Callback{private SurfaceHolder holder;public CameraPreviewView(Context context, Camera camera) {super(context);holder = getHolder();holder.addCallback(this);holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {// TODO Auto-generated method stub}@Overridepublic void surfaceCreated(SurfaceHolder holder) {try {mCamera.setPreviewDisplay(holder);mCamera.startPreview();} catch (IOException e) {e.printStackTrace();}}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {if (holder.getSurface() == null) {return;}try {if(mCamera != null) {holder.removeCallback(this);mCamera.setPreviewCallback(null);mCamera.stopPreview();mCamera.lock();mCamera.release();mCamera = null;}} catch (Exception e) {e.printStackTrace();}}}/*** 获取camera实例* @return*/public static Camera getCameraInstance(){Camera camera = null;try {camera = Camera.open();} catch (Exception e) {e.printStackTrace();}return camera;}/*** 检测手机有无摄像头* @param context* @return*/private boolean checkCameraHardware(Context context){if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {ToastUtils.showToast(context, "successfully detact camera!");return true;}else {ToastUtils.showToast(context, "not detact camera!!!");return false;}}}
在预览界面就简单了,在onresultActivity方法中实现如下代码
if (data != null) {final String filepath = data.getExtras().getString("path");final VideoView videoView = new VideoView(context);Uri uri = Uri.parse(filepath);videoView.setLayoutParams(layoutParams);videoView.setVideoURI(uri);videoView.setMediaController(new MediaController(context));videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {@Overridepublic void onPrepared(MediaPlayer mp) {
// videoView.start();}});ll_pics.addView(videoView,ll_pics.getChildCount() - 1);Log.e(TAG, "onActivityResult: " + filepath);file = new File(filepath);Log.e(TAG, "filename----"+ file.getName());
// receiveHandler.sendEmptyMessage(HANDLE_UPLOAD_IMG);//实现上传方法}
实现上传的代码我这里就不展示了,如有不足望见谅
PS:应大家都在找我要源码,再更新一下具体使用方法吧:
1、前面Activity_VideoCamera.jvav文件和以及对于的activity_video.xml文件就不多说了,复制代码新建文件就OK了。(注:其中的动态权限申请会有异常,自己处理一下吧)
2、在调用视频拍摄时,比如在Activity页面中点击按钮调用此页面时
Intent it = new Intent(context, Activity_VideoCamera.class);
startActivityForResult(it, 11);
然后在此Activity页面重写onresultActivity方法,添加如下代码
@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1){if (data != null) {final String filepath = data.getExtras().getString("path");final VideoView videoView = new VideoView(context);Uri uri = Uri.parse(filepath);videoView.setLayoutParams(layoutParams);videoView.setVideoURI(uri);videoView.setMediaController(new MediaController(context));videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {@Overridepublic void onPrepared(MediaPlayer mp) {
// videoView.start();}});ll_pics.addView(videoView,ll_pics.getChildCount() - 1);//此处自己用一个LinearLayout控件来进行装载就ok了Log.e(TAG, "onActivityResult: " + filepath);file = new File(filepath);Log.e(TAG, "filename----"+ file.getName());
// receiveHandler.sendEmptyMessage(HANDLE_UPLOAD_IMG);//实现上传方法}
}
}
Android拍摄视频上传服务器及本地预览相关推荐
- [html] 图片上传时实现本地预览功能的原理是什么?
[html] 图片上传时实现本地预览功能的原理是什么? 通过HTML5 File API读取用户上传的图片,生成一个image对象显示到页面 个人简介 我是歌谣,欢迎和大家一起交流前后端知识.放弃很容 ...
- JS实现图片上传时的本地预览,兼容IE和firefox谷歌
旁白: 一般来说如果要实现在上传前预览图片的话,用纯服务器端的语言必定是办不到的,需要先传到服务器上,哪怕是只是服务器上的临时文件,这也是个很麻烦的事情,不过可以用javascript来做这件事.下面 ...
- 文件上传,下载,预览,删除(File),分页接口
文件上传,下载,预览,删除(File) 1.公共参数方法 1.1公共返回类型定义 1.2 分页接口 1.3公共实体类 1.4 公共的 mapper.java/xml(都放在一起) 1.4.1 File ...
- Springboot + layui + FTP文件上传删除 + HTTP文件下载预览 + pdf.js文件预览(项目实战总结)
文件管理 0.需求及前言 1.前端,上传按钮嵌入数据表格中 2.利用IIS部署FTP文件服务器 3.后台FTP连接和文件操作 4.FTP遇到的问题和解决方案 5.预览PDF文件V1.0:FTP+临时文 ...
- 利用钉钉云盘实现业务系统需要的附件上传、下载和预览
本文主要记录自己在工作学习中遇到的坑和解决思路,仅供大家参考 目录 前言 一.钉盘是什么? 二.为什么要使用钉盘? 三.JSAPI鉴权 1.鉴权的时机 2.鉴权的时效 3.鉴权的代码 3.1.获取ac ...
- html5 图片上传,支持图片预览、压缩、及进度显示,兼容IE6+及标准浏览器
原文:html5 图片上传,支持图片预览.压缩.及进度显示,兼容IE6+及标准浏览器 以前写过上传组件,见 打造 html5 文件上传组件,实现进度显示及拖拽上传,兼容IE6+及其它标准浏览器,对付一 ...
- dropzonejs中文翻译手册 DropzoneJS是一个提供文件拖拽上传并且提供图片预览的开源类库....
http://wxb.github.io/dropzonejs.com.zh-CN/dropzonezh-CN/ 由于项目需要,完成一个web的图片拖拽上传,也就顺便学习和了解了一下前端的比较新的技术 ...
- 小程序自定义上传富文本并预览
上传时的效果 预览时的效果 代码如下(可直接全部复制查看,注意:下面上传的接口需要改成你们自己的服务器上传接口) <view class="col"><text& ...
- HTML5 原生API input file 来实现多图上传,并大图预览
闲来无事,突然想用原生来实现图片的多图上传. 一.效果图大致如下: 1.上传时可以选择多图 2.上传之后缩略图下过图如下: 3.点击缩略图,大图展示当前所点击的图片,并可以左右滑动查看其它的缩略图对应 ...
最新文章
- CSS jQuery制作漂亮的文字模糊效果
- Python操作数据库之 MySQL
- QTP自动化测试框架的基础知识
- MyBatis使用心得(一)--- 简单介绍
- 使用jsp打印HTTP请求头部所有字段的值
- floquet端口必须沿z轴设置_Ansys Workbench 振动给料机偏心轴的模态分析
- 《Unix网络编程》卷一(简介TCP/IP、基础套接字编程)
- 实现option上下移动_ES6原生实战Uploader工具类(从设计到实现)
- 【科睿唯安】注意,最新SCI/SSCI列表,警惕这7本期刊被剔除?
- 电力系统分析实验--生成节点导纳矩阵
- x64位call代码注入器1.0版
- 高考数学计算机题,高考数学大题
- CAD工程图纸转jpg格式教程
- Codeforces 592 A. PawnChess 【Codeforces Round #328 (Div. 2)】
- BootStrap表格鼠标悬停颜色修改
- 流程审批: 有个人不走申请人直属领导审批,审批流程设定(设定条件,矩阵相关)
- AIX各项知识链接(IBM官网)
- 汇编语言编写方法及程序分析
- 高端时尚飞行模拟体验为展会聚拢人气
- QGC的PlanToolBar