将音频从mongodb传递到音频标签 [英] passing audio from mongodb to audio tag

查看:87
本文介绍了将音频从mongodb传递到音频标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

For my project I'm trying to create an audio player. The database aspect of storing files is new to me as I've only stored strings before.

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

So far, what I've been able to do is:

  1. 将音频文件存储到数据库中.(为简单起见,我在这里链接到文件,但将来会上传)

  1. Store the audio file into the database.(I'm linking to a file here for simplicity but in the future it will be uploaded)

将音频文件检索为对象.

Retrieve the audio file as an object.

将音频文件存储在公用文件夹中以供使用.

Store the audio file in the public folder for use.

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

Server side code(the route code is separate from the server code)

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访问权限,而不必将其保存在公用文件夹中,然后在使用后将其删除.

The third step is what I don't what to do. I'd like to send the result object to the audio.ejs page and somehow give the audio tag access to it without having to save it in the public folder an then have to delete it after use.

类似这样的东西

第3步

  res.render('audio', result);

,并通过某种方式在audio.ejs页面中授予audio tag访问权限

and somehow give an audio tag access to it in the audio.ejs page

更新

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);
            });
        });
    });

推荐答案

在老式数据库中,行话媒体对象称为BLOBS(二进制大对象).在Mongo中,它们使用称为gridfs子系统进行处理.有一个很好的 npm模块称为gridfs-stream ,可以使此操作变得更加容易.

In old-timey database lingo media objects are called BLOBS -- binary large objects. In Mongo they're handled with a subsystem known as gridfs. There's a nice npm module called gridfs-stream to make this easier.

将媒体对象传递给浏览器的一种简单方法是使它们在看起来像https://example.com/audio/objectname.mp3的URL后面可用.并且,应使用适当的Content-Type标头来提供它们对于正在使用的编解码器(对于MP3,为audio/mpeg).然后,src标记可以简单地命名URL,您就摇摇欲坠".浏览器页面中的音频标签如下所示:

An easy way to deliver media objects to browsers is to make them available behind URLs that look like https://example.com/audio/objectname.mp3. And, they should be delivered with the appropriate Content-Type header for the codec in use (audio/mpeg for MP3). Then the src tag can simply name the URL and you're rockin' and rollin'. The audio tag in the browser page looks something like this:

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

因此,如果您想直接通过express传递音频,则需要一条带有参数的路由,例如

So, if you want to deliver audio directly via express, you need a route with a parameter, something like

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

然后,节点程序使用类似这样的内容未调试!)

Then the node program uses something like this not debugged!)

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中.音频文件可能很大.

This is cool because streams are cool: your node program doesn't need to slurp the whole audio file into RAM. Audio files can be large.

gridfs提供了 mongofiles命令行工具 y,用于将文件加载到gridfs.

gridfs offers the mongofiles command line utility for loading files into gridfs.

但是,话虽这么说:大多数可伸缩媒体服务都使用从文件系统和/或内容交付网络交付的静态媒体文件.诸如apache和nginx之类的服务器已经投入了许多程序员的精力来使文件传递变得快速高效.数据库保存CDN中文件的路径名.

But, all that being said: Most scalable media services use static media files delivered from file systems and/or content delivery networks. Servers like apache and nginx have many programmer years invested in making file delivery fast and efficient. The database holds the pathnames for the files in the CDN.

如何解决此类问题?

  • 观看浏览器的控制台日志.
  • 直接从浏览器中命中媒体URL.看看你得到什么.如果为空,则您的检索代码有问题.
  • 在浏览器的开发工具中,查看网络"标签(在Google Chrome中).寻找媒体对象,然后检查发生了什么.

这篇关于将音频从mongodb传递到音频标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆