music-metadata: parseStream on s3 stream not working - no errors, but execution halts

Bug description For some reason, mm.parseStream fails to work. My code doesn’t throw any exceptions, but the execution halts at that point.

Expected behavior I expected parseStream to work properly.

const S3 = require('aws-sdk/clients/s3');
const s3 = new S3();
const mm = require('music-metadata');

(async function() {
  const stream = s3
    .getObject({
      Bucket: 'my-bucket',
      Key: 'test.wav',
    })
    .createReadStream();

  const data = await mm.parseStream(stream);
  console.log('we never get here :(', data);
})();

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 30 (18 by maintainers)

Most upvoted comments

but I’m not sure how I would know what range to grab

But music-metadata knows. Via the ITokenizer the SomeS3orHttpRangedReader would be able to calculate this. I am considering to implement something like that, because I have already done it for the browser.

But again, it’s not a huge deal. Using Node.js’s streams should be sufficient!

Understood. Don’t worry, this is an area which has my interest. In addition to that, I see a growing number of users reading directly from cloud storage.

Should be solved, sorry I cannot easily prevent reading the entire WAV via a stream is not something I can prevent here; see #283.

You can use the skipCovers option to prevent those from being returned and loaded in the first place.

const metadata = await mm.parseBuffer(body, {skipCovers: true});

@Borewit Hey, sorry about that! Let me put together a reproduction for you, one that you can just easily deploy to AWS (and remove cleanly). Please leave this issue open and I’ll try to get to it this week.

BTW, my workaround is this:

  try {
    const s3obj = new S3Object({ bucket: event.bucket, key: event.key });
    const body = await s3obj.getBody();
    // @ts-ignore
    const metadata = await mm.parseBuffer(body);

    // Just remove cover images for now
    delete metadata.common.picture;

    return {
      success: true,
      metadata,
    };
  } catch (e) {
    console.log(
      JSON.stringify({
        error: true,
        reqId: event.reqId,
        reason: e.message,
      }),
    );
    return { success: false };
  }

Is there any disadvantage to reading the whole file like this, besides consuming memory? Will mm.parseStream just read enough to get the metadata and not read the whole file?

Hey, I’m on a trip but will give it a try when I get back. But no errors are being thrown so I don’t think this will make a difference.