播放存储在 MongoDB Atlas 上的音频文件

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

我在 Heroku 上有一个应用程序,用于处理使用 GridFS 存储在 MongoDB Atlas 数据库中的音频文件。

这个应用程序使用Next.JS和express。

为了回答这个问题,让我们考虑一下我在 MongoDB Atlas 上 fs.files 集合中的这条记录。

_id: 46e737001837a062ce85dd4c
length: 214023
chunkSize: 261120
uploadDate: 2023-08-12T05:09:22.521+00:00
filename: "Audio_2023-09-18:14:39:26"

下面的代码(Block:server.get('/download', (req, res) => {...})是文件server.js的一部分,将是我的问题的对象:

const express = require('express'),
            next = require('next'),
      .....
      mongoose = require('mongoose'),
      Grid = require('gridfs-stream'),
      mongoURI = process.env.MDB_URI_AUDIO;

mongoose.connect(mongoURI);

.....


const conn = mongoose.connection;

let gfs; // GridFS stream

conn.once('open', () => {
  // Initialize GridFS stream
  gfs = Grid(conn.db, mongoose.mongo);
});

.....


app.prepare().then(() => {
    const server = express();
  server.use(bodyParser.json({ limit: '1mb' }));

  .....

  server.get('/download', (req, res) => {
    const gridFSBucket = new mongoose.mongo.GridFSBucket(conn.db);
    const dataType = "audio/mp3";

    if (req.query.afn) {
      const filename = req.query.afn;
      const downloadStream = gridFSBucket.openDownloadStreamByName(filename);
       res.set('Content-Type', dataType); // Adjust the content type based on your audio format
      res.set('Content-Disposition', `inline; filename="${filename}"`);
      downloadStream.pipe(res)
    }

    if (req.query.id) {
      // const recordID = req.query.id.toString(); // This does not work !
      // const recordID = new ObjectID(req.query.id); // This does not work !
      // const recordID = mongoose.Types.ObjectID(req.query.id); // This does not work !
      const recordID = mongoose.Types.ObjectID.from(req.query.id); // This does not work !
      const downloadStream = gridFSBucket.openDownloadStream(recordID);
      res.set('Content-Type', dataType)
      res.set('Content-Disposition', `inline; filename=BLABLAH`);
      downloadStream.pipe(res);
    }
  });

  .....

  // Default route handler for Next.js pages
  server.all('*', (req, res) => {
    return handle(req, res);
  });


  const PORT = process.env.PORT || 3000; // Use Heroku-assigned port or default to 3000.

  server.listen(PORT, (err) => {
    if (err) throw err;
    console.log(`> Ready on http://localhost:${PORT}`);
  });
});

当我将浏览器指向此地址时:

https://myapp.herokuapp.com/download?afn=Audio_2023-09-18:14:39:26

我听到正在播放音频文件。这就是我所期望的。

当我将浏览器指向另一个地址时:

https://myapp.herokuapp.com/download?id=46e737001837a062ce85dd4c

我期望与第一个链接相同的事情,但它没有发生(我什么也没听到并收到错误)。 在第一个链接中,我使用文件名来获取音频, 对于第二个链接,我使用文件 ID 来获取它。

我的这部分代码很可能存在问题。但我错过了什么并且做错了什么?

if (req.query.id) {
  .....
}

我希望有人能阐明这个问题并帮助我解决问题。

mongodb express next.js media-player gridfs-stream
1个回答
0
投票

我对 Mongo 也有类似的问题。这与 Mongo 中 ID 的存储方式有关,您需要在使用 JS 查询之前进行此转换。

您不能简单地提供条目作为 GUID

"ec7427c4-567d-4e86-b4aa-e425fc2ec9b0"

您需要以十六进制格式提供

"Binary(Buffer.from("c42774ec7d56864eb4aae425fc2ec9b0", "hex"), 3)"

您可以使用此脚本进行转换

function convertGuidToHex(msGuid) {
    let cleanGuid = msGuid.replace(/-/g, "").toLowerCase();

    let hexString = cleanGuid.substring(6, 8) + cleanGuid.substring(4, 6) +
                    cleanGuid.substring(2, 4) + cleanGuid.substring(0, 2) +
                    cleanGuid.substring(10, 12) + cleanGuid.substring(8, 10) +
                    cleanGuid.substring(14, 16) + cleanGuid.substring(12, 14) +
                    cleanGuid.substring(16);
    
    return `Binary(Buffer.from("${hexString}", "hex"), 3);
}

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