话不多说先看第一个有毛病的代码 这是使用pipeline的并行合并,合成出来的视频有时候可以播放,有时候不行,求请教
Promise.all(
all_chunks.map(item => {
// 开始写的位置
const start = item * chunkSize
console.log(start)
// 使用管道连接读流和写流
return new Promise((resolve, reject) => {
pipeline(
fs.createReadStream(`${CHUNK_PATH}/${md5}/${item}`),
fs.createWriteStream(`${VIDEO_PATH}/${md5}`, {
flags: 'w+',
start: start,
autoClose: true
}),
err => {
if (!err) {
resolve('success')
}
console.log(err)
}
)
})
})
).then(() => {
fs.rename(`${VIDEO_PATH}/${md5}`, `${VIDEO_PATH}/${md5}.mp4`, () => {})
})
这是获取的文件
然后我以为是并行合并的问题,然后我就使用串行合并,也就是for循坏,但视频也不能播放
// 进行串行合并操作
for (let i = 0; i < all_chunks.length; i++) {
pipeline(
fs.createReadStream(`${CHUNK_PATH}/${md5}/${all_chunks[i]}`),
fs.createWriteStream(`${VIDEO_PATH}/${md5}`, {
flags: 'a',
autoClose: true
}),
err => {
if (err) {
console.log(err)
}
}
)
}
最后我使用了,pipe的递归合并,视频就可以播放,但官网推荐使用pipeline,说更安全,有大佬能发现bug吗
this.streamMergeRecursive(all_chunks, fs.createWriteStream(`${VIDEO_PATH}/${md5}.mp4`, { flags: 'w+' }), `${CHUNK_PATH}/${md5}`)
该函数的内容
// 递归合并切片
streamMergeRecursive(chunk_list = [], fileWriteStream, chunks_path) {
// 递归到尾部情况判断
if (!chunk_list.length) {
return fileWriteStream.end("console.log('Stream 合并完成')") // 最后关闭可写流,防止内存泄漏
}
const currentFile = `${chunks_path}/${chunk_list.shift()}` // 获取当前文件路径
const currentReadStream = fs.createReadStream(currentFile) // 获取当前的可读流
currentReadStream.pipe(fileWriteStream, { end: false })
currentReadStream.on('end', () => {
this.streamMergeRecursive(chunk_list, fileWriteStream, chunks_path)
})
currentReadStream.on('error', function (error) {
// 监听错误事件,关闭可写流,防止内存泄漏
console.error(error)
fileWriteStream.close()
})
}