如何将mpeg电影文件中的文件以正确的格式写入磁盘?

时间:2019-04-04 17:54:18

标签: javascript node.js encoding stream

我正在尝试下载一个外部ts(mpeg)文件并将其写入磁盘,但是我不明白如何获取格式正确的文件内容。

我将文件保存在磁盘上,但是无法在媒体播放器中播放,当我查看文件属性时,它没有像ts文件那样显示任何视频/声音信息。我已经尝试了许多不同的编码,如果这是问题的根源,或者如果我需要以某种方式指出contentType,写入文件属性或此处缺少的内容,我什至都不会支持。

写入无法播放的文件的代码:

getFile = (url) => {
  https.get(url, r => {
    let rawData = [];

    r.on("data", chunk => {
      rawData += chunk;
    });

    r.on("end", () => {
      fs.writeFile(`./resources/test.ts`, rawData, "utf-8", err => {
        if (err) {
          console.log(`error writing file`);
          return;
        }

        console.log(`Wrote successfully`);
      });
    });
  });
};

对我来说这是一个新领域。我习惯于提供文件并设置各种内容类型,而不是下载它们。非常感谢帮助!

2 个答案:

答案 0 :(得分:1)

由于请求二进制数据,因此必须在响应中和调用writeFile时相应地设置编码。默认编码为utf-8,这可能是导致此问题的原因。您可以尝试以下方法:

getFile = (url) => {
    https.get(url, r => {
        let rawData = '';
        r.setEncoding('binary');

        r.on('data', chunk => {
            rawData += chunk;
        });

        r.on('end', () => {
            fs.writeFile(`./resources/test.ts`, rawData, 'binary', err => {
                if (err) {
                    console.log(`error writing file`);
                    return;
                }

                console.log(`Wrote successfully`);
            });
        });
    });
}

答案 1 :(得分:1)

UTF-8编码将填充设置了最高有效位的字节,这会破坏二进制文件。您可以将res.pipe()调用到Writable创建的fs.createWriteStream()流中,从而将其保存到磁盘而不缓冲所有数据:

getFile = url =>
  https.get(url, res => {
    res.pipe(fs.createWriteStream('./resources/test.ts', 'binary'))
      .on('error', console.error)
      .on('finish', () => { console.log('wrote successfully') })
  })

如果希望调用者能够告知下载何时完成以及是否有错误,则可以将返回值包装在Promise中,然后使用stream.finished()

const { finished } = require('stream')
const getFile = url => new Promise((resolve, reject) => {
  https.get(url, res => {
    const stream = res.pipe(
      fs.createWriteStream('./resources/test.ts', 'binary')
    )

    finished(stream, err => {
      if (err) reject(err)
      else resolve()
    })
  })
})

// usage
getFile('some url').then(() => {
  console.log('wrote successfully')
}, error => {
  console.error(error)
})