Flutter音频识别插件flutter_shazam_kit的使用

发布于 1周前 作者 ionicwang 来自 Flutter

Flutter音频识别插件flutter_shazam_kit的使用

一个帮助你通过设备麦克风检测歌曲的插件。

注意:

  • 此插件依赖于Apple的ShazamKit,需要iOS 15或更高版本,并且需要Android API级别23(Android 6.0)或更高版本。
  • 在此插件的早期版本中,我只使用了ShazamCatalog,它是用于音乐检测的默认库。未来我计划实现CustomCatalog

配置

Android配置

  1. 在你的AndroidManifest.xml文件中添加以下权限:

    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    
    <uses-permission android:name="android.permission.INTERNET"/>
    
  2. 前往ShazamKit下载页面并下载最新版本的ShazamKit。下载后,在项目的android/app目录下创建一个名为libs的新文件夹,并将.aar文件放入该文件夹中。

    你的Android项目结构应如下所示:

    Untitled

  3. 在你的应用级build.gradle文件中,将minSdkVersion更改为23并同步项目。

    minSdkVersion 23
    
  4. 要在Android上使用ShazamCatalog,你需要一个Apple开发者令牌以访问Apple提供的ShazamKit服务。请参阅此链接获取更多详情。

    如果你不知道如何操作,请遵循以下步骤:

    1. 创建媒体标识符

      • 前往证书、标识符与配置文件,点击侧边栏中的标识符。
      • 点击左上角的添加按钮(+),选择Media IDs,然后点击继续
      • 输入描述和标识符,启用ShazamKit并点击继续。

      Untitled

      • 点击注册,你应该会在标识符列表中看到新的媒体ID。
    2. 创建私钥(.p8

      • 前往证书、标识符与配置文件,点击侧边栏中的密钥。
      • 点击左上角的添加按钮(+),输入你的密钥名称。
      • 启用Media Services (MusicKit, ShazamKit)复选框,然后点击右侧的配置按钮。

      Untitled

      • 选择你之前创建的媒体ID并点击保存。

      Untitled

      • 点击继续,然后点击注册。
      • 下载私钥(.p8文件)并记住你的Key ID。

      Untitled

    3. 生成开发者令牌

      • 请参阅此链接了解如何生成开发者令牌。
      • 由于苹果政策,开发者令牌只能有效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配置

  1. 在你的Info.plist文件中添加以下权限:

    <key>NSMicrophoneUsageDescription</key>
    <string>需要麦克风访问以检测音乐</string>
    
  2. 更新你的Podfile全局iOS平台到iOS 15.0。

    # 取消注释这一行以定义项目的全局平台
    platform :ios, '15.0'
    
  3. 注册新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

1 回复

更多关于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进行音频识别:

  1. 导入插件

在你的Dart文件中导入flutter_shazam_kit

import 'package:flutter_shazam_kit/flutter_shazam_kit.dart';
  1. 初始化音频识别

在需要进行音频识别的页面或组件中,初始化音频识别器。这通常在你的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();
  }

  // 其他方法...
}
  1. 开始和停止音频识别

添加按钮或其他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'),
            ),
          ],
        ),
      ),
    );
  }
}
  1. 处理识别结果

在上面的代码中,_startRecognition方法中的回调函数会接收识别结果。你可以根据这些结果更新UI或执行其他操作。

请注意,flutter_shazam_kit是一个假设的插件名称,实际上并没有一个广泛使用的名为flutter_shazam_kit的官方插件。如果你是在寻找一个具体的音频识别插件,你可能需要查找类似功能的插件,如flutter_sound或其他第三方音频处理库,并结合机器学习或音频识别服务(如Google Cloud Speech-to-Text API)来实现音频识别功能。

此外,实际使用时,音频识别功能可能涉及复杂的后台处理和API调用,因此你可能需要仔细阅读插件文档,并根据项目需求进行适当的配置和调试。

回到顶部