diff --git a/README.md b/README.md index 37bee455d..e2b52f6fd 100644 --- a/README.md +++ b/README.md @@ -64,13 +64,15 @@ Thanks to [WebTorrent](https://github.com/feross/webtorrent), we can make P2P (t * **NodeJS >= 4.2** * OpenSSL (cli) * MongoDB - * xvfb-run libgtk2.0-0 libgconf-2-4 libnss3 libasound2 libxtst6 libxss1 libnotify-bin (for electron) + * ffmpeg xvfb-run libgtk2.0-0 libgconf-2-4 libnss3 libasound2 libxtst6 libxss1 libnotify-bin (for electron) #### Debian -Install NodeJS 4.2: [https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions](https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions) + * Install NodeJS 4.2: [https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions](https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions) + * Add jessie backports to your *source.list*: http://backports.debian.org/Instructions/ - # apt-get install mongodb openssl xvfb curl sudo git build-essential libgtk2.0-0 libgconf-2-4 libnss3 libasound2 libxtst6 libxss1 libnotify-bin + # apt-get update + # apt-get install ffmpeg mongodb openssl xvfb curl sudo git build-essential libgtk2.0-0 libgconf-2-4 libnss3 libasound2 libxtst6 libxss1 libnotify-bin # npm install -g electron-prebuilt #### Other distribution... (PR welcome) diff --git a/package.json b/package.json index 85b383a69..746a0d968 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "express": "^4.12.4", "express-oauth-server": "https://github.com/Chocobozzz/express-oauth-server", "express-validator": "^2.11.0", + "fluent-ffmpeg": "^2.1.0", "js-yaml": "^3.5.4", "lodash": "^4.11.1", "mkdirp": "^0.5.1", diff --git a/server/controllers/api/v1/videos.js b/server/controllers/api/v1/videos.js index d25ca95f7..e69628961 100644 --- a/server/controllers/api/v1/videos.js +++ b/server/controllers/api/v1/videos.js @@ -3,6 +3,7 @@ const config = require('config') const crypto = require('crypto') const express = require('express') +const ffmpeg = require('fluent-ffmpeg') const multer = require('multer') const logger = require('../../../helpers/logger') @@ -60,26 +61,37 @@ function addVideo (req, res, next) { return next(err) } - const video_data = { - name: video_infos.name, - namePath: video_file.filename, - description: video_infos.description, - magnetUri: torrent.magnetURI, - author: res.locals.oauth.token.user.username - } - - Videos.add(video_data, function (err) { + ffmpeg.ffprobe(video_file.path, function (err, metadata) { if (err) { - // TODO unseed the video - logger.error('Cannot insert this video in the database.') + // TODO: unseed the video + logger.error('Cannot retrieve metadata of the file') return next(err) } - // Now we'll add the video's meta data to our friends - friends.addVideoToFriends(video_data) + const duration = Math.floor(metadata.format.duration) - // TODO : include Location of the new video -> 201 - res.type('json').status(204).end() + const video_data = { + name: video_infos.name, + namePath: video_file.filename, + description: video_infos.description, + magnetUri: torrent.magnetURI, + author: res.locals.oauth.token.user.username, + duration: duration + } + + Videos.add(video_data, function (err) { + if (err) { + // TODO unseed the video + logger.error('Cannot insert this video in the database.') + return next(err) + } + + // Now we'll add the video's meta data to our friends + friends.addVideoToFriends(video_data) + + // TODO : include Location of the new video -> 201 + res.type('json').status(204).end() + }) }) }) } @@ -144,7 +156,8 @@ function getFormatedVideo (video_obj) { podUrl: video_obj.podUrl, isLocal: videos.getVideoState(video_obj).owned, magnetUri: video_obj.magnetUri, - author: video_obj.author + author: video_obj.author, + duration: video_obj.duration } return formated_video diff --git a/server/helpers/customValidators.js b/server/helpers/customValidators.js index a5ae32780..0fbabab52 100644 --- a/server/helpers/customValidators.js +++ b/server/helpers/customValidators.js @@ -13,7 +13,8 @@ function eachIsRemoteVideosAddValid (values) { return validator.isLength(val.name, 1, 50) && validator.isLength(val.description, 1, 50) && validator.isLength(val.magnetUri, 10) && - validator.isURL(val.podUrl) + validator.isURL(val.podUrl) && + !isNaN(val.duration) }) } diff --git a/server/models/videos.js b/server/models/videos.js index 13ef2295a..e02158be7 100644 --- a/server/models/videos.js +++ b/server/models/videos.js @@ -22,7 +22,8 @@ const videosSchema = mongoose.Schema({ description: String, magnetUri: String, podUrl: String, - author: String + author: String, + duration: Number }) const VideosDB = mongoose.model('videos', videosSchema) @@ -72,7 +73,8 @@ function addRemotes (videos, callback) { namePath: null, description: video.description, magnetUri: video.magnetUri, - podUrl: video.podUrl + podUrl: video.podUrl, + duration: video.duration } to_add.push(params) diff --git a/server/tests/api/multiplePods.js b/server/tests/api/multiplePods.js index ba4ce70c9..adc99f714 100644 --- a/server/tests/api/multiplePods.js +++ b/server/tests/api/multiplePods.js @@ -95,6 +95,7 @@ describe('Test multiple pods', function () { expect(video.description).to.equal('my super description for pod 1') expect(video.podUrl).to.equal('http://localhost:9001') expect(video.magnetUri).to.exist + expect(video.duration).to.equal(10) if (server.url !== 'http://localhost:9001') { expect(video.isLocal).to.be.false @@ -144,6 +145,7 @@ describe('Test multiple pods', function () { expect(video.description).to.equal('my super description for pod 2') expect(video.podUrl).to.equal('http://localhost:9002') expect(video.magnetUri).to.exist + expect(video.duration).to.equal(5) if (server.url !== 'http://localhost:9002') { expect(video.isLocal).to.be.false @@ -190,17 +192,20 @@ describe('Test multiple pods', function () { const videos = res.body expect(videos).to.be.an('array') expect(videos.length).to.equal(4) + const video1 = videos[2] expect(video1.name).to.equal('my super name for pod 3') expect(video1.description).to.equal('my super description for pod 3') expect(video1.podUrl).to.equal('http://localhost:9003') expect(video1.magnetUri).to.exist + expect(video1.duration).to.equal(5) const video2 = videos[3] expect(video2.name).to.equal('my super name for pod 3-2') expect(video2.description).to.equal('my super description for pod 3-2') expect(video2.podUrl).to.equal('http://localhost:9003') expect(video2.magnetUri).to.exist + expect(video2.duration).to.equal(5) if (server.url !== 'http://localhost:9003') { expect(video1.isLocal).to.be.false diff --git a/server/tests/api/singlePod.js b/server/tests/api/singlePod.js index efd8a64bc..e2999530e 100644 --- a/server/tests/api/singlePod.js +++ b/server/tests/api/singlePod.js @@ -4,6 +4,7 @@ const async = require('async') const chai = require('chai') const expect = chai.expect const fs = require('fs') +const keyBy = require('lodash/keyBy') const pathUtils = require('path') const webtorrent = require(pathUtils.join(__dirname, '../../lib/webtorrent')) @@ -165,6 +166,37 @@ describe('Test a single pod', function () { }) }) + it('Should upload 6 videos', function (done) { + this.timeout(25000) + const videos = [ + 'video_short.mp4', 'video_short.ogv', 'video_short.webm', + 'video_short1.webm', 'video_short2.webm', 'video_short3.webm' + ] + async.each(videos, function (video, callback_each) { + utils.uploadVideo(server.url, server.access_token, video + ' name', video + ' description', video, callback_each) + }, done) + }) + + it('Should have the correct durations', function (done) { + utils.getVideosList(server.url, function (err, res) { + if (err) throw err + + const videos = res.body + expect(videos).to.be.an('array') + expect(videos.length).to.equal(6) + + const videos_by_name = keyBy(videos, 'name') + expect(videos_by_name['video_short.mp4 name'].duration).to.equal(5) + expect(videos_by_name['video_short.ogv name'].duration).to.equal(5) + expect(videos_by_name['video_short.webm name'].duration).to.equal(5) + expect(videos_by_name['video_short1.webm name'].duration).to.equal(10) + expect(videos_by_name['video_short2.webm name'].duration).to.equal(5) + expect(videos_by_name['video_short3.webm name'].duration).to.equal(5) + + done() + }) + }) + after(function (done) { process.kill(-server.app.pid) process.kill(-webtorrent.app.pid)