Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将音频从mongodb传递到音频标签_Javascript_Node.js_Html5 Audio_Gridfs_Mangodb - Fatal编程技术网

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

Javascript 将音频从mongodb传递到音频标签,javascript,node.js,html5-audio,gridfs,mangodb,Javascript,Node.js,Html5 Audio,Gridfs,Mangodb,对于我的项目,我正在尝试创建一个音频播放器。存储文件的数据库方面对我来说是新的,因为我以前只存储字符串 到目前为止,我所能做的是: 将音频文件存储到数据库中。(为了简单起见,我在这里链接到一个文件,但将来它将被上传) 将音频文件作为对象检索 将音频文件存储在公用文件夹中以供使用 服务器端代码(路由代码与服务器代码分开) 让fs=require('fs'); var bodyParser=require('body-parser') var urlencodedParser=bodyParser

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

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

  • 将音频文件存储到数据库中。(为了简单起见,我在这里链接到一个文件,但将来它将被上传)

  • 将音频文件作为对象检索

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

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

    让fs=require('fs');
    var bodyParser=require('body-parser')
    var urlencodedParser=bodyParser.urlencoded({
    扩展:false
    })
    const MongoClient=require('mongodb')。MongoClient;
    const Binary=require('mongodb').Binary;
    const ObjectId=require('mongodb').ObjectId;
    module.exports=函数(应用程序){
    app.get('/music',函数(req,res){
    //第一步
    var data=fs.readFileSync(_dirname+'/../public/recordings/Piso 21-Puntos suspentivos.mp3');
    var insert_data={};
    插入_data.name='Piso 21-Puntos suspentivos.mp3';
    插入_data.file_data=二进制(数据);
    MongoClient.connect(“mongodb://localhost/songs", {
    useNewUrlParser:true
    },函数(err,db){
    如果(错误)抛出错误;
    var dbo=db.db(“歌曲”);
    dbo.collection(“song”).insertOne(插入数据、函数(err、res){
    如果(错误)抛出错误;
    控制台日志(“插入1个文档”);
    db.close();
    });
    });
    //第二步
    MongoClient.connect(“mongodb://localhost/songs", {
    useNewUrlParser:true
    },函数(err,db){
    如果(错误)抛出错误;
    var dbo=db.db(“歌曲”);
    dbo.收藏(“歌曲”).findOne({
    名称:“Piso 21-Puntos suspentivos.mp3”
    },函数(错误,结果){
    如果(错误)抛出错误;
    db.close();
    //第三步
    fs.writeFile(result.name、result.file\u data.buffer、函数(err){
    如果(错误)抛出错误;
    控制台日志(结果);
    });
    });
    });
    res.render(“音频”);
    });
    
    第三步是我不知道该做什么。我想将
    结果
    对象发送到
    audio.ejs
    页面,并以某种方式让
    audio标签
    访问它,而不必将其保存在公用文件夹中,然后在使用后将其删除

    像这样的,

    第三步

      res.render('audio', result);
    
    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);
                });
            });
        });
    
    并在
    audio.ejs
    页面中提供一个
    audio标签
    访问权限

    更新

      res.render('audio', result);
    
    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);
                });
            });
        });
    

    我认为您正在寻找的是一个流,因此您可以将数据从服务器直接流到网页,而无需保存。Node js附带了此功能。更多信息来自此处的文档在旧式数据库行话中,媒体对象被称为blob——二进制大对象。在Mongo中,它们使用让这更容易

    向浏览器交付媒体对象的一种简单方法是,在类似
    URL的URL后面提供媒体对象https://example.com/audio/objectname.mp3
    。而且,它们应该附带一个(
    音频/mpeg
    用于MP3)。然后src标记可以简单地命名URL,您就可以“摇”和“滚”。浏览器页面中的音频标记如下所示:

    <audio controls src="/audio/objectname.mp3" ></audio>
    
    然后节点程序使用如下内容未调试!

    这很酷,因为流很酷:您的节点程序不需要将整个音频文件混入RAM。音频文件可能很大

    gridfs提供了将文件加载到gridfs的方法

    但是,总而言之:大多数可扩展的媒体服务使用从文件系统和/或内容交付网络交付的静态媒体文件。apache和nginx等服务器在使文件交付快速高效方面投入了多年的程序员时间。数据库持有CDN中文件的路径名

    如何解决这类问题

    • 查看浏览器的控制台日志
    • 直接从浏览器点击媒体URL。查看您得到的内容。如果为空,则表示您的检索代码有问题
    • 在浏览器的“开发工具”中,查看“网络”选项卡(在Google Chrome中)。查找媒体对象,并检查发生了什么

    回答得很好。我现在正试图避免使用gridfs,但这看起来很容易理解。谢谢。不过我有一些问题。我猜我必须在客户端发出ajax请求。如果是这样,我应该为文件位置
    xhttp.open(“GET”,“file location”,true)添加什么内容;
    这就是我指定内容类型的方式吗?
    xhttp.setRequestHeader(“内容类型”、“音频/mpeg”);
    audio标签中的
    src
    属性将导致浏览器检索您的音频文件,而不需要任何复杂的ajax。如果我是您,我会先让它工作。因此我一直在尝试让它工作,但我不能。我已经对它进行了一些更新,以匹配我现有的代码。请看一看。我更新了我的问题。我认为此行中有错误`const db=new MongoClient.db('songs',new MongoClient.Server('localhost',27017));`。我的数据库名是
    songs
    。集合名是
    song
    。我不明白仅仅输入数据库名是如何搜索集合的。请阅读有关GridFS的内容。请注意,它有自己的索引方案。使用GridFS提取的对象必须以相同的方式放入其中。这就是我为什么要这样做的原因分区
    mongofiles
    。您可以将我为您提供的进入Mongo的示例代码替换为有效的代码。您的mongofiles链接不支持word。您可以更新它吗?