buzz/mediainfo.js

mediainfo with HTTP Range Requests

seppevs opened this issue · 1 comments

Hi @buzz , thank you for this awesome library!

I'm trying to retrieve the mediainfo data from an URL by using Range Requests HTTP feature in Node.js.

Here is my code:

const MediaInfo = require('mediainfo.js');
const axios = require('axios');

// main
(async () => {

    const mediainfo = await MediaInfo({ chunkSize: 256*1024, coverData: false, format: 'object' });

    const url = "http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_60fps_stereo_abl.mp4";

    const response = await axios.get(url, {responseType: 'stream'});
    const contentLength = response.headers['content-length'];
    console.log(contentLength);

    const getSize = () => {
        const size = Number(contentLength);
        return size;
    }

    let readChunk = async (chunkSize, offset) => {
        const Range = `bytes=${offset}-${offset + chunkSize}`;
        console.log('reading ' + Range);
        try {
            const res = await axios.get(url, {
                headers: {
                    Range,
                }
            });
            console.log('-> received ' + res.headers['content-length'] + ' bytes');

            return res.data;
        } catch (err) {
            console.log(err);
            throw err;
        }
    };

    const result = await mediainfo.analyzeData(getSize, readChunk);
    console.log(JSON.stringify(result, null, 2));
})();

This is the output I get:

514832018
reading bytes=0-262144
-> received 262145 bytes
reading bytes=424967-687111
-> received 262145 bytes
{
  "media": {
    "@ref": "",
    "track": [
      {
        "@type": "General",
        "Format": "MPEG-4",
        "Format_Profile": "Base Media",
        "CodecID": "isom",
        "CodecID_Compatible": "isom/avc1",
        "FileSize": "514832018",
        "StreamSize": "514832018",
        "extra": {
          "IsTruncated": "Yes"
        }
      }
    ]
  }
}

This data is incomplete, so I guess I'm doing something incorrect. I've noticed that the logged ranges are not contiguous.

Can you spot what I'm missing?
Thanks a lot!

@seppevs Hi, you should change axios request Hearders.responseType = 'arraybuffer' and transport parameters to mediainfo.analyzeData TypedArray, like this.
Hope it helps you.

(async () => {
        const mediainfo = await MediaInfo({ chunkSize: 256 * 1024, coverData: true, format: "object" });

        const url = "http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_60fps_stereo_abl.mp4";

        const response = await axios.get(url, { responseType: "stream" });
        const contentLength = response.headers["content-length"];
        console.log(contentLength);

        const getSize = () => {
          const size = Number(contentLength);
          return size;
        };

        let readChunk = async (chunkSize, offset) => {
          const Range = `bytes=${offset}-${offset + chunkSize}`;
          console.log("reading " + Range);
          try {
            const res = await axios.get(url, {
              headers: {
                Range,
              },
              responseType: "arraybuffer",
            });
            console.log("-> received " + res.headers["content-length"] + " bytes");
            console.info("res", res)

            return new Uint8Array(res.data);
          } catch (err) {
            console.log(err);
            throw err;
          }
        };

        const result = await mediainfo.analyzeData(getSize, readChunk);
        console.log(JSON.stringify(result, null, 2));
      })();

图片