Flutter MIDI通信插件flutter_midi的使用

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

Flutter MIDI通信插件flutter_midi的使用

flutter_midi 是一个用于在 iOS 和 Android 上播放 MIDI 音频的 Flutter 插件。该插件通过 SoundFont (.sf2) 文件来实现音频播放功能。

安装与配置

1. 下载 SoundFont 文件

首先,你需要下载一些 SoundFont (.sf2) 文件,例如 Piano.SF2SmallTimGM6mb.sf2

2. 更新 pubspec.yaml

将下载的 .sf2 文件存储在项目的 /assets/sf2/ 目录下,并更新 pubspec.yaml 文件以包含这些文件:

flutter:
  assets:
    - assets/sf2/Piano.SF2
    - assets/sf2/SmallTimGM6mb.sf2

3. 加载 SoundFont 文件

在应用启动时加载 SoundFont 文件以便后续播放音符。

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_midi/flutter_midi.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  [@override](/user/override)
  void initState() {
    load('assets/sf2/Piano.SF2');
    super.initState();
  }

  void load(String asset) async {
    FlutterMidi.unmute(); // Optionally Unmute
    ByteData _byte = await rootBundle.load(asset);
    FlutterMidi.prepare(sf2: _byte);
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter MIDI Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: () {
                  FlutterMidi.playMidiNote(midi: 60); // Play middle C
                },
                child: Text('Play Middle C'),
              ),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: () {
                  FlutterMidi.stopMidiNote(midi: 60); // Stop middle C
                },
                child: Text('Stop Middle C'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

示例 Demo

以下是一个完整的示例 Demo,展示了如何加载和播放 MIDI 音符:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_midi/flutter_midi.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final _flutterMidi = FlutterMidi();
  String _value = 'assets/sf2/Piano.SF2';

  [@override](/user/override)
  void initState() {
    if (!kIsWeb) {
      load(_value);
    } else {
      _flutterMidi.prepare(sf2: null);
    }
    super.initState();
  }

  void load(String asset) async {
    print('Loading File...');
    _flutterMidi.unmute();
    ByteData _byte = await rootBundle.load(asset);
    _flutterMidi.prepare(sf2: _byte, name: _value.replaceAll('assets/', ''));
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Center(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisSize: MainAxisSize.min,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                child: Text('Play C'),
                onPressed: () {
                  _play(60);
                },
              ),
            ],
          ),
        ),
      ),
    );
  }

  void _play(int midi) {
    if (kIsWeb) {
      // WebMidi.play(midi);
    } else {
      _flutterMidi.playMidiNote(midi: midi);
    }
  }
}

更多关于Flutter MIDI通信插件flutter_midi的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter MIDI通信插件flutter_midi的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何使用Flutter MIDI通信插件flutter_midi的代码示例。这个示例将展示如何初始化MIDI插件、列出连接的MIDI设备、发送MIDI消息以及接收MIDI消息。

首先,确保你已经在pubspec.yaml文件中添加了flutter_midi依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_midi: ^latest_version  # 替换为最新的版本号

然后运行flutter pub get来安装依赖。

主代码文件 (main.dart)

import 'package:flutter/material.dart';
import 'package:flutter_midi/flutter_midi.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  FlutterMidi? _midi;
  List<MidiDeviceInfo> _connectedDevices = [];

  @override
  void initState() {
    super.initState();
    _initializeMidi();
  }

  Future<void> _initializeMidi() async {
    _midi = FlutterMidi();

    // 监听设备连接状态变化
    _midi!.deviceConnectionStateChanged!.listen((event) {
      setState(() {
        _connectedDevices = event.connectedDevices;
      });
    });

    // 监听MIDI消息
    _midi!.midiMessageReceived!.listen((event) {
      print('Received MIDI message: ${event.data}');
    });

    // 请求权限并列出已连接的设备
    await _midi!.requestMidiAccess();
    setState(() {
      _connectedDevices = _midi!.connectedDevices;
    });
  }

  Future<void> _sendMidiMessage(int status, int data1, int data2) async {
    if (_midi!.isOpen) {
      Uint8List message = Uint8List.fromList([status, data1, data2]);
      await _midi!.sendData(message);
      print('Sent MIDI message: $message');
    } else {
      print('MIDI is not open');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter MIDI Demo'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text('Connected MIDI Devices:'),
              SizedBox(height: 16),
              Expanded(
                child: ListView.builder(
                  itemCount: _connectedDevices.length,
                  itemBuilder: (context, index) {
                    return ListTile(
                      title: Text(_connectedDevices[index].name),
                    );
                  },
                ),
              ),
              SizedBox(height: 16),
              ElevatedButton(
                onPressed: () async {
                  await _sendMidiMessage(0x90, 60, 127); // Note on C4 with velocity 127
                },
                child: Text('Send Note On'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

解释

  1. 依赖添加:在pubspec.yaml中添加flutter_midi依赖。
  2. 初始化MIDI:在initState方法中初始化FlutterMidi实例,并监听设备连接状态变化和MIDI消息接收。
  3. 请求MIDI访问权限:使用_midi!.requestMidiAccess()请求MIDI访问权限。
  4. 列出已连接设备:在UI中列出已连接的MIDI设备。
  5. 发送MIDI消息:定义一个方法_sendMidiMessage,用于发送MIDI消息。在这个例子中,发送了一个Note On消息。

这个示例展示了如何使用flutter_midi插件进行基本的MIDI通信。你可以根据需要扩展这个示例,例如处理更多类型的MIDI消息、优化UI等。

回到顶部