对于我的项目,我正在尝试创建一个音频播放器。存储文件的数据库方面对我来说是新的,因为我之前只存储过字符串。
到目前为止,我能够做的是:
服务器端代码(路由代码与服务器代码分开)
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);
});
});
});
在旧时数据库中,术语媒体对象称为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 use(audio/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中文件的路径名。
如何解决这类问题?
我认为您正在寻找的是一个流,因此您可以直接将数据从服务器流式传输到网页而不保存。节点js更多地来自这里的文档https://nodejs.org/api/stream.html