接下来是最后一个功能的实现录像,倒腾了几个小时也算做出来了,中途也遇到各式各样的错误,大多是因为方法调用顺序不正确 。废话不多说下面回到正题。
惯例post参考的文章:[https://www.cnblogs.com/guanxinjing/p/10986766.html] (https://www.cnblogs.com/guanxinjing/p/10986766.html)
在manifests中的xml加入录像的许可
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission
android:name="android.permission.RECORD_AUDIO">
</uses-permission>
在主类中定义 private MediaRecorder mrecord;//用于启动、设置录像功能
private boolean isrecord=false;//判断录像功能是否已经启动
private SurfaceHolder mSurfaceHolder;
在oncreate方法中找到button
final Button recording=findViewById(R.id.recording);
然后给recording设定监听器和点击方法recording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {}});
定义一个初始化record的方法
private void initrecord(){
mrecord=new MediaRecorder();
}
定义一个设置record值的方法configurerecord()
private void configurerecord(){
File save=new File(getExternalCacheDir(),"recording.mp4");
if(save.exists()){
save.delete();
}
camera.unlock();
mrecord.setCamera(camera);
mrecord.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mrecord.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
mrecord.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
mrecord.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mrecord.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
mrecord.setVideoFrameRate(60);
mrecord.setMaxDuration(60*100);
mrecord.setPreviewDisplay(mSurfaceHolder.getSurface());
mrecord.setOutputFile(save.getAbsolutePath());
mrecord.setOnErrorListener(new MediaRecorder.OnErrorListener() {
@Override
public void onError(MediaRecorder mr, int what, int extra) {
mrecord.stop();
mrecord.reset();
try{
camera.setPreviewDisplay(v.getHolder());
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
因为推荐的文章里有详细介绍我就不解释上述set的作用了
设置好值后就是开启录像和关闭录像了
private void startRecorder(){
if(!isrecord){
camera.stopPreview();;
configurerecord();
try {
mrecord.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mrecord.start();
isrecord=true;
}
}
private void stopRecorder(){
if(isrecord){
mrecord.stop();
mrecord.reset();
isrecord=false;
try{
camera.setPreviewDisplay(v.getHolder());
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这全部设置好后回到关于recording的onclick方法中补充相关的方法
recording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Button b=(Button)v;
switch (b.getText().toString()){//这里switch的值是按钮的文本值,这个可以自己设置不一定要和我一样
case "recording":
startRecorder();
b.setText("stop");
break;
case "stop":
stopRecorder();
b.setText("recording");
break;
}
}
});
这样一个简单的录像、预览、拍照就算完成了。除了图片的保存。
用手机录像完后,在手机文件管理器中搜索就找到了录制的视频了
下面post出完整的代码
MainActivity.java
package com.example.testdemo2;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import java.io.File;
import java.io.IOException;
public class MainActivity extends AppCompatActivity implements Shutter {
private Camera camera;
private MediaRecorder mrecord;
private boolean isrecord=false;
private Camera.Size resize;
private SurfaceView v;
private SurfaceHolder mSurfaceHolder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
v=findViewById(R.id.surfaceView);
final Button take_picture=findViewById(R.id.snapshot);
final Button recording=findViewById(R.id.recording);
SurfaceHolder h=v.getHolder();
initrecord();
take_picture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
camera.takePicture(shutterCallback,null,pictureCallback);
}
});
recording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Button b=(Button)v;
switch (b.getText().toString()){
case "recording":
startRecorder();
b.setText("stop");
break;
case "stop":
stopRecorder();
b.setText("recording");
break;
}
}
});
startpreview(h);
}
public void startpreview(SurfaceHolder h){
if(ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)== PackageManager.PERMISSION_GRANTED) {
h.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder h) {
camera = camera.open();
camera.setDisplayOrientation(90);
try {
camera.setPreviewDisplay(h);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mSurfaceHolder = holder;
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.release();
}
});
}
}
Camera.ShutterCallback shutterCallback=new Camera.ShutterCallback() {
@Override
public void onShutter() {
}
};
Camera.PictureCallback pictureCallback=new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
}
};
private void initrecord(){
mrecord=new MediaRecorder();
}
private void configurerecord(){
File save=new File(getExternalCacheDir(),"recording.mp4");
if(save.exists()){
save.delete();
}
camera.unlock();
mrecord.setCamera(camera);
mrecord.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mrecord.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
mrecord.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
mrecord.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mrecord.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
//mrecord.setVideoSize();
mrecord.setVideoFrameRate(60);
//mrecord.setOrientationHint();
mrecord.setMaxDuration(60*100);
// Surface surface=new Surface(v.getHolder());
mrecord.setPreviewDisplay(mSurfaceHolder.getSurface());
mrecord.setOutputFile(save.getAbsolutePath());
mrecord.setOnErrorListener(new MediaRecorder.OnErrorListener() {
@Override
public void onError(MediaRecorder mr, int what, int extra) {
mrecord.stop();
mrecord.reset();
try{
camera.setPreviewDisplay(v.getHolder());
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
private void startRecorder(){
if(!isrecord){
camera.stopPreview();;
configurerecord();
try {
mrecord.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mrecord.start();
isrecord=true;
}
}
private void stopRecorder(){
if(isrecord){
mrecord.stop();
mrecord.reset();
isrecord=false;
try{
camera.setPreviewDisplay(v.getHolder());
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testdemo2">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission
android:name="android.permission.RECORD_AUDIO">
</uses-permission>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="600dp"
android:layout_height="480dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/snapshot"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="109dp"
android:layout_marginRight="109dp"
android:text="snapshot"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/recording"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/recording" />
<Button
android:id="@+id/recording"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="recording"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/snapshot"
app:layout_constraintTop_toBottomOf="@+id/surfaceView" />
</androidx.constraintlayout.widget.ConstraintLayout>
这里就是全部的代码了,因为这是camera api1的所以就不大算继续深入学习了,准备开始camera api2的学习,下次就更新camera api2的拍摄、预览、录像,希望这篇文章对也是新手的你有所帮助!