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:
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');
}
});
});