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