Flutter媒体处理与AI集成插件mediapipe_genai的使用
Flutter媒体处理与AI集成插件mediapipe_genai的使用
一个用于在Flutter中使用MediaPipe GenAI API的插件,包含多个基于生成式AI的MediaPipe任务。
要了解更多关于MediaPipe的信息,请访问 MediaPipe网站。
开始使用
要开始使用MediaPipe,请参阅 文档。
支持的任务
任务 | Android | iOS | Web | Windows | macOS | Linux |
---|---|---|---|---|---|---|
推理 | ✔ | ✔ | ✖ | ✖ | ✔ | ✖ |
选择设备
离线推理是一项资源密集型任务,建议在Pixel 7或更新的设备(或其他类似的Android设备)上运行。对于iOS设备,建议使用iPhone 13或更新的设备。
移动仿真器不被支持。
对于桌面端,macOS被支持,Windows和Linux将在不久的将来支持。
使用方法
要开始使用此插件,您必须处于 master
通道。
其次,您需要启用 native-assets
实验,使用 --enable-experiment=native-assets
标志运行任何使用 $ dart
命令行工具的命令。
要在Flutter中全局启用此功能,请运行:
$ flutter config --enable-native-assets
要在Flutter中全局禁用此功能,请运行:
$ flutter config --no-enable-native-assets
添加依赖
在您的 pubspec.yaml
文件中添加 mediapipe_core
和 mediapipe_genai
依赖:
dependencies:
flutter:
sdk: flutter
mediapipe_core: latest
mediapipe_genai: latest
添加tflite模型
与MediaPipe的其他任务风味(文本、视觉和音频)不同,生成式AI模型必须在运行时从开发者托管的URL下载。为了获取这些模型,您需要创建一个 Kaggle 账户,接受服务条款,下载您想在应用中使用的模型,并自行托管这些模型在您选择的位置,然后配置您的应用以在运行时下载它们。
查看示例目录以获得一个实现示例和指导,了解如何使MediaPipe的推理任务工作。
CPU与GPU模型
推理任务可以在CPU或GPU上运行,每个模型都为每种策略编译一次。当您从Kaggle选择要使用的模型时,请注意其CPU和GPU变体,并确保调用适当的选项构造函数。
初始化引擎
推理示例:
import 'package:mediapipe_genai/mediapipe_genai.dart';
// 您在运行时下载文件的位置,或者提前将模型放置在自己的位置(使用`adb push`等)
final String modelPath = getModelPath();
// 根据您的模型选择CPU或GPU运行时
// 查看示例以获取传递给`LlmInferenceOptions`类其余参数的合适值。
bool isGpu = yourValueHere;
final options = switch (isGpu) {
true => LlmInferenceOptions.gpu(
modelPath: modelPath,
// 其他参数...
),
false => LlmInferenceOptions.cpu(
modelPath: modelPath,
// 其他参数...
),
};
// 创建推理引擎
final engine = LlmInferenceEngine(options);
// 流式处理引擎结果
final Stream<String> responseStream = engine.generateResponse('Hello, world!');
await for (final String responseChunk in responseStream) {
print('The LLM said: $responseChunk');
}
问题和反馈
请在我们的 问题跟踪器 中提交与Flutter-MediaPipe相关的错误、问题或功能请求。
与Flutter相关的问题可以提交到 Flutter问题跟踪器。
要为该插件贡献更改,请参阅我们的 贡献指南,并打开一个 拉取请求。
示例代码
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:logging/logging.dart';
import 'llm_inference_demo.dart';
import 'logging.dart';
/// {[@template](/user/template) AppBlocObserver}
/// 记录所有与`pkg:flutter_bloc`相关的事项。
/// {[@endtemplate](/user/endtemplate)}
class AppBlocObserver extends BlocObserver {
/// {[@macro](/user/macro) AppBlocObserver}
const AppBlocObserver();
static final _log = Logger('AppBlocObserver');
[@override](/user/override)
void onChange(BlocBase<dynamic> bloc, Change<dynamic> change) {
_log.finest('onChange(${bloc.runtimeType}, $change)');
super.onChange(bloc, change);
}
[@override](/user/override)
void onEvent(Bloc<dynamic, dynamic> bloc, Object? event) {
_log.finest('onEvent($event)');
super.onEvent(bloc, event);
}
[@override](/user/override)
void onError(BlocBase<dynamic> bloc, Object error, StackTrace stackTrace) {
_log.shout('onError(${bloc.runtimeType}, $error, $stackTrace)');
super.onError(bloc, error, stackTrace);
}
}
void main() {
initLogging();
Bloc.observer = const AppBlocObserver();
runApp(
const MaterialApp(
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate, // 这是必需的
],
home: MainApp(),
),
);
}
class MainApp extends StatefulWidget {
const MainApp({super.key});
[@override](/user/override)
State<MainApp> createState() => _MainAppState();
}
class _MainAppState extends State<MainApp> {
final PageController controller = PageController();
final titles = <String>['推理'];
int titleIndex = 0;
[@override](/user/override)
void initState() {
controller.addListener(() {
final newIndex = controller.page?.toInt();
if (newIndex != null && newIndex != titleIndex) {
setState(() {
titleIndex = newIndex;
});
}
});
super.initState();
}
void switchToPage(int index) {
controller.animateToPage(
index,
duration: const Duration(milliseconds: 200),
curve: Curves.easeOut,
);
setState(() {
titleIndex = index;
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: controller,
children: const <Widget>[
LlmInferenceDemo(),
],
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: titleIndex,
onTap: switchToPage,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.chat_bubble),
activeIcon: Icon(Icons.chat_bubble, color: Colors.blue),
label: '推理',
),
BottomNavigationBarItem(
icon: Icon(Icons.cancel),
activeIcon: Icon(Icons.cancel, color: Colors.blue),
label: '即将推出',
),
],
),
);
}
}
更多关于Flutter媒体处理与AI集成插件mediapipe_genai的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter媒体处理与AI集成插件mediapipe_genai的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中集成和使用mediapipe_genai
插件进行媒体处理与AI集成的代码示例。这个插件可以帮助你利用MediaPipe和Google的AI模型进行实时媒体处理。
1. 添加依赖
首先,你需要在pubspec.yaml
文件中添加mediapipe_genai
依赖:
dependencies:
flutter:
sdk: flutter
mediapipe_genai: ^最新版本号 # 请替换为实际的最新版本号
然后运行flutter pub get
来安装依赖。
2. 配置权限
在AndroidManifest.xml
中配置相机和麦克风权限(如果需要使用这些功能):
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
3. 初始化插件
在你的Flutter项目的Dart代码中,初始化mediapipe_genai
插件。这里是一个简单的例子,展示如何使用插件进行实时面部检测:
import 'package:flutter/material.dart';
import 'package:mediapipe_genai/mediapipe_genai.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: FaceDetectionScreen(),
);
}
}
class FaceDetectionScreen extends StatefulWidget {
@override
_FaceDetectionScreenState createState() => _FaceDetectionScreenState();
}
class _FaceDetectionScreenState extends State<FaceDetectionScreen> {
late MediaPipeGenaiPlugin mediapipeGenai;
@override
void initState() {
super.initState();
mediapipeGenai = MediaPipeGenaiPlugin();
// 初始化MediaPipe模型,这里以面部检测为例
mediapipeGenai.initialize(model: 'face_detection');
mediapipeGenai.startCamera();
mediapipeGenai.addListener(() {
setState(() {}); // 更新UI以显示检测结果
});
}
@override
void dispose() {
mediapipeGenai.stopCamera();
mediapipeGenai.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Face Detection with MediaPipe and AI'),
),
body: Center(
child: mediapipeGenai.frame != null
? CustomPaint(
size: Size(mediapipeGenai.frame!.width.toDouble(), mediapipeGenai.frame!.height.toDouble()),
painter: FacePainter(mediapipeGenai.results!))
: CircularProgressIndicator(),
),
);
}
}
class FacePainter extends CustomPainter {
final List<dynamic> results;
final Uint8List? frame;
FacePainter(this.results, {this.frame}) {
// 你可以在这里处理frame和results,进行绘制
}
@override
void paint(Canvas canvas, Size size) {
// 绘制逻辑,比如根据results中的面部检测数据在frame上绘制矩形框
final Paint paint = Paint()
..color = Colors.red
..style = PaintingStyle.stroke
..strokeWidth = 4.0;
results.forEach((result) {
final Rect rect = Rect.fromLTWH(
result['x']! - result['width']! / 2,
result['y']! - result['height']! / 2,
result['width']!,
result['height']!,
);
canvas.drawRect(rect, paint);
});
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true; // 每当状态改变时重绘
}
}
注意事项
- 权限处理:在实际应用中,你需要处理权限请求,确保用户在使用前已授予必要的权限。
- 错误处理:添加错误处理逻辑,以应对初始化失败、相机不可用等情况。
- 性能优化:在实际项目中,你可能需要优化绘制逻辑,以提高性能和用户体验。
这个示例展示了如何在Flutter中使用mediapipe_genai
插件进行基本的面部检测。你可以根据需求扩展此代码,以处理其他类型的媒体和AI任务。