]>
Commit | Line | Data |
---|---|---|
9f10b292 C |
1 | 'use strict' |
2 | ||
f0f5567b C |
3 | const async = require('async') |
4 | const config = require('config') | |
0ae6a09d | 5 | const ffmpeg = require('fluent-ffmpeg') |
cbe2f7c3 C |
6 | const fs = require('fs') |
7 | const map = require('lodash/map') | |
f0f5567b | 8 | const pathUtils = require('path') |
9f10b292 | 9 | |
cbe2f7c3 | 10 | const constants = require('../initializers/constants') |
f0f5567b | 11 | const logger = require('../helpers/logger') |
cbe2f7c3 | 12 | const utils = require('../helpers/utils') |
f0f5567b | 13 | const Videos = require('../models/videos') |
cbe2f7c3 | 14 | const webtorrent = require('../lib/webtorrent') |
9f10b292 | 15 | |
f0f5567b | 16 | const uploadDir = pathUtils.join(__dirname, '..', '..', config.get('storage.uploads')) |
cbe2f7c3 | 17 | const thumbnailsDir = pathUtils.join(__dirname, '..', '..', config.get('storage.thumbnails')) |
9f10b292 | 18 | |
f0f5567b | 19 | const videos = { |
cbe2f7c3 | 20 | createRemoteVideos: createRemoteVideos, |
0ae6a09d | 21 | getVideoDuration: getVideoDuration, |
5101105e | 22 | getVideoState: getVideoState, |
57a56079 | 23 | createVideoThumbnail: createVideoThumbnail, |
cbe2f7c3 C |
24 | removeVideosDataFromDisk: removeVideosDataFromDisk, |
25 | removeRemoteVideos: removeRemoteVideos, | |
9f10b292 C |
26 | seed: seed, |
27 | seedAllExisting: seedAllExisting | |
28 | } | |
29 | ||
cbe2f7c3 C |
30 | function createRemoteVideos (videos, callback) { |
31 | // Create the remote videos from the new pod | |
bc503c2a | 32 | createRemoteVideoObjects(videos, function (err, remoteVideos) { |
cbe2f7c3 C |
33 | if (err) return callback(err) |
34 | ||
bc503c2a | 35 | Videos.addRemotes(remoteVideos, callback) |
cbe2f7c3 C |
36 | }) |
37 | } | |
38 | ||
bc503c2a C |
39 | function getVideoDuration (videoPath, callback) { |
40 | ffmpeg.ffprobe(videoPath, function (err, metadata) { | |
0ae6a09d C |
41 | if (err) return callback(err) |
42 | ||
43 | return callback(null, Math.floor(metadata.format.duration)) | |
44 | }) | |
45 | } | |
46 | ||
2df82d42 | 47 | function getVideoState (video) { |
f0f5567b C |
48 | const exist = (video !== null) |
49 | let owned = false | |
5101105e C |
50 | if (exist === true) { |
51 | owned = (video.namePath !== null) | |
52 | } | |
53 | ||
2df82d42 | 54 | return { exist: exist, owned: owned } |
5101105e C |
55 | } |
56 | ||
57a56079 | 57 | function createVideoThumbnail (videoPath, callback) { |
bc503c2a C |
58 | const filename = pathUtils.basename(videoPath) + '.jpg' |
59 | ffmpeg(videoPath) | |
cbe2f7c3 C |
60 | .on('error', callback) |
61 | .on('end', function () { | |
62 | callback(null, filename) | |
63 | }) | |
64 | .thumbnail({ | |
65 | count: 1, | |
66 | folder: thumbnailsDir, | |
67 | size: constants.THUMBNAILS_SIZE, | |
68 | filename: filename | |
69 | }) | |
70 | } | |
71 | ||
72 | // Remove video datas from disk (video file, thumbnail...) | |
73 | function removeVideosDataFromDisk (videos, callback) { | |
bc503c2a | 74 | async.each(videos, function (video, callbackEach) { |
cbe2f7c3 C |
75 | fs.unlink(thumbnailsDir + video.thumbnail, function (err) { |
76 | if (err) logger.error('Cannot remove the video thumbnail') | |
77 | ||
78 | if (getVideoState(video).owned === true) { | |
79 | fs.unlink(uploadDir + video.namePath, function (err) { | |
80 | if (err) { | |
81 | logger.error('Cannot remove this video file.') | |
bc503c2a | 82 | return callbackEach(err) |
cbe2f7c3 C |
83 | } |
84 | ||
bc503c2a | 85 | callbackEach(null) |
cbe2f7c3 C |
86 | }) |
87 | } else { | |
bc503c2a | 88 | callbackEach(null) |
cbe2f7c3 C |
89 | } |
90 | }) | |
91 | }, callback) | |
92 | } | |
93 | ||
94 | function removeRemoteVideos (videos, callback) { | |
95 | Videos.removeByIds(map(videos, '_id'), function (err) { | |
96 | if (err) return callback(err) | |
97 | ||
98 | removeVideosDataFromDisk(videos, callback) | |
99 | }) | |
100 | } | |
101 | ||
9f10b292 C |
102 | function seed (path, callback) { |
103 | logger.info('Seeding %s...', path) | |
104 | ||
105 | webtorrent.seed(path, function (torrent) { | |
106 | logger.info('%s seeded (%s).', path, torrent.magnetURI) | |
107 | ||
108 | return callback(null, torrent) | |
109 | }) | |
110 | } | |
111 | ||
112 | function seedAllExisting (callback) { | |
bc503c2a | 113 | Videos.listOwned(function (err, videosList) { |
9f10b292 C |
114 | if (err) { |
115 | logger.error('Cannot get list of the videos to seed.') | |
116 | return callback(err) | |
117 | } | |
118 | ||
bc503c2a | 119 | async.each(videosList, function (video, callbackEach) { |
9f10b292 C |
120 | seed(uploadDir + video.namePath, function (err) { |
121 | if (err) { | |
122 | logger.error('Cannot seed this video.') | |
123 | return callback(err) | |
124 | } | |
125 | ||
bc503c2a | 126 | callbackEach(null) |
9f10b292 C |
127 | }) |
128 | }, callback) | |
129 | }) | |
130 | } | |
131 | ||
132 | // --------------------------------------------------------------------------- | |
133 | ||
134 | module.exports = videos | |
cbe2f7c3 C |
135 | |
136 | // --------------------------------------------------------------------------- | |
137 | ||
138 | function createRemoteVideoObjects (videos, callback) { | |
bc503c2a | 139 | const remoteVideos = [] |
cbe2f7c3 | 140 | |
bc503c2a | 141 | async.each(videos, function (video, callbackEach) { |
cbe2f7c3 | 142 | // Creating the thumbnail for this remote video |
bc503c2a C |
143 | utils.generateRandomString(16, function (err, randomString) { |
144 | if (err) return callbackEach(err) | |
cbe2f7c3 | 145 | |
bc503c2a C |
146 | const thumbnailName = randomString + '.jpg' |
147 | createThumbnailFromBase64(thumbnailName, video.thumbnailBase64, function (err) { | |
148 | if (err) return callbackEach(err) | |
cbe2f7c3 C |
149 | |
150 | const params = { | |
151 | name: video.name, | |
152 | description: video.description, | |
153 | magnetUri: video.magnetUri, | |
154 | podUrl: video.podUrl, | |
155 | duration: video.duration, | |
be587647 C |
156 | thumbnail: thumbnailName, |
157 | tags: video.tags | |
cbe2f7c3 | 158 | } |
bc503c2a | 159 | remoteVideos.push(params) |
cbe2f7c3 | 160 | |
bc503c2a | 161 | callbackEach(null) |
cbe2f7c3 C |
162 | }) |
163 | }) | |
164 | }, | |
165 | function (err) { | |
166 | if (err) return callback(err) | |
167 | ||
bc503c2a | 168 | callback(null, remoteVideos) |
cbe2f7c3 C |
169 | }) |
170 | } | |
171 | ||
bc503c2a C |
172 | function createThumbnailFromBase64 (thumbnailName, data, callback) { |
173 | fs.writeFile(thumbnailsDir + thumbnailName, data, { encoding: 'base64' }, callback) | |
cbe2f7c3 | 174 | } |