nodejs服务代码
const express = require("express");
const fs = require("fs");
const app = express();
app.get("/", function (req, res) {
res.sendFile(__dirname + "/index.html");
});
if (!Date.now()) {
let i = 0
const readableStream = fs.createReadStream('asai.mp4') + fs.createReadStream('asai1.mp4');
readableStream.on('data', (chunk) => {
i++
console.log(666.123465, i, chunk);
});
readableStream.on('end', () => {
console.log('数据读取完毕');
});
}
if (!Date.now()) {
const writeStream = fs.createWriteStream('asai-a.mp4');
let readStream
function concatFiles(readfiles) {
if (readfiles && readfiles[0]) {
console.log(666.30002, readfiles[0])
readStream = fs.createReadStream(readfiles[0]);
readStream.pipe(writeStream, { end: false })
readStream.on('end', () => {
readfiles.shift()
concatFiles(readfiles);
});
} else {
writeStream.close();
}
readStream.on('error', (error) => {
console.error(666.789, error);
writeStream.close();
});
}
concatFiles(['asai.mp4', 'asai1.mp4'])
}
if (!Date.now()) {
const buffer = fs.readFileSync('asai.mp4')
const file1 = buffer.subarray(0, 3000000)
const file2 = buffer.subarray(3000000)
const allfile = Buffer.concat([file1, file2])
console.log(666.2008, allfile)
const s1 = fs.readFileSync('asai.mp4')
const s2 = fs.readFileSync('asai1.mp4')
const bb = Buffer.concat([s1, s2])
fs.writeFileSync('asai-c.mp4', bb)
}
const videoData = {
list: [
{ path: 'asai.mp4', size: fs.statSync('asai.mp4').size },
],
index: 0,
curStart: 0,
curSize: 0,
totalSize: 0
}
videoData.totalSize = videoData.list.reduce((prev, cur) => {
return prev + cur.size
}, 0)
app.get("/video", function (req, res) {
const range = req.headers.range;
if (range) {
resVideo(res, range)
} else {
const path = 'asai.mp4'
const fileSize = fs.statSync(path).size
let head = {
'Content-Length': fileSize,
'Content-Type': 'video/mp4',
};
res.writeHead(200, head);
fs.createReadStream(path).pipe(res);
res.status(400).send("Requires Range header");
}
});
app.listen(8000, function () {
console.log("Listening on port 8000!");
});
function resVideo(res, range) {
console.log(666.10001, range)
let [, start, end] = range.match(/(\d*)-(\d*)/);
if (videoData.list[videoData.index]) {
const videoPath = videoData.list[videoData.index].path;
const videoSize = videoData.list[videoData.index].size;
const CHUNK_SIZE = 10 ** 5;
end = Math.min(end ? end : start + CHUNK_SIZE, videoData.curStart + videoSize - 1);
console.log(666.10002, videoPath, { start, end, size: videoData.totalSize, startv: start - videoData.curStart, endv: end - videoData.curStart, sizev: videoSize }, (start >= videoData.curStart && start < end), videoData)
const videoStream = fs.createReadStream(videoPath, { start: start - videoData.curStart, end: end - videoData.curStart });
const newRange = `bytes ${start}-${end}/${videoData.totalSize}`
console.log(666.789, newRange)
const headers = {
"If-Range": "Etag",
"Content-Range": newRange,
"Accept-Ranges": "bytes",
"Content-Type": "multipart/byteranges",
"Transfer-Encoding": "chunked",
};
res.writeHead(206, headers);
videoStream.pipe(res);
videoData.curSize = end
if (end - videoData.curStart === videoSize - 1 && videoData.list[videoData.index + 1]) {
videoData.curStart += videoData.list[videoData.index].size
videoData.index += 1
console.log(666.123, videoPath, 'send over.', videoData)
}
}
}
前端html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>视频/文件切片请求处理nodejs+html</title>
<style>
body {
max-width: 100%;
height: 100vh;
background-color: rgb(14, 14, 14);
display: flex;
margin: auto;
align-items: center;
justify-content: center;
}
</style>
</head>
<body>
<video height="100%" src="/video" controls autoplay muted></video>
</body>
</html>
附件:前端js切片上次
<html lang="zh-cn">
<head>
<meta title="文件切片合并" />
</head>
<body>
<input type="file" id="file" />
<video id="play" controls style="width:500px;height:auto"></video>
</body>
<script>
file.addEventListener('change', async (e) => {
let file2 = file.files[0]
let chunckArr = []
let reader = file2.stream().getReader()
let done = false
while (!done) {
let { value, done: readDone } = await reader.read()
console.log(value)
chunckArr.push(value)
done = readDone
}
let newFile = new Blob(chunckArr)
play.setAttribute('src', URL.createObjectURL(newFile))
})
</script>
</html>