如何在Node JS中从mongodb插入和检索视频

时间:2018-12-27 11:38:23

标签: node.js mongodb mean-stack

我是新来的意思。我想将视频上传到mongodb,然后再将其检索。

  

这是app.js文件

  `const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const crypto = require('crypto');
const mongoose = require('mongoose');
const multer = require('multer');
const GridFsStorage = require('multer-gridfs-storage');
const Grid = require('gridfs-stream');
const methodOverride = require('method-override');

const app = express();

// Middleware
app.use(bodyParser.json());
app.use(methodOverride('_method'));
app.set('view engine', 'ejs');

// Mongo URI
const mongoURI = 'mongodb://fawad:Fawad123@ds155243.mlab.com:55243/imageupload';

// Create mongo connection
const conn = mongoose.createConnection(mongoURI);

// Init gfs
let gfs;

conn.once('open', () => {
  // Init stream
  gfs = Grid(conn.db, mongoose.mongo);
  gfs.collection('uploads');
});

// Create storage engine
const storage = new GridFsStorage({
  url: mongoURI,
  file: (req, file) => {
    return new Promise((resolve, reject) => {
      crypto.randomBytes(16, (err, buf) => {
        if (err) {
          return reject(err);
        }
        const filename = buf.toString('hex') + path.extname(file.originalname);
        const fileInfo = {
          filename: filename,
          bucketName: 'uploads'
        };
        resolve(fileInfo);
      });
    });
  }
});
const upload = multer({ storage });

// @route GET /
// @desc Loads form
app.get('/', (req, res) => {
  gfs.files.find().toArray((err, files) => {
    // Check if files
    if (!files || files.length === 0) {
      res.render('index', { files: false });
    } else {
      files.map(file => {
        if (
          file.contentType === 'video/mp4' ||
          file.contentType === 'video/webm '
        ) {
          file.isVideo = true;
        } else {
          file.isVideo = false;
        }
      });
      res.render('index', { files: files });
    }
  });
});

// @route POST /upload
// @desc  Uploads file to DB
app.post('/upload', upload.single('file'), (req, res) => {
  // res.json({ file: req.file });
  res.redirect('/');
});

// @route GET /files
// @desc  Display all files in JSON
app.get('/files', (req, res) => {
  gfs.files.find().toArray((err, files) => {
    // Check if files
    if (!files || files.length === 0) {
      return res.status(404).json({
        err: 'No files exist'
      });
    }

    // Files exist
    return res.json(files);
  });
});

// @route GET /files/:filename
// @desc  Display single file object
app.get('/files/:filename', (req, res) => {
  gfs.files.findOne({ filename: req.params.filename }, (err, file) => {
    // Check if file
    if (!file || file.length === 0) {
      return res.status(404).json({
        err: 'No file exists'
      });
    }
    // File exists
    return res.json(file);
  });
});

// @route GET /image/:filename
// @desc Display Image
app.get('/video/:filename', (req, res) => {
  gfs.files.findOne({ filename: req.params.filename }, (err, file) => {
    // Check if file
    if (!file || file.length === 0) {
      return res.status(404).json({
        err: 'No file exists'
      });
    }

    // Check if image
    if (file.contentType === 'video/mp4' || file.contentType === 'video/webm') {
      // Read output to browser
      const readstream = gfs.createReadStream(file.filename);
      readstream.pipe(res);
    } else {
      res.status(404).json({
        err: 'Not an image'
      });
    }
  });
});

// @route DELETE /files/:id
// @desc  Delete file
app.delete('/files/:id', (req, res) => {
  gfs.remove({ _id: req.params.id, root: 'uploads' }, (err, gridStore) => {
    if (err) {
      return res.status(404).json({ err: err });
    }

    res.redirect('/');
  });
});

const port = 9000;

app.listen(port, () => console.log(`Server started on port ${port}`));
`
  

index.ejs

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
    crossorigin="anonymous">
  <style>
    video {
      width: 100%;
    }
  </style>
  <title>Mongo File Uploads</title>
</head>

<body>
  <div class="container">
    <div class="row">
      <div class="col-md-6 m-auto">
        <h1 class="text-center display-4 my-4">Mongo File Uploads</h1>
        <form action="/upload" method="POST" enctype="multipart/form-data">
          <div class="custom-file mb-3">
            <input type="file" name="file" id="file" class="custom-file-input">
            <label for="file" class="custom-file-label">Choose File</label>
          </div>
          <input type="submit" value="Submit" class="btn btn-primary btn-block">
        </form>
        <hr>
        <% if(files){ %>
          <% files.forEach(function(file) { %>
            <div class="card card-body mb-3">
              <% if(file.isVideo) { %>
                <video src="video/<%= file.filename %>" alt="">
                <% } else { %>
                  <%= file.filename %>
                    <% } %>
                      <form method="POST" action="/files/<%= file._id %>?_method=DELETE">
                        <button class="btn btn-danger btn-block mt-4">Delete</button>
                      </form>
            </div>
            <% }) %>
              <% } else { %>
                <p>No files to show</p>
                <% } %>
      </div>
    </div>
  </div>

  <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
    crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
    crossorigin="anonymous"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
    crossorigin="anonymous"></script>
</body>

</html>

此代码适用于image ..当我使用(file.contentType = image / png)时。 但是对于视频来说,它不起作用..图像和视频上传是否相同?

3 个答案:

答案 0 :(得分:0)

您可以使用Formidable。由于它支持多部分数据。对于检索视频,您可以使用fs(文件系统)

答案 1 :(得分:0)

实际上,您没有将媒体(图像或视频)保存在数据库中,而是将其存储在诸如s3存储桶之类的某些存储驱动器(本地或云)中,然后将其位置网址存储在数据库中。 这段代码可能会有所帮助。

saveImage(urlPath, folderPath, multiple) {
    return new Promise((resolve, reject) => {
        var timestamp = Date.now();
        var filepath = urlPath;
        var imageUrl;
        var ext = path.extname(filepath || '').split('.');
        var extension = ext[ext.length - 1];

        var tmp_path = filepath;
        imageUrl = folderPath + timestamp + '.' + extension;
        if (multiple != '' && multiple != undefined) { imageUrl = folderPath + timestamp + multiple + '.' + extension; }
        var target_path = __dirname + '/../' + imageUrl;//Change according to your location.
        console.log("target_path", target_path);
        mv(tmp_path, target_path, { mkdirp: true }, function (err) { })
        return resolve({ status: 1, url: imageUrl });
    })
}

现在,urlPath是您的媒体路径,foldarPath是您要存储媒体的路径,而multipath是要提供唯一名称。

您可以像这样调用此方法。

var multiple = Number(0) + Number(10);
                console.log("multiple", multiple);
                var saveImage = await 'YOUR_FILE_NAME'.saveImage(files.photo[0].path, 'public/Image/', multiple);

console.log(saveImage);

答案 2 :(得分:0)

<video src="video/<%= file.filename %>" controls alt="">

///尝试将控件命令添加到视频标签中。它有助于视频播放。