一、前言
之前用image_picker
来进行调起摄像头进行拍摄,具体可看Flutter调用摄像头录像及获取视频信息。但是页面及相关功能都是封装好的,无法自定义,所以不合适。比如可以重复录制等等,而当前项目不允许重复录制,所以只能再找插件,也就是现在的camera
。预览图如下:
二、引用
1 camera: 0.9.4
功能:调起摄像头,允许重制页面布局。安卓看一下配置要求。
地址:https://pub.dev/packages/camera
备注:我使用的版本是0.9.4,安卓下minSdkVersion 21
,再往上需要修改compileSdkVersion
,记得页面销毁时,也要把controller销毁掉哦。
三、使用
1 初始化摄像头
最好再initState()时就初始化摄像头
import 'package:camera/camera.dart';
late CameraController _controller;
late List<CameraDescription> _cameras;
/// 初始化摄像头
Future<void> _initCamera() async {
_cameras = await availableCameras(); /// 获取设备摄像头,默认0:后置 1:前置
_controller = CameraController(_cameras[selectCamera], ResolutionPreset.max);
_controller.initialize().then((_) {
/// 这里可以设置个变量用来监控是否初始化完成
if (!mounted) {
return;
}
});
}
2 翻转摄像头
实则是销毁之前的,重新生成一个摄像头。
/// 翻转摄像头
Future<void> _onCameraSwitch() async {
final CameraDescription cameraDescription =
(_controller.description == _cameras[0]) ? _cameras[1] : _cameras[0];
if (_controller != null) {
await _controller.dispose();
}
_controller = CameraController(cameraDescription, ResolutionPreset.medium);
try {
await _controller.initialize();
} on CameraException catch (e) {
toastShow(e);
}
if (mounted) {
setState(() {});
}
}
3 录制视频
/// 录制视频
Future<void> startVideoRecording() async {
print('startVideoRecording');
if (!_controller.value.isInitialized) {
}
_isRecording.value = true;
startCountdownTimer(); /// 这里为我统计的录制时长
if (_controller.value.isRecordingVideo) {
return; /// 如果正在录制则无效
}
try {
await _controller.startVideoRecording(); /// 开始录制,会卡一下
} on CameraException catch (e) {
print(e);
}
}
4 结束录制
/// 停止录制
Future<void> stopVideoRecording() async {
if (!_controller.value.isRecordingVideo) {
return; /// 如果不在录制,则无效
}
try {
XFile file = await _controller.stopVideoRecording();
print(file.path); /// 这里为文件地址,测试中我去找的时候未找到,但是可以拿到文件,应该是隐藏地址。
} on CameraException catch (e) {
print(e);
}
}
5 拍照
比录像简单,不需要结束录制,点击后就可以直接拿到值。
_controller.takePicture()
6 渲染摄像机组件
/// 初始化摄像机
Widget _buildCameraPreview() {
return CameraPreview(
_controller,
child: RotatedBox( /// 旋转屏幕
quarterTurns: 1,
child: Stack(
children: [
_buildBottomNavigationBar(), /// 这里可以渲染页面的覆盖物
... /// 这里可以放渲染时加载进度
]
),
),
);
}