nodejs关闭可读流的问题,无法关闭,导致视频播放有问题?

项目用的是electron-vue的脚手架开发,electron版本为2.04,本机的node版本为14.12.0。electron升级后electron为11.3.0,node版本不变。升级前视频可以正常播放,升级后第一次播放视频正常,第二次播放出现问题,下面为代码逻辑

const highWaterMark = 1024 * 1024
function decodefiletostream (req, res, fileInfo) {
   //  log.debug('decodefiletostream', fileInfo.filepath)
    let file = path.resolve(fileInfo.filepath)
    let rs = fs.createReadStream(file, {highWaterMark: highWaterMark, autoClose: true, eimtClose: true})
    let head = {
      'Content-Type': fileInfo.c
    }
    let skey = decrypt(fileInfo.s)
    // log.debug('decodefiletostream-->skey', skey)
    // 需要设置HTTP HEAD
    res.writeHead(206, head)
    let bufferStream = new Stream.PassThrough()
    let counter = 0
    let counterSize = 0
    rs.on('data', function (chunk) {
      counter++
      counterSize += chunk.length
      log.info('00000000000000?????', chunk.length, skey, 'hightwatermark???', highWaterMark)
        // log.debug('chunk', chunk.length, skey)
        // 如果加密标志是0,则是非加密文件
        // 功能更新: 视频头部加密1M内容, 所以highWaterMark的数值以后都不能改了 (2/19/2021)
        if (fileInfo.f === '0' || skey === '') {
          log.info('1111111?????', chunk.length)
            let flag = bufferStream.write(chunk)
            if (!flag) {
              rs.pause()
            }
        } else {
          // 否则是加密文件
          let tmp = new Array(chunk.length)
          log.info('22222222?????', chunk.length, 'tmp length', tmp.length)
            for (let i = 0; i < chunk.length; i++) {
                tmp[i] = chunk[i] - parseInt(skey.charAt((i + 1) % 32), 16)
            }
            skey = ''
            let flag = bufferStream.write(Buffer.from(tmp))
            if (!flag) {
              rs.pause()
            }
        }
    })
    bufferStream.on('drain', function () {
      log.info('buffer drain')
      rs.resume()
    })
    rs.on('close', function () {
      log.info('res close', counter, counterSize)
    })
    rs.on('end', function () {
      log.info('res end', counter, counterSize)
      bufferStream.end()
      rs.unpipe()
      rs.destroy()
    })
    bufferStream.pipe(res)
}

一次可读写流完成,上面的逻辑写入流的drain事件,可读流的end,close都正常监听到。可读流的data事件每次读取1M数据,每次播放对第1M数据做了解密处理,后续流为源数据。在data事件中,打印chunk长度发现了问题。
第一次播放流处理完成时的日志信息

第二次播发流处理开始时的日志信息

第二次播放处理流结束时的日志信息

已经尝试用unpipe和destroy关闭或销毁可读流,但是仍然出现这个问题。除非我重启应用实例,重启后第一播放没问题,第二次有问题。这个问题困扰了我好几天,但一直没有找到方法解决,请问这个问题如何解决?希望有处理过类似问题的大佬能指点迷津,如能解决,红包答谢!万分感谢,万分感谢,万分感谢。

参考GPT和自己的思路:

通过分析你提供的代码,发现在视频播放的过程中,每次读取1M的数据后,对第1M数据进行了解密处理,并将处理后的数据流传给了bufferStream,从bufferStream中pipe到了res。在第二次播放时,你发现chunk的长度只有262144,也就是只有1/4的数据被读取了,并且数据部分发生了变化,因此导致了问题。

这个问题可能是由于可读流没有及时关闭导致的。在代码中,可以看到使用了rs.unpipe()和rs.destroy()来关闭可读流,但是仍然没有解决问题。你可以尝试使用rs.close()方法关闭可读流,同时也可以将可读流的高水位线(highWaterMark)设为0来避免触发后续的data事件。同时,为了提高代码的健壮性和可读性,建议使用try-catch语句块来处理可读流的异常,例如:

try {
    rs.close();
} catch (err) {
    console.log('Error closing read stream:', err.message);
}

另外,在代码中使用了Stream.PassThrough()实例来创建可写流,建议使用WritableStream的子类Transform,它不仅可以读取数据,还可以对数据进行处理后输出,能够更好地满足你的需求。