Flutter音频识别插件flutter_shazam_kit的使用
Flutter音频识别插件flutter_shazam_kit的使用
一个帮助你通过设备麦克风检测歌曲的插件。
注意:
- 此插件依赖于Apple的ShazamKit,需要iOS 15或更高版本,并且需要Android API级别23(Android 6.0)或更高版本。
- 在此插件的早期版本中,我只使用了
ShazamCatalog
,它是用于音乐检测的默认库。未来我计划实现CustomCatalog
。
配置
Android配置
-
在你的
AndroidManifest.xml
文件中添加以下权限:<uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.INTERNET"/>
-
前往ShazamKit下载页面并下载最新版本的ShazamKit。下载后,在项目的
android/app
目录下创建一个名为libs
的新文件夹,并将.aar
文件放入该文件夹中。你的Android项目结构应如下所示:
-
在你的应用级
build.gradle
文件中,将minSdkVersion
更改为23并同步项目。minSdkVersion 23
-
要在Android上使用
ShazamCatalog
,你需要一个Apple开发者令牌以访问Apple提供的ShazamKit服务。请参阅此链接获取更多详情。如果你不知道如何操作,请遵循以下步骤:
-
创建媒体标识符
- 前往证书、标识符与配置文件,点击侧边栏中的标识符。
- 点击左上角的添加按钮(+),选择Media IDs,然后点击继续。
- 输入描述和标识符,启用ShazamKit并点击继续。
- 点击注册,你应该会在标识符列表中看到新的媒体ID。
-
创建私钥(
.p8
)- 前往证书、标识符与配置文件,点击侧边栏中的密钥。
- 点击左上角的添加按钮(+),输入你的密钥名称。
- 启用Media Services (MusicKit, ShazamKit)复选框,然后点击右侧的配置按钮。
- 选择你之前创建的媒体ID并点击保存。
- 点击继续,然后点击注册。
- 下载私钥(
.p8
文件)并记住你的Key ID。
-
生成开发者令牌
- 请参阅此链接了解如何生成开发者令牌。
- 由于苹果政策,开发者令牌只能有效3个月。因此,你应该有一个远程位置来存储和刷新生成的开发者令牌,你可以使用后端服务器或类似Firebase Remote Config的东西来存储、生成和刷新你的开发者令牌。
- 为了测试目的,你可以使用以下Node JS代码片段,或者你可以使用我的仓库来创建它。
- 注意:此代码片段使用著名的
jsonwebtoken
库,所以在使用此代码片段之前需要安装该库。
"use strict"; const fs = require("fs"); const jwt = require("jsonwebtoken"); const privateKey = fs.readFileSync("<YOUR_P8_FILE_NAME>.p8").toString(); const teamId = "<YOUR_TEAM_ID>"; const keyId = "<YOUR_KEY_ID>"; const jwtToken = jwt.sign({}, privateKey, { algorithm: "ES256", issuer: teamId, expiresIn: "180d", // 由于苹果政策,开发者密钥只能有效180天 header: { alg: "ES256", kid: keyId, typ: "JWT" } }); console.log(jwtToken);
-
iOS配置
-
在你的
Info.plist
文件中添加以下权限:<key>NSMicrophoneUsageDescription</key> <string>需要麦克风访问以检测音乐</string>
-
更新你的
Podfile
全局iOS平台到iOS 15.0。# 取消注释这一行以定义项目的全局平台 platform :ios, '15.0'
-
注册新App ID
- 前往证书、标识符与配置文件,点击侧边栏中的标识符。
- 点击左上角的添加按钮(+),选择App IDs,然后点击继续。
- 选择App类型作为此标识符,然后点击继续。
- 填写描述和Bundle ID(必须为你的App Bundle ID),切换到App Services选项卡并启用ShazamKit服务,然后点击继续。
- 点击注册按钮以注册新App ID。
- 你应该会在标识符列表中看到你的新App ID。
如何使用
初始化
初始化配置
final _flutterShazamKitPlugin = FlutterShazamKit();
[@override](/user/override)
void initState() {
super.initState();
_flutterShazamKitPlugin
.configureShazamKitSession(developerToken: developerToken);
}
[@override](/user/override)
void dispose() {
super.dispose();
_flutterShazamKitPlugin.endSession();
}
监听匹配事件
_flutterShazamKitPlugin.onMatchResultDiscovered((result) {
if (result is Matched) {
print(result.mediaItems);
} else if (result is NoMatch) {
// 在无匹配情况下执行某些操作
}
});
监听检测状态变化
_flutterShazamKitPlugin.onDetectStateChanged((state) {
print(state);
});
监听错误
_flutterShazamKitPlugin.onError((error) {
print(error.message);
});
通过麦克风检测
开始通过麦克风检测
_flutterShazamKitPlugin.startDetectingByMicrophone();
结束检测
_flutterShazamKitPlugin.endDetecting();
完整的示例请参见example
文件夹中的main.dart
文件。
完整示例
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_shazam_kit/flutter_shazam_kit.dart';
void main() {
runApp(const MyApp());
}
const developerToken = "<YOUR_DEVELOPER_TOKEN>"; // 仅适用于Android
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _flutterShazamKitPlugin = FlutterShazamKit();
DetectState _state = DetectState.none;
final List<MediaItem> _mediaItems = [];
[@override](/user/override)
void initState() {
super.initState();
_flutterShazamKitPlugin
.configureShazamKitSession(developerToken: developerToken)
.then((value) {
_flutterShazamKitPlugin.onMatchResultDiscovered((result) {
if (result is Matched) {
setState(() {
_mediaItems.insertAll(0, result.mediaItems);
});
} else if (result is NoMatch) {
// 在无匹配情况下执行某些操作
}
_flutterShazamKitPlugin.endDetectionWithMicrophone();
});
_flutterShazamKitPlugin.onDetectStateChanged((state) {
setState(() {
_state = state;
});
});
_flutterShazamKitPlugin.onError((error) {
print(error.message);
});
});
}
[@override](/user/override)
void dispose() {
super.dispose();
_flutterShazamKitPlugin.endSession();
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('插件示例应用'),
),
body: _body()),
);
}
Widget _body() {
return Column(
children: [_detectButton(), Expanded(child: _detectedItems())],
);
}
Widget _detectButton() {
return CupertinoButton(
child: Container(
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primary,
borderRadius: BorderRadius.circular(10)),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(_state == DetectState.none ? "开始检测" : "结束检测",
style:
Theme.of(context).textTheme.headline6?.copyWith(color: Colors.white)),
if (_state == DetectState.detecting) ...[
const SizedBox(width: 10),
const SizedBox(
height: 10,
width: 10,
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white)),
)
]
],
),
),
onPressed: () async {
if (_state == DetectState.detecting) {
endDetect();
} else {
startDetect();
}
});
}
Widget _detectedItems() {
return ListView.builder(
itemCount: _mediaItems.length,
shrinkWrap: true,
itemBuilder: ((context, index) {
MediaItem item = _mediaItems[index];
return Container(
margin: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: const Color(0xFFF5f5f5),
borderRadius: BorderRadius.circular(10)),
child: Row(
children: [
Container(
decoration:
BoxDecoration(borderRadius: BorderRadius.circular(10)),
height: 100,
width: 100,
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.network(
item.artworkUrl,
height: 150.0,
width: 100.0,
),
),
),
const SizedBox(width: 10),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(item.title,
style: Theme.of(context).textTheme.subtitle1
?.copyWith(fontWeight: FontWeight.bold)),
Text("艺术家: ${item.artist}",
style: Theme.of(context).textTheme.subtitle2
?.copyWith(fontWeight: FontWeight.bold)),
Text("流派: ${item.genres.join(", ")}",
style: Theme.of(context).textTheme.subtitle2
?.copyWith(fontWeight: FontWeight.bold))
],
),
),
)
],
),
);
}));
}
startDetect() {
_flutterShazamKitPlugin.startDetectionWithMicrophone();
}
endDetect() {
_flutterShazamKitPlugin.endDetectionWithMicrophone();
}
}
更多关于Flutter音频识别插件flutter_shazam_kit的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter音频识别插件flutter_shazam_kit的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何使用Flutter音频识别插件flutter_shazam_kit
的示例代码。这个插件允许你在Flutter应用中实现音频识别功能。请注意,实际使用时,你可能需要根据具体需求和项目配置进行相应调整。
首先,确保你的Flutter项目已经设置好,并在pubspec.yaml
文件中添加flutter_shazam_kit
依赖:
dependencies:
flutter:
sdk: flutter
flutter_shazam_kit: ^最新版本号 # 替换为当前最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,在你的Flutter应用中,你可以按照以下步骤使用flutter_shazam_kit
进行音频识别:
- 导入插件:
在你的Dart文件中导入flutter_shazam_kit
:
import 'package:flutter_shazam_kit/flutter_shazam_kit.dart';
- 初始化音频识别:
在需要进行音频识别的页面或组件中,初始化音频识别器。这通常在你的State类中进行:
class AudioRecognitionPage extends StatefulWidget {
@override
_AudioRecognitionPageState createState() => _AudioRecognitionPageState();
}
class _AudioRecognitionPageState extends State<AudioRecognitionPage> {
late AudioRecognition _audioRecognition;
@override
void initState() {
super.initState();
_audioRecognition = AudioRecognition();
_initializeAudioRecognition();
}
Future<void> _initializeAudioRecognition() async {
try {
await _audioRecognition.initialize();
print('Audio recognition initialized');
} catch (e) {
print('Failed to initialize audio recognition: $e');
}
}
@override
void dispose() {
_audioRecognition.dispose();
super.dispose();
}
// 其他方法...
}
- 开始和停止音频识别:
添加按钮或其他UI元素来控制音频识别的开始和停止:
class _AudioRecognitionPageState extends State<AudioRecognitionPage> {
// ...其他代码...
void _startRecognition() async {
try {
_audioRecognition.startListening((recognitionResult) {
print('Recognition result: $recognitionResult');
// 在这里处理识别结果,例如更新UI
});
} catch (e) {
print('Failed to start recognition: $e');
}
}
void _stopRecognition() async {
try {
await _audioRecognition.stopListening();
print('Recognition stopped');
} catch (e) {
print('Failed to stop recognition: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Audio Recognition'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: _startRecognition,
child: Text('Start Recognition'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _stopRecognition,
child: Text('Stop Recognition'),
),
],
),
),
);
}
}
- 处理识别结果:
在上面的代码中,_startRecognition
方法中的回调函数会接收识别结果。你可以根据这些结果更新UI或执行其他操作。
请注意,flutter_shazam_kit
是一个假设的插件名称,实际上并没有一个广泛使用的名为flutter_shazam_kit
的官方插件。如果你是在寻找一个具体的音频识别插件,你可能需要查找类似功能的插件,如flutter_sound
或其他第三方音频处理库,并结合机器学习或音频识别服务(如Google Cloud Speech-to-Text API)来实现音频识别功能。
此外,实际使用时,音频识别功能可能涉及复杂的后台处理和API调用,因此你可能需要仔细阅读插件文档,并根据项目需求进行适当的配置和调试。