下载以块形式存储在 GridFS 中的视频文件的特定部分时出错

问题描述 投票:0回答:1

我目前正在为我的大学项目开发视频流服务器,并且使用 MongoDB GridFS 以及官方 MongoDB Node.js 驱动程序。在我的项目中,我尝试下载存储在 GridFS 中的视频文件的特定部分作为块。不幸的是,我在这个过程中遇到了“FileNotFound”错误

app.get('/download-video', async (req, res) => {
    if (db === null) {
        console.error('Error connecting to MongoDB:',);
        res.status(500).send('Error connecting to MongoDB');
        return;
    }
    const chunkSizeBytes = 50 * 1024; // 50kb chunk size as an example

    // Create a GridFSBucket with the desired chunk size
    const bucket = new mongodb.GridFSBucket(db, { chunkSizeBytes });

    // Specify the file ID you want to retrieve
    const fileId = '514a65328a1e0fef0c936c1109bbc946.mp4';

    // Get the file information
    const fileInfo = await db.collection('fs.files').findOne({ filename: fileId });
    if (!fileInfo) {
        console.error('File not found');
        res.status(400).json({ message: "file not found" })
        return;
    }
    // Calculate the total number of chunks based on the file size and chunk size
    const totalChunks = Math.ceil(fileInfo.length / chunkSizeBytes);
    // Array to store downloaded chunks
    const chunksArray = [];
    try {
        // Download each chunk one by one
        for (let i = 0; i < totalChunks; i++) {
            const downloadStream = bucket.openDownloadStream(fileId, { start: i * chunkSizeBytes });
            let chunkData = Buffer.from([]);

            downloadStream.on('data', (chunk) => {
                // Append the chunk to the existing data buffer
                chunkData = Buffer.concat([chunkData, chunk]);

            });

            downloadStream.on('end', () => {
                // Process the downloaded chunk, e.g., save to a file, send to the client, etc.
                console.log(`Downloaded chunk ${i + 1} of ${totalChunks}`);

                // Add the chunk to the array
                chunksArray.push(chunkData);

                // If this is the last chunk, concatenate and process the complete video
                if (i === totalChunks - 1) {
                    // Concatenate all chunks into a single Buffer
                    const completeVideo = Buffer.concat(chunksArray);

                    // Specify the path where you want to save the complete video
                    const outputPath = 'path/to/output/video.mp4';

                    // Save the complete video to a file
                    fs.writeFileSync(outputPath, completeVideo);

                    console.log('Video saved:', outputPath);
                }
            });

            downloadStream.on('error', (error) => {
                console.error(`Error downloading chunk ${i + 1}:`, error);
                // res.send(400).json({message:"oops error"});
                return;

            });
        }

    } catch (error) {
        console.log(error.message);
        res.json({ message: error.message });
        //Error downloading chunk 102: Error: FileNotFound: file 514a65328a1e0fef0c936c1109bbc946.mp4 was not found
    }
});

这是代码图像 code image 1 code image2

我正在寻求帮助来理解和解决此问题。任何指导或见解将不胜感激。

database mongodb video-streaming gridfs chunks
1个回答
0
投票

我不使用 MongoDB,但根据一般编码经验,以下是我认为您显示的代码中存在错误的内容:

(1) 使用实际(十进制)字节长度来获取所需的字节数

尝试更换:

const chunkSizeBytes = 50 * 1024; // 50kb of chunk size as an example

有了这个新的计算版本:

const chunkSizeBytes = 50 * 1000; // 50 000 bytes of chunk size as an example

不用担心文件存储技术问题,例如

1 KiloByte == 1024 bytes
等。
您需要使用所需字节的十进制数
这将避免任何“超出”字节长度真实范围的情况。

(2) 仔细检查您的阅读位置。

您的代码 (示例,其中

i
101:

const downloadStream = bucket.openDownloadStream(fileId, { start: i * chunkSizeBytes });

使用计算器检查您的

101 * chunkSizeBytes
是否在文件的字节长度内。

还可以尝试在给定配置对象中设置

end
位置以及
start
位置。

例如:

{ start: (i * chunkSizeBytes), end: ((i * chunkSizeBytes) + chunkSizeBytes) }

注意: 您的最后一个块可以设置较小的大小,以便获得上次读取中未形成完整块的剩余最后几个字节。

如果没有

end
,您可能正在下载整个文件的字节(从开始位置到文件结尾),只是在从下一个块的位置读取时覆盖相同的数据(也读取到文件末尾),然后重复如此步骤,直到稍后出现错误为止。

(3) 文件保存后应返回

在您的

if (i === totalChunks - 1)
块中,您应该使用
return;
退出该函数。

console.log('Video saved:', outputPath);
return;

这将保证退出并停止任何进一步尝试读取下载文件的操作。

© www.soinside.com 2019 - 2024. All rights reserved.