passing audio from mongodb to audio tag

好久不见. 提交于 2020-08-23 06:59:11

问题


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. Store the audio file into the database.(I'm linking to a file here for simplicity but in the future it will be uploaded)

  2. Retrieve the audio file as an object.

  3. 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');
    });

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.

Something like this,

STEP THREE

  res.render('audio', result);

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

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

回答1:


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.

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>

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

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 offers the mongofiles command line utility for loading files into gridfs.

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.

How to troubleshoot this kind of thing?

  • Watch the browser's console log.
  • Hit the media URL directly from a browser. See what you get. If it's empty, something's wrong with your retrieval code.
  • In dev tools in the browser, look at the Network tab (in Google Chrome). Look for the media object, and examine what's going on.



回答2:


I think what you're looking for is a stream, so you can stream data from the server to the webpage directly without saving it. Node js comes with this functionality more of it from the documentation here https://nodejs.org/api/stream.html



来源:https://stackoverflow.com/questions/55230048/passing-audio-from-mongodb-to-audio-tag

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!