Flutter mobile,播放midi文件

Posted

技术标签:

【中文标题】Flutter mobile,播放midi文件【英文标题】:Flutter mobile, playing midi files 【发布时间】:2021-01-01 08:02:09 【问题描述】:

我想知道如何在移动应用上播放 MIDI 文件

我找到了两个midi库,但没有看到如何实现播放midi文件的功能

https://pub.dev/packages/flutter_midi 这里我在我的应用程序中使用这个包来播放 sf2 音频,虽然我当时只能播放单个音符,这是我用来做的代码

    class KeyPage extends StatefulWidget 
  @override
  _KeyPageState createState() => _KeyPageState();


class _KeyPageState extends State<KeyPage> 
  //final _flutterMidi = FlutterMidi(); //TODO 1 check TODO 2

  @override
  void initState() 
    if (!kIsWeb) 
      load(_value);
     else 
      FlutterMidi.prepare(
          sf2:
              null); //TODO 2 check what to do here with static issue Original line was:
      // _flutterMidi.prepare(sf2: null);
    
    super.initState();
  

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

https://pub.dev/packages/dart_midi 还没有尝试过这个包,但是通过阅读它,我看不到它播放midi文件的功能,虽然他们使用的语言对我来说是新的,所以我猜这个库是这样做的,但我不明白如何

谢谢

【问题讨论】:

您好@Jan,您需要移动应用还是网络应用? 您好,移动应用需要它 嗨@Jan 对于移动来说它更简单:fm.playMidiNote(midi: midiNote); C2 例如是 36; fm 是一个 FlutterMidi 实例 谢谢,虽然我的意思是播放整个 MIDI 文件(如 For Elise 的作品或类似的音乐),而不是一次播放一个音符 【参考方案1】:

这是我使用 Flutter_midi 的实现。

我使用了一个计时器来播放整个音符序列,一个接一个。 要使其正常工作,您需要提供要弹奏的音符数量以及它们之间的时间。

这确实适用于 ios 模拟器,但我想说Flutter_midi 包含一些已弃用的代码,并且它不提供以midi 格式播放完整歌曲的方法。

例如,无法设置音符的速度。

反正我已经实现了这个解决方案,但我个人不推荐这个包。

class MyHomePage extends StatefulWidget 
  const MyHomePage(Key? key) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();


class _MyHomePageState extends State<MyHomePage> 
  late FlutterMidi fm;
  final songFile = 'assets/Piano.sf2';

  @override
  void initState() 
    super.initState();

    fm = FlutterMidi();
    _load(songFile);
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: const Text('MidiPlayer'),
      ),
      body: Center(
        child: TextButton(
          onPressed: () 
            _playSong(
              timing: 100,
              notes: 30,
            );
          ,
          child: const Text('Play'),
        ),
      ),
    );
  

  void _load(String asset) async 
    fm.unmute();
    ByteData _byte = await rootBundle.load(asset);
    fm.prepare(sf2: _byte, name: songFile.replaceAll('assets/', ''));
  

  void _playSong(
    required int timing, //Time between notes
    required int notes, //Number of notes to be played
  ) 
    var note = 0;
    Timer.periodic(Duration(milliseconds: timing), (timer) 
      //You played the last note
      if (note == notes) 
        fm.stopMidiNote(midi: note - 1);
        timer.cancel();
        return;
      

      //Interrupt the previous note
      if (note > 0) 
        fm.stopMidiNote(midi: note - 1);
      

      //Play the current note and increase the counter
      fm.playMidiNote(midi: note++);
    );
  


【讨论】:

以上是关于Flutter mobile,播放midi文件的主要内容,如果未能解决你的问题,请参考以下文章

FL STUDIO 载入midi后使用别的软音源只有一轨有声音(求大神给详细解答)

在 Python 中为 Kivy 播放跨平台、移动、MIDI - 这可能吗?

异步播放midi文件?

MIDI信息为什么不能通过FL Studio输出

使用 chrome 播放 MIDI 文件

在 python 中播放 MIDI 文件?