Flutter摄像头管理插件vconnex_camera的使用
Flutter摄像头管理插件vconnex_camera的使用
本项目通过阿里云连接到摄像头。该库支持多种功能,如实时预览、回放、PTZ控制、获取设备信息等。
示例代码
import 'dart:io';
import 'dart:typed_data';
import 'package:gallery_saver/gallery_saver.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:vconnex_camera/VCNCameraPlaybackViewWidget.dart';
import 'package:vconnex_camera/camera_controller.dart';
import 'package:vconnex_camera/vcn_camera_view_widget.dart';
import 'package:vconnex_camera/vconnex_camera.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
late CameraController _cameraController;
late CameraController _cameraPlaybackController;
bool _isLogin = false;
[@override](/user/override)
void initState() {
super.initState();
initPlatformState();
VconnexCamera.setCameraCallback(_handleMessages);
}
Future<dynamic> _handleMessages(MethodCall call) async {
switch (call.method) {
case 'startAddDevice':
Map map = call.arguments as Map;
print(map);
}
}
// 平台消息异步初始化
Future<void> initPlatformState() async {
String platformVersion;
try {
platformVersion = await VconnexCamera.platformVersion ?? 'Unknown platform version';
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
Future<dynamic> _handlePlayBackMessages(MethodCall call) async {
print("playback message: ${call.method}, args: ${call.arguments}");
}
Future<dynamic> _handleLiveViewMessages(MethodCall call) async {
switch (call.method) {
case 'sendFromNative':
String text = call.arguments as String;
return new Future.value("Text from native: $text");
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('插件示例应用'),
),
body: Padding(
padding: EdgeInsets.all(20),
child: Column(
children: [
VCNCameraPlaybackViewWidget(
width: 320,
height: 200,
callback: (controller) {
_cameraPlaybackController = controller;
},
handler: _handlePlayBackMessages,
),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("登录验证"),
onPressed: () async {
Map<String, dynamic> args = {};
args['authCode'] = 'eyJhbGciOiJIUzI1NiJ9.eyJvIjp7InByb3ZpZGVyIjoiZW1haWwiLCJwcm92aWRlclVzZXJJZCI6ImtzMmMyNTExQGdtYWlsLmNvbSJ9LCJpYXQiOjE2Njk3NzU2MDksImV4cCI6MTY3MjM2NzYwOX0.hcYBs51RHR7K3o0ZxuMQAX_SCBsKENbc3bYnvv0Wa14';
bool? isLoginSuccess = await VconnexCamera.loginWithAuthCode(args);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("刷新令牌"),
onPressed: () async {
VconnexCamera.refreshToken();
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("登出"),
onPressed: () async {
VconnexCamera.logout();
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("是否已登录: ${_isLogin ? 'True' : 'False'}"),
onPressed: () async {
_isLogin = await VconnexCamera.refreshToken() ?? false;
setState(() {});
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("请求设备列表"),
onPressed: () async {
Map? devices = await VconnexCamera.requestUserDeviceList();
if (devices != null) {
// _selectedCamera = devices.first;
}
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("设置设备参数"),
onPressed: () async {
VconnexCamera.setDeviceParameter(productKey: 'a1BxN4TY5nN', linkType: 6, enableToken: true, regionNode: 0);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("添加摄像头"),
onPressed: () async {
if (await Permission.locationWhenInUse.serviceStatus.isEnabled) {
} else {
}
Map<Permission, PermissionStatus> statuses = await [
Permission.location,
].request();
Map? infos = await VconnexCamera.startAddDevice(ssid: 'TEST', pass: '0913456789', timeout: 240);
print("添加摄像头结果:");
print(infos);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("停止添加摄像头"),
onPressed: () async {
await VconnexCamera.stopAddDevice();
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("解除绑定设备"),
onPressed: () async {
VconnexCamera.unbindDevice(iotId: 'vyrpCPlpvVSRZXbjRDAE000000');
},
),
),
Row(
children: [
Padding(
padding: const EdgeInsets.all(4.0),
child: TextButton(
child: Text("播放"),
onPressed: () async {
_cameraController.playCamera(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', streamType: 0);
},
),
),
Padding(
padding: const EdgeInsets.all(4.0),
child: TextButton(
child: Text("停止"),
onPressed: () async {
_cameraController.stopCamera();
},
),
),
Padding(
padding: const EdgeInsets.all(4.0),
child: TextButton(
child: Text("暂停"),
onPressed: () async {
_cameraController.pauseCamera();
},
),
),
Padding(
padding: const EdgeInsets.all(4.0),
child: TextButton(
child: Text("恢复"),
onPressed: () async {
// _cameraController.restoreCamera();
},
),
),
],
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("从RF卡回放"),
onPressed: () async {
_cameraPlaybackController.playCameraByLocalRecordTime(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', vodStartTime: 1663200000, vodEndTime: 1663286399, seekTime: 2, recordType: 0);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("跳转到时间点"),
onPressed: () async {
_cameraPlaybackController.seekTo(8);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("设置视频缩放模式"),
onPressed: () async {
_cameraController.playCamera(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', streamType: 1);
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Padding(
padding: const EdgeInsets.all(2.0),
child: TextButton(
child: Text("左"),
onPressed: () async {
VconnexCamera.stepPTZControl(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', actionType: 0, step: 5);
},
),
),
Padding(
padding: const EdgeInsets.all(2.0),
child: TextButton(
child: Text("右"),
onPressed: () async {
VconnexCamera.stepPTZControl(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', actionType: 1, step: 5);
},
),
),
Padding(
padding: const EdgeInsets.all(2.0),
child: TextButton(
child: Text("上"),
onPressed: () async {
VconnexCamera.stepPTZControl(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', actionType: 2, step: 5);
},
),
),
Padding(
padding: const EdgeInsets.all(2.0),
child: TextButton(
child: Text("下"),
onPressed: () async {
VconnexCamera.stepPTZControl(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', actionType: 3, step: 5);
},
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("放大"),
onPressed: () async {
VconnexCamera.stepPTZControl(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', actionType: 9, step: 5);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("缩小"),
onPressed: () async {
VconnexCamera.stepPTZControl(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', actionType: 8, step: 5);
},
),
),
],
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("停止PTZ控制"),
onPressed: () async {
VconnexCamera.stepPTZControl(iotId: 'UF0mFdBYqwehGavXRaj7000000', actionType: 4, step: 5);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("获取快照"),
onPressed: () async {
Uint8List list = await _cameraController.getVideoSnapshot(filePath: '');
File file = await File.fromRawPath(list);
Directory appDocDir = await getApplicationSupportDirectory();
final File newImage = await file.copy('${appDocDir.path}/image1.png');
print('文件大小: ${await newImage.length()}');
await GallerySaver.saveImage('${appDocDir.path}/image1.png');
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("设置静音"),
onPressed: () async {
_cameraController.setMute(mute: false);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("设置声音变化类型"),
onPressed: () async {
_cameraController.setVoiceChangeType(type: 1);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("设置播放速度"),
onPressed: () async {
_cameraController.setPlaySpeed(speed: 8000);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("开始录制视频"),
onPressed: () async {
Directory appDocDir = await getApplicationSupportDirectory();
String appDocPath = appDocDir.path + '/sampleVideo.mp4';
_cameraController.startRecordVideo(filePath: appDocPath);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("停止录制视频"),
onPressed: () async {
_cameraController.stopRecordVideo();
Directory appDocDir = await getApplicationSupportDirectory();
String appDocPath = appDocDir.path + '/sampleVideo.mp4';
File file = await File(appDocPath);
print('文件大小: ${await file.length()}');
await GallerySaver.saveVideo(file.path);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("设置显示缓冲"),
onPressed: () async {
_cameraController.setDisplayBuffer(buffer: 10);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("设置对讲编码参数"),
onPressed: () async {
_cameraController.setIntercomEncodeParam(sampleRate: 8000, channel: 1, bitPerSample: 16, format: 1);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("打开语音对讲"),
onPressed: () async {
if (await Permission.microphone.request().isGranted) {
_cameraController.openVoiceIntercom(mode: 1, iotId: "vyrpCPlpvVSRZXbjRDAE000000");
} else {
Map<Permission, PermissionStatus> statuses = await [
Permission.microphone,
].request();
}
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("关闭语音对讲"),
onPressed: () async {
_cameraController.stopVoiceIntercom();
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("获取设备信息"),
onPressed: () async {
VconnexCamera.getDeviceInfo(iotId: 'vyrpCPlpvVSRZXbjRDAE000000');
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("设置录像模式"),
onPressed: () async {
VconnexCamera.setStorageRecordMode(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', mode: 2);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("获取摄像机属性"),
onPressed: () async {
VconnexCamera.getpropertiesCamera(iotId: 'vyrpCPlpvVSRZXbjRDAE000000');
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("设置日夜模式"),
onPressed: () async {
VconnexCamera.setDayNightMode(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', mode: 0);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("设置主流视频质量"),
onPressed: () async {
VconnexCamera.setStreamVideoQuality(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', quality: 2);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("获取录像列表"),
onPressed: () async {
VconnexCamera.getQueryRecordList(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', beginTime: 1663200000, endTime: 1663286399, type: 99, querySize: 128);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("启用移动检测"),
onPressed: () async {
VconnexCamera.setMotionDetectAlarmSwitch(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', montionDetectEnable: 1);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("启用人体检测"),
onPressed: () async {
VconnexCamera.humanDetectAlarmSwitch(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', humanDetectEnable: 1);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("启用区域检测"),
onPressed: () async {
VconnexCamera.areaDetectAlarmSwitch(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', areaDetectEnable: 1);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("启用入侵检测"),
onPressed: () async {
VconnexCamera.intrusionDetectSwitch(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', intrusionDetectEnable: 1);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("启用人脸识别"),
onPressed: () async {
VconnexCamera.faceRecognitionSwitch(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', faceRecognitionEnable: 1);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("启用车牌识别"),
onPressed: () async {
VconnexCamera.licensePlateRecognitionSwitch(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', licensePlateRecognitionEnable: 1);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("启用自动跟踪"),
onPressed: () async {
VconnexCamera.autoTrackingSwitch(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', autoTrackingEnable: 1);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("设置报警通知计划"),
onPressed: () async {
VconnexCamera.setAlarmNotifyPlan(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', beginTime: 1, endTime: 86300, dayOfWeek: [0, 1, 2, 3, 4, 5, 6]);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("设置子流视频质量"),
onPressed: () async {
VconnexCamera.setSubStreamVideoQuality(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', quality: 1);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("设置HSR检测灵敏度"),
onPressed: () async {
VconnexCamera.setHSRDetectSensitivity(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', hSRDetectSensitivity: 1);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("设置移动检测灵敏度"),
onPressed: () async {
VconnexCamera.setMotionDetectSensitivity(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', motionDetectSensitivity: 1);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("格式化存储介质"),
onPressed: () async {
VconnexCamera.formatStorageMedium(iotId: 'vyrpCPlpvVSRZXbjRDAE000000');
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("设置报警提示开关"),
onPressed: () async {
VconnexCamera.setAlarmPromptSwitch(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', alarmPromptSwitchEnable: 1);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("设置设备时区"),
onPressed: () async {
VconnexCamera.setDeviceTimeZone(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', timezone: 7);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("按时间获取图片列表"),
onPressed: () async {
VconnexCamera.getListPictureByTime(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', startTime: DateTime.now().millisecondsSinceEpoch - 3600, endTime: DateTime.now().millisecondsSinceEpoch);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
child: Text("设置翻转图像"),
onPressed: () async {
VconnexCamera.setImageFlipState(iotId: 'vyrpCPlpvVSRZXbjRDAE000000', state: 2);
},
),
),
],
),
),
),
],
),
),
),
);
}
}
更多关于Flutter摄像头管理插件vconnex_camera的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter摄像头管理插件vconnex_camera的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
vconnex_camera
是一个用于管理摄像头的 Flutter 插件,它提供了访问和控制设备摄像头的功能。以下是如何使用 vconnex_camera
插件的基本步骤:
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 vconnex_camera
插件的依赖。
dependencies:
flutter:
sdk: flutter
vconnex_camera: ^1.0.0 # 请根据实际情况使用最新版本
然后运行 flutter pub get
来获取依赖。
2. 导入插件
在你的 Dart 文件中导入 vconnex_camera
插件。
import 'package:vconnex_camera/vconnex_camera.dart';
3. 初始化摄像头
在使用摄像头之前,你需要初始化它。通常,你可以在 initState
方法中进行初始化。
class CameraExample extends StatefulWidget {
[@override](/user/override)
_CameraExampleState createState() => _CameraExampleState();
}
class _CameraExampleState extends State<CameraExample> {
late VconnexCameraController _cameraController;
[@override](/user/override)
void initState() {
super.initState();
_initializeCamera();
}
Future<void> _initializeCamera() async {
_cameraController = VconnexCameraController();
await _cameraController.initialize();
}
[@override](/user/override)
void dispose() {
_cameraController.dispose();
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Camera Example'),
),
body: Center(
child: _cameraController.isInitialized
? CameraPreview(_cameraController)
: CircularProgressIndicator(),
),
);
}
}
4. 显示摄像头预览
使用 CameraPreview
小部件来显示摄像头的实时预览。
CameraPreview(_cameraController)
5. 拍照
你可以使用 takePicture
方法来拍照,并保存照片到指定路径。
Future<void> takePicture() async {
final String imagePath = await _cameraController.takePicture();
print('Image saved to: $imagePath');
}
6. 切换摄像头
如果需要切换前后摄像头,可以使用 toggleCamera
方法。
Future<void> toggleCamera() async {
await _cameraController.toggleCamera();
}
7. 处理权限
确保你在 Android 和 iOS 上已经请求了摄像头权限。你可以在 AndroidManifest.xml
和 Info.plist
中添加相应的权限声明。
AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />
Info.plist
<key>NSCameraUsageDescription</key>
<string>We need access to your camera to take pictures.</string>
8. 处理异常
在实际使用中,可能会遇到摄像头不可用或权限被拒绝的情况。你可以使用 try-catch
块来处理这些异常。
try {
await _cameraController.initialize();
} catch (e) {
print('Failed to initialize camera: $e');
}
9. 释放资源
在不再使用摄像头时,记得调用 dispose
方法来释放资源。
[@override](/user/override)
void dispose() {
_cameraController.dispose();
super.dispose();
}
10. 完整示例
以下是一个完整的示例,展示了如何使用 vconnex_camera
插件来显示摄像头预览、拍照和切换摄像头。
import 'package:flutter/material.dart';
import 'package:vconnex_camera/vconnex_camera.dart';
class CameraExample extends StatefulWidget {
[@override](/user/override)
_CameraExampleState createState() => _CameraExampleState();
}
class _CameraExampleState extends State<CameraExample> {
late VconnexCameraController _cameraController;
bool _isCameraInitialized = false;
[@override](/user/override)
void initState() {
super.initState();
_initializeCamera();
}
Future<void> _initializeCamera() async {
try {
_cameraController = VconnexCameraController();
await _cameraController.initialize();
setState(() {
_isCameraInitialized = true;
});
} catch (e) {
print('Failed to initialize camera: $e');
}
}
Future<void> takePicture() async {
if (!_isCameraInitialized) return;
final String imagePath = await _cameraController.takePicture();
print('Image saved to: $imagePath');
}
Future<void> toggleCamera() async {
if (!_isCameraInitialized) return;
await _cameraController.toggleCamera();
}
[@override](/user/override)
void dispose() {
_cameraController.dispose();
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Camera Example'),
),
body: Center(
child: _isCameraInitialized
? CameraPreview(_cameraController)
: CircularProgressIndicator(),
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: takePicture,
child: Icon(Icons.camera),
),
SizedBox(height: 16),
FloatingActionButton(
onPressed: toggleCamera,
child: Icon(Icons.switch_camera),
),
],
),
);
}
}
void main() {
runApp(MaterialApp(
home: CameraExample(),
));
}