Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tools.makeMetadataSeekable returns broken webm file on server side (node.js) #55

Open
hiroMTB opened this issue Sep 27, 2024 · 0 comments

Comments

@hiroMTB
Copy link

hiroMTB commented Sep 27, 2024

tools.makeMetadataSeekable returns broken webm file on server side (node.js), it works on browser though. mkinfo returns (MKVInfo) No EBML head found. This file is probably not a Matroska file.

When I decode created webm file, it returns following error.

Uncaught Error: Unrepresentable length: Infinity

Also, /lib/cli.js is not working.

The error above comes from readVint function ebml.js package here

static readVint(buffer, start = 0) {
    const length = 8 - Math.floor(Math.log2(buffer[start]));
    if (length > 8) {
      const number = Tools.readHexString(buffer, start, start + length);
      throw new Error(`Unrepresentable length: ${length} ${number}`);
    }
...

When buffer[start] == 0 , then Math.log2() goes to Infinite.

I'm investigating what causes this issue, especially makeMetadataSeekable() works on browser side.
Any suggestion would be appreciated!

how to reproduce

here is my simple test code to reproduce this error. (or simply try cli.js and check resulted webm)

// index.js
const fs = require('fs');
const path = require('path');

const ebml = require("ts-ebml");
const { Decoder, Reader, tools } = ebml;

async function fixWebmDuration(filePath) {
    console.log("fixWebmDuration(), filePath=", filePath);

    let webMBuf;
    try {
        webMBuf = fs.readFileSync(filePath);
    } catch (err){
        console.error(err);
        return null;
    }

    const reader = checkWebm(webMBuf, "Original WebM file");

    // make webm seekable!
    const refinedMetadataArrayBuf = tools.makeMetadataSeekable(
        reader.metadatas,
        reader.duration,
        reader.cues
    );

    const refinedMetadataBuf = convertArrayBufferToBuffer(refinedMetadataArrayBuf);
    const body = webMBuf.subarray(reader.metadataSize);
    return Buffer.from(tools.concat([refinedMetadataBuf, body]).buffer);
}

function checkWebm(buffer, logName) {
    console.log('checkWebmDuration');

    const decoder = new Decoder();
    const reader = new Reader();
    reader.logging = true;
    reader.logGroup = logName;
    reader.drop_default_duration = false;

    const refinedElms = decoder.decode(buffer);
    refinedElms.forEach((elm) => {
        reader.read(elm);
    });
    reader.stop();

    return reader;
}

function convertArrayBufferToBuffer(arrayBuffer) {
    return Buffer.from(arrayBuffer);
}

async function fix(filepath){

    console.log('fix');
    const rawWebmPath = filepath;
    const refinedBuffer = await fixWebmDuration(rawWebmPath);

    checkWebm(refinedBuffer, "Refined WebM file");
    const refinedFilename = 'fixed.webm';
    const filePath = path.join(__dirname, refinedFilename);
    console.log('filePath', filePath);

    // Write the Buffer to a file
    try {
        fs.writeFileSync("fixed.webm", refinedBuffer);
        console.log('File written successfully');
    }catch (err){
        console.error(err);
    }
}

const filepath = path.join(__dirname, 'test_chrome52.webm');
fix(filepath);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant