将音频从mongodb传递到音频标签

问题描述 投票:3回答:2

对于我的项目,我正在尝试创建一个音频播放器。存储文件的数据库方面对我来说是新的,因为我之前只存储过字符串。

到目前为止,我能够做的是:

  1. 将音频文件存储到数据库中。(为了简单起见,我在这里链接到一个文件,但将来会上传)
  2. 将音频文件作为对象检索。
  3. 将音频文件存储在公用文件夹中以供使用。

服务器端代码(路由代码与服务器代码分开)

let fs = require('fs');
var bodyParser = require('body-parser')
var urlencodedParser = bodyParser.urlencoded({
  extended: false
})

const MongoClient = require('mongodb').MongoClient;
const Binary = require('mongodb').Binary;
const ObjectId = require('mongodb').ObjectId;

module.exports = function(app) {

    app.get('/music', function(req, res) {

      //STEP ONE

      var data = fs.readFileSync(__dirname + '/../public/recordings/Piso 21 - Puntos Suspensivos.mp3');
      var insert_data = {};
      insert_data.name = 'Piso 21 - Puntos Suspensivos.mp3';
      insert_data.file_data = Binary(data);

      MongoClient.connect("mongodb://localhost/songs", {
        useNewUrlParser: true
      }, function(err, db) {
        if (err) throw err;
        var dbo = db.db("songs");
        dbo.collection("song").insertOne(insert_data, function(err, res) {
          if (err) throw err;
          console.log("1 document inserted");
          db.close();
        });
      });

      //STEP TWO

      MongoClient.connect("mongodb://localhost/songs", {
        useNewUrlParser: true
      }, function(err, db) {
        if (err) throw err;
        var dbo = db.db("songs");
        dbo.collection("song").findOne({
          name: 'Piso 21 - Puntos Suspensivos.mp3'
        }, function(err, result) {
          if (err) throw err;
          db.close();

          //STEP THREE

          fs.writeFile(result.name, result.file_data.buffer, function(err) {
            if (err) throw err;
            console.log(result);
          });
        });
      });
      res.render('audio');
    });

第三步是我不做什么。我想将result对象发送到audio.ejs页面,并以某种方式让audio tag访问它,而不必将其保存在公共文件夹中,然后必须在使用后删除它。

像这样的东西,

第三步

  res.render('audio', result);

并以某种方式在audio tag页面中给audio.ejs访问它

UPDATE

let fs = require('fs');
var bodyParser = require('body-parser')
var urlencodedParser = bodyParser.urlencoded({ extended: false })

const MongoClient = require('mongodb');
const Binary = require('mongodb').Binary;
const ObjectId = require('mongodb').ObjectId;
const Grid = require('gridfs-stream');

const db = new MongoClient.Db('songs', new MongoClient.Server("localhost", 27017));
const gfs = Grid(db, MongoClient);

const bcrypt = require('bcryptjs');

module.exports = function(app){


    app.get('/audio/:filename', function (req, res) {

        MongoClient.connect("mongodb://localhost/songs", { useNewUrlParser: true }, function(err, db) {
            if (err) throw err;
            var dbo = db.db("songs");
            dbo.collection("song").findOne({name: req.params.filename}, function(err, result){
                if (err) throw err;
                db.close();
                const readstream = gfs.createReadStream(result.file_data);
                readstream.on('error', function (error) {
                    res.sendStatus(500);
                });
                console.log(res);
                res.type('audio/mpeg');
                readstream.pipe(res);
            });
        });
    });
javascript node.js html5-audio gridfs mangodb
2个回答
1
投票

在旧时数据库中,术语媒体对象称为BLOBS - 二进制大对象。在Mongo,他们用subsystem known as gridfs处理。有一个很好的npm module called gridfs-stream,使这更容易。

将媒体对象传递给浏览器的一种简单方法是将它们放在看起来像https://example.com/audio/objectname.mp3的URL后面。并且,他们应该与appropriate Content-Type header for the codec in useaudio/mpeg MP3)一起交付。然后src标签可以简单地命名URL,你就是摇滚和罗林。浏览器页面中的音频标签如下所示:

<audio controls src="/audio/objectname.mp3" ></audio>

因此,如果您想通过express直接传送音频,则需要一个带参数的路径,例如

 app.get('/audio/:filename', ...

然后节点程序使用这样的东西没有调试!)

const mongo = require('mongodb');
const Grid = require('gridfs-stream');
...
const db = new mongo.Db('yourDatabaseName', new mongo.Server("host", 27017));
const gfs = Grid(db, mongo);
...
app.get('/audio/:filename', function (req, res) {
   const readstream = gfs.createReadStream({filename: req.params.filename})
   readstream.on('error', function (error) {
        res.sendStatus(500)
   })
   res.type('audio/mpeg')
   readstream.pipe(res)
});

这很酷,因为流很酷:节点程序不需要将整个音频文件粘贴到RAM中。音频文件可能很大。

gridfs提供了mongofiles command line utility,用于将文件加载到gridfs中。

但是,所有这一切:大多数可伸缩媒体服务使用从文件系统和/或内容传送网络传送的静态媒体文件。像apache和nginx这样的服务器在编写文件时快速高效地投入了许多程序员。数据库保存CDN中文件的路径名。

如何解决这类问题?

  • 观看浏览器的控制台日志。
  • 直接从浏览器点击媒体URL。看看你得到了什么。如果它是空的,那么你的检索代码有问题。
  • 在浏览器中的开发工具中,查看“网络”标签(在Google Chrome中)。寻找媒体对象,并检查发生了什么。

0
投票

我认为您正在寻找的是一个流,因此您可以直接将数据从服务器流式传输到网页而不保存。节点js更多地来自这里的文档https://nodejs.org/api/stream.html

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