一.知识概要
1.拍照实现步骤:
<1>界面使用SurfaceView控件,显示照相机的画面
<2>SurfaceView接受摄像头界面变化的信息
surfaceView.getHolder().addCallback()
<3>重写三个方法
surfaceDestroyed--->当预览界面关闭时,触发
一般在这里执行销毁照相机的操作,释放内存
camera.stopPreview();
camera.release();
camera = null;
surfaceCreated----->预览界面被创建时,调用
一般在这里打开照相机和设置照相机的一些参数
// 打开摄像头
camera = Camera.open();
// 给摄像头设置参数
Parameters parameters = camera.getParameters();
// 设置每秒3栈
parameters.setPreviewFrameRate(3);
// 设置照片的输出格式
parameters.setPictureFormat(PixelFormat.JPEG);
// 设置照片的质量
parameters.set("jpeg-quality", 85);
// 给照相机设置参数
camera.setParameters(parameters);
//将摄像头的画面显示到SurfaceView控件上
camera.setPreviewDisplay(sv_main_camera.getHolder());
// 开始预览
camera.startPreview();
surfaceChanged----->当预览界面的格式和大小发生改变时,触发
<4>保存
camera.takePicture
将照片保存到内存卡(压缩)
2.视频录制
实现步骤:
<1>将视频动画显示到SurfaceView控件上
<2>使用MediaRecorder类进行视频的录制
常用的方法:
mediaRecorder.reset();
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); //从照相机采集视频
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setVideoFrameRate(3); //每秒3帧
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); //设置视频编码方式
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
File videoFile = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis()+".3gp");
mediaRecorder.setOutputFile(videoFile.getAbsolutePath());
mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());
mediaRecorder.prepare();//预期准备
mediaRecorder.start();//开始刻录
mediaRecorder.stop();//停止刻录
注意:权限
视频播放器有两种做法
1、使用VideoView播放视频
audio音频
2、使用SurfaceView+MediaPlayer播放视频
二.播放视频(MediaPlayer+SurfaceView)
1.找到安装Android Studio时的SDK下面的platform-tools,再copy路径
再使用adb命令
activity_main.xml
清单文件AndroidManifest.xml
MainActivity.java
package com.zking.android28_playvideo;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageButton;
import android.widget.SeekBar;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
private MediaPlayer mediaPlayer;
private SeekBar sb_main_bar;
private SurfaceView sv_main_surface;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sb_main_bar = (SeekBar) findViewById(R.id.sb_main_bar);//获取进度条
sv_main_surface = (SurfaceView) findViewById(R.id.sv_main_surface);//1.
sb_main_bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
//进度改变
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
//开始滑
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
//停止滑
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
//获取当前进度条的位置
int currentPosition=seekBar.getProgress();
//跳转到某个位置进行播放
mediaPlayer.seekTo(currentPosition);
}
});
}
public void playOrPause(View view){
final ImageButton imageButton= (ImageButton) view;
if(mediaPlayer==null) {//一点开始播放
//实例化MediaPlayer
//mediaPlayer = MediaPlayer.create(this, R.raw.s1);//从项目里面拿音乐
//点播放时拿到内存卡的路径(从内存卡中拿音乐)
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
String sdPath=Environment.getExternalStorageDirectory().getAbsolutePath();
mediaPlayer=new MediaPlayer();
//设置音频流的类型
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
//设置音源(协议:file://)
try {
mediaPlayer.setDataSource(this, Uri.parse("file://"+sdPath+"/dcim/camera/VID_20170717_184535.mp4"));//内存卡下面 //2.
mediaPlayer.prepare();//不需要异步准备,只需要准备
//需要在清单文件中加权限
} catch (IOException e) {
e.printStackTrace();
}
//将画面展示到 SurfaceView上
mediaPlayer.setDisplay(sv_main_surface.getHolder()); //3.
mediaPlayer.start();
//暂停图标
imageButton.setImageResource(android.R.drawable.ic_media_pause);
//获取音乐的播放时间
int time=mediaPlayer.getDuration();
//设置进度条的最大值 为 音乐的播放时间
sb_main_bar.setMax(time);
new MyThread().start();
//不需要设置准备监听
// mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
// @Override
// public void onPrepared(MediaPlayer mp) {
//
// }
// });
}
}else if(mediaPlayer.isPlaying()){//下一次点击如果正在播放
mediaPlayer.pause();//暂停
//播放图标
imageButton.setImageResource(android.R.drawable.ic_media_play);
}else{//第三次播放
mediaPlayer.start();//接着播放
//暂停图标
imageButton.setImageResource(android.R.drawable.ic_media_pause);
}
}
//子线程 让进度条动起来
class MyThread extends Thread{
@Override
public void run() {
super.run();
while(sb_main_bar.getProgress()
二.视频播放(VideoView)
简单的,用系统自带的控件。
效果图:
具体代码实现如下:
activity_video.xml
AndroidManifest.xml
VideoActivity.java
package com.zking.android28_playvideo;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.MediaController;
import android.widget.VideoView;
public class VideoActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video);
VideoView vv_video= (VideoView) findViewById(R.id.vv_video);
vv_video.setVideoURI(Uri.parse("file://mnt/sdcard/dcim/camera/VID_20170715_140439.mp4"));
MediaController mediaController=new MediaController(this);//媒体控制器 this:上下文
mediaController.setMediaPlayer(vv_video);//让vv_video播放
vv_video.setMediaController(mediaController);//给vv_video这个控件设置媒体控制器
}
}
三.拍照
activity_camera.xml
AndroidManifest.xml
CameraActivity.java
package com.zking.android28_playvideo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
public class CameraActivity extends AppCompatActivity {
private SurfaceView sv_camera_surface;
private Camera camera;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
sv_camera_surface = (SurfaceView) findViewById(R.id.sv_camera_surface);
//给SurfaceView添加回调函数
sv_camera_surface.getHolder().addCallback(new SurfaceHolder.Callback() {
//surface:想象成画面
//画面创建,画面开始
@Override
public void surfaceCreated(SurfaceHolder holder) {
//打开摄像头
camera = Camera.open(); //.hardware:硬件 默认打开后置摄像头 括号里面Ctrl+P查看参数
//设置摄像参数
Camera.Parameters parameters= camera.getParameters();//拿到参数
parameters.setPictureFormat(PixelFormat.JPEG);//照片的后缀
parameters.set("jpeg-quality",100);//照片的质量 0-100值越大照片的质量越高
camera.setParameters(parameters);
//开启预览效果
camera.startPreview();
//将画面展示到surfaceView
try {
camera.setPreviewDisplay(sv_camera_surface.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
//画面改变时
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
//画面销毁时
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();//摄像头关闭
camera.release();//让摄像头释放内存
}
});
}
//拍照的点击事件
public void takePhoto(View view){
camera.takePicture(null, null, new Camera.PictureCallback() {//Ctrl+P查看参数
//图片压缩技术 oom:内存溢出
@Override
public void onPictureTaken(byte[] data, Camera camera) {//data字节数组,放图片
Bitmap bitmap= BitmapFactory.decodeByteArray(data,0,data.length);//先有一个图片 转码:从0到data.length
//时间戳
Calendar calendar=Calendar.getInstance();//拿年月日
int year=calendar.get(Calendar.YEAR);
int month=calendar.get(Calendar.MONTH);
int day=calendar.get(Calendar.DAY_OF_MONTH);
try {
FileOutputStream fos = new FileOutputStream("/mnt/sdcard/dcim/camera/IMG_"+year+(month+1)+day+"_"+System.currentTimeMillis()+".jpg");//照片名字的标准格式
//压缩
bitmap.compress(Bitmap.CompressFormat.JPEG,85,fos);//压缩的格式,质量,压缩到哪里去
//拍完之后接着拍
camera.stopPreview();//停一下
camera.startPreview();//再给camera开一下,就好比如重启
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
});
}
}