0
votes

so I have a program that grabs the meta data out of the sound file.

If the sound file has an album image I am able to turn that into a blob object url and use it locally, but how would I be able to save that blob image to the server?

Right now I have two file input fields, one to select the sound file and one to select an image if there is none pulled from the sound file.

I am using musicmetadata (https://github.com/leetreveil/musicmetadata) and this is how I pull the image from the sound file.

musicmetadata(data, function(err, result){
            if(err)
                console.log(err);

            if(result.picture.length > 0){
                var picture = result.picture[0];
                var url = URL.createObjectURL(new Blob([picture.data], {'type':'image/' + picture.format}));
                var image = document.getElementById('albumImage');

                imageList.innerHTML = "<p>" + result.title + "." + picture.format + "</p>";

                image.style.backgroundImage = "url(" + url + ")";
                image.style.backgroundRepeat = "no-repeat";
                image.style.backgroundSize = "155px 131px";

                bgImage = url;
            } else {
                imageList.innerHTML = "<p>No image available in Meta Data<p>";
            }

I've tried formData to set and append the blob to the form once its posted, but it just passes as either undefined or the blob url blob:http://localhost:3000/5c9db74b-f4f1-4125-8839-a7604ec1f7f9

I am using express with multer to handle file uploads. I would be fine with adding test conditions that if there is an album image on post, then save it to the file system else just save the file from the file input image field.

here is my post request info for the upload just in case.

var manageUpload = upload.fields([{ name: 'fileElem', maxCount: 1 }, { name: 'imageElem', maxCount: 1 } ]);
app.post('/upload', manageUpload, function(req, res){
    post = new Post();

    User.findOne({ username: req.session.user }, function(err, newUser){
        if(err) console.log(err);

        post.audioFile = req.files['fileElem'][0].filename;

        if(typeof req.files['imageElem'] !== "undefined"){
            post.imageFile = req.files['imageElem'][0].filename;
        }

        post._user = newUser._id;
        post.title = req.body.title;
        post.artist = req.body.artist;
        post.start = req.body.start;
        post.stop = req.body.stop;
        post.genre = req.body.genre;
        post.tags = req.body.tags;

        post.save(function(err, newPost){
            if(err) 
                console.log(err);
            if(newPost){
                res.redirect('/');
            }
        });
    });
});

So everything works how I want it besides being able to save the blob image directly to a server directory for storing album images.

Any help on solving this would be greatly appreciated, thank you.

1

1 Answers

1
votes

append [...] to the form once its posted

You can't append to the form once it has been posted. But you can delay submission of the form until all your metadata is fetched.

I've tried formData to set and append the blob [...], but it just passes either undefined or the blob url

It looks like you were passing your url variable to the form and not the blob itself.

This snippet hopefully gives you a hint in the right direction

$('#file-input').on('change', function() {
  var formData = new FormData();
  var file = this.files[0];

  musicmetadata(file, function(err, result) {
    var picture = result.picture[0];
    var picBlob = new Blob([picture.data], {
      'type': 'image/' + picture.format
    });

    formData.append('fileElem', file);
    formData.append('imageElem', picBlob);
    
    console.log(formData); // Do whatever you want with the data
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/musicmetadata/2.0.2/musicmetadata.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input id="file-input" type="file" name="file">