diff options
-rw-r--r-- | README.md | 8 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | server/controllers/api/v1/videos.js | 45 | ||||
-rw-r--r-- | server/helpers/customValidators.js | 3 | ||||
-rw-r--r-- | server/models/videos.js | 6 | ||||
-rw-r--r-- | server/tests/api/multiplePods.js | 5 | ||||
-rw-r--r-- | server/tests/api/singlePod.js | 32 |
7 files changed, 78 insertions, 22 deletions
@@ -64,13 +64,15 @@ Thanks to [WebTorrent](https://github.com/feross/webtorrent), we can make P2P (t | |||
64 | * **NodeJS >= 4.2** | 64 | * **NodeJS >= 4.2** |
65 | * OpenSSL (cli) | 65 | * OpenSSL (cli) |
66 | * MongoDB | 66 | * MongoDB |
67 | * xvfb-run libgtk2.0-0 libgconf-2-4 libnss3 libasound2 libxtst6 libxss1 libnotify-bin (for electron) | 67 | * ffmpeg xvfb-run libgtk2.0-0 libgconf-2-4 libnss3 libasound2 libxtst6 libxss1 libnotify-bin (for electron) |
68 | 68 | ||
69 | #### Debian | 69 | #### Debian |
70 | 70 | ||
71 | 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) | 71 | * 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) |
72 | * Add jessie backports to your *source.list*: http://backports.debian.org/Instructions/ | ||
72 | 73 | ||
73 | # apt-get install mongodb openssl xvfb curl sudo git build-essential libgtk2.0-0 libgconf-2-4 libnss3 libasound2 libxtst6 libxss1 libnotify-bin | 74 | # apt-get update |
75 | # apt-get install ffmpeg mongodb openssl xvfb curl sudo git build-essential libgtk2.0-0 libgconf-2-4 libnss3 libasound2 libxtst6 libxss1 libnotify-bin | ||
74 | # npm install -g electron-prebuilt | 76 | # npm install -g electron-prebuilt |
75 | 77 | ||
76 | #### Other distribution... (PR welcome) | 78 | #### 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 @@ | |||
52 | "express": "^4.12.4", | 52 | "express": "^4.12.4", |
53 | "express-oauth-server": "https://github.com/Chocobozzz/express-oauth-server", | 53 | "express-oauth-server": "https://github.com/Chocobozzz/express-oauth-server", |
54 | "express-validator": "^2.11.0", | 54 | "express-validator": "^2.11.0", |
55 | "fluent-ffmpeg": "^2.1.0", | ||
55 | "js-yaml": "^3.5.4", | 56 | "js-yaml": "^3.5.4", |
56 | "lodash": "^4.11.1", | 57 | "lodash": "^4.11.1", |
57 | "mkdirp": "^0.5.1", | 58 | "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 @@ | |||
3 | const config = require('config') | 3 | const config = require('config') |
4 | const crypto = require('crypto') | 4 | const crypto = require('crypto') |
5 | const express = require('express') | 5 | const express = require('express') |
6 | const ffmpeg = require('fluent-ffmpeg') | ||
6 | const multer = require('multer') | 7 | const multer = require('multer') |
7 | 8 | ||
8 | const logger = require('../../../helpers/logger') | 9 | const logger = require('../../../helpers/logger') |
@@ -60,26 +61,37 @@ function addVideo (req, res, next) { | |||
60 | return next(err) | 61 | return next(err) |
61 | } | 62 | } |
62 | 63 | ||
63 | const video_data = { | 64 | ffmpeg.ffprobe(video_file.path, function (err, metadata) { |
64 | name: video_infos.name, | ||
65 | namePath: video_file.filename, | ||
66 | description: video_infos.description, | ||
67 | magnetUri: torrent.magnetURI, | ||
68 | author: res.locals.oauth.token.user.username | ||
69 | } | ||
70 | |||
71 | Videos.add(video_data, function (err) { | ||
72 | if (err) { | 65 | if (err) { |
73 | // TODO unseed the video | 66 | // TODO: unseed the video |
74 | logger.error('Cannot insert this video in the database.') | 67 | logger.error('Cannot retrieve metadata of the file') |
75 | return next(err) | 68 | return next(err) |
76 | } | 69 | } |
77 | 70 | ||
78 | // Now we'll add the video's meta data to our friends | 71 | const duration = Math.floor(metadata.format.duration) |
79 | friends.addVideoToFriends(video_data) | ||
80 | 72 | ||
81 | // TODO : include Location of the new video -> 201 | 73 | const video_data = { |
82 | res.type('json').status(204).end() | 74 | name: video_infos.name, |
75 | namePath: video_file.filename, | ||
76 | description: video_infos.description, | ||
77 | magnetUri: torrent.magnetURI, | ||
78 | author: res.locals.oauth.token.user.username, | ||
79 | duration: duration | ||
80 | } | ||
81 | |||
82 | Videos.add(video_data, function (err) { | ||
83 | if (err) { | ||
84 | // TODO unseed the video | ||
85 | logger.error('Cannot insert this video in the database.') | ||
86 | return next(err) | ||
87 | } | ||
88 | |||
89 | // Now we'll add the video's meta data to our friends | ||
90 | friends.addVideoToFriends(video_data) | ||
91 | |||
92 | // TODO : include Location of the new video -> 201 | ||
93 | res.type('json').status(204).end() | ||
94 | }) | ||
83 | }) | 95 | }) |
84 | }) | 96 | }) |
85 | } | 97 | } |
@@ -144,7 +156,8 @@ function getFormatedVideo (video_obj) { | |||
144 | podUrl: video_obj.podUrl, | 156 | podUrl: video_obj.podUrl, |
145 | isLocal: videos.getVideoState(video_obj).owned, | 157 | isLocal: videos.getVideoState(video_obj).owned, |
146 | magnetUri: video_obj.magnetUri, | 158 | magnetUri: video_obj.magnetUri, |
147 | author: video_obj.author | 159 | author: video_obj.author, |
160 | duration: video_obj.duration | ||
148 | } | 161 | } |
149 | 162 | ||
150 | return formated_video | 163 | 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) { | |||
13 | return validator.isLength(val.name, 1, 50) && | 13 | return validator.isLength(val.name, 1, 50) && |
14 | validator.isLength(val.description, 1, 50) && | 14 | validator.isLength(val.description, 1, 50) && |
15 | validator.isLength(val.magnetUri, 10) && | 15 | validator.isLength(val.magnetUri, 10) && |
16 | validator.isURL(val.podUrl) | 16 | validator.isURL(val.podUrl) && |
17 | !isNaN(val.duration) | ||
17 | }) | 18 | }) |
18 | } | 19 | } |
19 | 20 | ||
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({ | |||
22 | description: String, | 22 | description: String, |
23 | magnetUri: String, | 23 | magnetUri: String, |
24 | podUrl: String, | 24 | podUrl: String, |
25 | author: String | 25 | author: String, |
26 | duration: Number | ||
26 | }) | 27 | }) |
27 | const VideosDB = mongoose.model('videos', videosSchema) | 28 | const VideosDB = mongoose.model('videos', videosSchema) |
28 | 29 | ||
@@ -72,7 +73,8 @@ function addRemotes (videos, callback) { | |||
72 | namePath: null, | 73 | namePath: null, |
73 | description: video.description, | 74 | description: video.description, |
74 | magnetUri: video.magnetUri, | 75 | magnetUri: video.magnetUri, |
75 | podUrl: video.podUrl | 76 | podUrl: video.podUrl, |
77 | duration: video.duration | ||
76 | } | 78 | } |
77 | 79 | ||
78 | to_add.push(params) | 80 | 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 () { | |||
95 | expect(video.description).to.equal('my super description for pod 1') | 95 | expect(video.description).to.equal('my super description for pod 1') |
96 | expect(video.podUrl).to.equal('http://localhost:9001') | 96 | expect(video.podUrl).to.equal('http://localhost:9001') |
97 | expect(video.magnetUri).to.exist | 97 | expect(video.magnetUri).to.exist |
98 | expect(video.duration).to.equal(10) | ||
98 | 99 | ||
99 | if (server.url !== 'http://localhost:9001') { | 100 | if (server.url !== 'http://localhost:9001') { |
100 | expect(video.isLocal).to.be.false | 101 | expect(video.isLocal).to.be.false |
@@ -144,6 +145,7 @@ describe('Test multiple pods', function () { | |||
144 | expect(video.description).to.equal('my super description for pod 2') | 145 | expect(video.description).to.equal('my super description for pod 2') |
145 | expect(video.podUrl).to.equal('http://localhost:9002') | 146 | expect(video.podUrl).to.equal('http://localhost:9002') |
146 | expect(video.magnetUri).to.exist | 147 | expect(video.magnetUri).to.exist |
148 | expect(video.duration).to.equal(5) | ||
147 | 149 | ||
148 | if (server.url !== 'http://localhost:9002') { | 150 | if (server.url !== 'http://localhost:9002') { |
149 | expect(video.isLocal).to.be.false | 151 | expect(video.isLocal).to.be.false |
@@ -190,17 +192,20 @@ describe('Test multiple pods', function () { | |||
190 | const videos = res.body | 192 | const videos = res.body |
191 | expect(videos).to.be.an('array') | 193 | expect(videos).to.be.an('array') |
192 | expect(videos.length).to.equal(4) | 194 | expect(videos.length).to.equal(4) |
195 | |||
193 | const video1 = videos[2] | 196 | const video1 = videos[2] |
194 | expect(video1.name).to.equal('my super name for pod 3') | 197 | expect(video1.name).to.equal('my super name for pod 3') |
195 | expect(video1.description).to.equal('my super description for pod 3') | 198 | expect(video1.description).to.equal('my super description for pod 3') |
196 | expect(video1.podUrl).to.equal('http://localhost:9003') | 199 | expect(video1.podUrl).to.equal('http://localhost:9003') |
197 | expect(video1.magnetUri).to.exist | 200 | expect(video1.magnetUri).to.exist |
201 | expect(video1.duration).to.equal(5) | ||
198 | 202 | ||
199 | const video2 = videos[3] | 203 | const video2 = videos[3] |
200 | expect(video2.name).to.equal('my super name for pod 3-2') | 204 | expect(video2.name).to.equal('my super name for pod 3-2') |
201 | expect(video2.description).to.equal('my super description for pod 3-2') | 205 | expect(video2.description).to.equal('my super description for pod 3-2') |
202 | expect(video2.podUrl).to.equal('http://localhost:9003') | 206 | expect(video2.podUrl).to.equal('http://localhost:9003') |
203 | expect(video2.magnetUri).to.exist | 207 | expect(video2.magnetUri).to.exist |
208 | expect(video2.duration).to.equal(5) | ||
204 | 209 | ||
205 | if (server.url !== 'http://localhost:9003') { | 210 | if (server.url !== 'http://localhost:9003') { |
206 | expect(video1.isLocal).to.be.false | 211 | 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') | |||
4 | const chai = require('chai') | 4 | const chai = require('chai') |
5 | const expect = chai.expect | 5 | const expect = chai.expect |
6 | const fs = require('fs') | 6 | const fs = require('fs') |
7 | const keyBy = require('lodash/keyBy') | ||
7 | const pathUtils = require('path') | 8 | const pathUtils = require('path') |
8 | 9 | ||
9 | const webtorrent = require(pathUtils.join(__dirname, '../../lib/webtorrent')) | 10 | const webtorrent = require(pathUtils.join(__dirname, '../../lib/webtorrent')) |
@@ -165,6 +166,37 @@ describe('Test a single pod', function () { | |||
165 | }) | 166 | }) |
166 | }) | 167 | }) |
167 | 168 | ||
169 | it('Should upload 6 videos', function (done) { | ||
170 | this.timeout(25000) | ||
171 | const videos = [ | ||
172 | 'video_short.mp4', 'video_short.ogv', 'video_short.webm', | ||
173 | 'video_short1.webm', 'video_short2.webm', 'video_short3.webm' | ||
174 | ] | ||
175 | async.each(videos, function (video, callback_each) { | ||
176 | utils.uploadVideo(server.url, server.access_token, video + ' name', video + ' description', video, callback_each) | ||
177 | }, done) | ||
178 | }) | ||
179 | |||
180 | it('Should have the correct durations', function (done) { | ||
181 | utils.getVideosList(server.url, function (err, res) { | ||
182 | if (err) throw err | ||
183 | |||
184 | const videos = res.body | ||
185 | expect(videos).to.be.an('array') | ||
186 | expect(videos.length).to.equal(6) | ||
187 | |||
188 | const videos_by_name = keyBy(videos, 'name') | ||
189 | expect(videos_by_name['video_short.mp4 name'].duration).to.equal(5) | ||
190 | expect(videos_by_name['video_short.ogv name'].duration).to.equal(5) | ||
191 | expect(videos_by_name['video_short.webm name'].duration).to.equal(5) | ||
192 | expect(videos_by_name['video_short1.webm name'].duration).to.equal(10) | ||
193 | expect(videos_by_name['video_short2.webm name'].duration).to.equal(5) | ||
194 | expect(videos_by_name['video_short3.webm name'].duration).to.equal(5) | ||
195 | |||
196 | done() | ||
197 | }) | ||
198 | }) | ||
199 | |||
168 | after(function (done) { | 200 | after(function (done) { |
169 | process.kill(-server.app.pid) | 201 | process.kill(-server.app.pid) |
170 | process.kill(-webtorrent.app.pid) | 202 | process.kill(-webtorrent.app.pid) |