1

I am working on a website for a project where the user uploads a MIDI file which is then sent to the backend to be processed, and the processed MIDI file is then sent back to the user. The issue is that after uploading the file through Flutter in an http.MultipartRequest the header changes and and some seemingly random characters are added to it, which causes the Python library mido to no longer recognise it as a valid MIDI file. Is the file supposed to change in some way in transit or during encoding/decoding? And how do I remedy that?

The beginning of the same file after being uploaded through FTP first and then through the Flutter frontend: Text

Mido error:

b'\xbf\xbdMT'
Traceback (most recent call last):
  File "generate.py", line 141, in <module>
    midi_file = MidiFile(MIDI_PATH)
  File "/usr/local/lib/python3.8/dist-packages/miditoolkit/midi/parser.py", line 31, in __init__
    mido_obj = mido.MidiFile(filename=filename, clip=clip, charset=charset)
  File "/usr/local/lib/python3.8/dist-packages/mido/midifiles/midifiles.py", line 324, in __init__
    self._load(file)
  File "/usr/local/lib/python3.8/dist-packages/mido/midifiles/midifiles.py", line 359, in _load
    self.tracks.append(read_track(infile,
  File "/usr/local/lib/python3.8/dist-packages/mido/midifiles/midifiles.py", line 181, in read_track
    raise IOError('no MTrk header at start of track')
OSError: no MTrk header at start of track

The Flutter code responsible for the upload and sending the POST request:

void _pickFile() async {
    final result = await FilePicker.platform.pickFiles(allowMultiple: false);

    if (result == null) {
      return;
    }

    setState(() {
      _isLoading = true;
    });

    if (result.files.first.bytes != null) {
      final request =
          http.MultipartRequest('POST', Uri.parse(genAPI));
      request.files.add(await http.MultipartFile.fromBytes(
          'file', result.files.first.bytes!,
          contentType: MediaType('audio', 'midi')));
      print("files");
      print(request.files);
      try {
        final response = await request.send();
        if (response.statusCode == 200) {
          // Do something with the response
          print("response");
          print(response);
          setState(() {
            _isDownloadable = true;
            _file = result.files.first;
          });
        } else {
          // Handle error response
          print(response);
        }
      } catch (e) {
        // Handle network errors
        print(e);
      }
    } else {
      print('ERROR');
    }

    setState(() {
      _isLoading = false;
    });
  }

The Node.JS code that receives the file and writes it to disk:

app.post('/process-file', upload.single('file'), (req, res) => {
  // Check if req.file is defined
  if (!req.body.file) {
    console.log("NO FILE IN REQUEST");
    return res.status(400).send('No file uploaded');
  }

  // Get the uploaded file from the request object
  const file = req.body.file;

  const fpath = Date.now() + '.mid'; //file.originalname;

  // Write file to disk
  fs.writeFileSync('uploads/orig_' + fpath, file, (err) => {
    if (err) {
      console.error(err);
      return res.status(500).send('Error writing file to disk');
    } else {
      console.error('file loaded successfully');
    } 
  });

});
Marwan Sabry
  • 85
  • 3
  • 9

0 Answers0