aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/helpers
diff options
context:
space:
mode:
Diffstat (limited to 'server/helpers')
-rw-r--r--server/helpers/webtorrent.ts61
1 files changed, 48 insertions, 13 deletions
diff --git a/server/helpers/webtorrent.ts b/server/helpers/webtorrent.ts
index c84376304..012918468 100644
--- a/server/helpers/webtorrent.ts
+++ b/server/helpers/webtorrent.ts
@@ -1,5 +1,6 @@
1import * as bencode from 'bencode'
1import * as createTorrent from 'create-torrent' 2import * as createTorrent from 'create-torrent'
2import { createWriteStream, ensureDir, remove, writeFile } from 'fs-extra' 3import { createWriteStream, ensureDir, readFile, remove, writeFile } from 'fs-extra'
3import * as magnetUtil from 'magnet-uri' 4import * as magnetUtil from 'magnet-uri'
4import * as parseTorrent from 'parse-torrent' 5import * as parseTorrent from 'parse-torrent'
5import { dirname, join } from 'path' 6import { dirname, join } from 'path'
@@ -79,43 +80,65 @@ async function downloadWebTorrentVideo (target: { magnetUri: string, torrentName
79 }) 80 })
80} 81}
81 82
82function createTorrentAndSetInfoHash ( 83function createTorrentAndSetInfoHash (videoOrPlaylist: MVideo | MStreamingPlaylistVideo, videoFile: MVideoFile) {
83 videoOrPlaylist: MVideo | MStreamingPlaylistVideo,
84 videoFile: MVideoFile
85) {
86 const video = extractVideo(videoOrPlaylist) 84 const video = extractVideo(videoOrPlaylist)
87 85
88 const options = { 86 const options = {
89 // Keep the extname, it's used by the client to stream the file inside a web browser 87 // Keep the extname, it's used by the client to stream the file inside a web browser
90 name: `${video.name} ${videoFile.resolution}p${videoFile.extname}`, 88 name: `${video.name} ${videoFile.resolution}p${videoFile.extname}`,
91 createdBy: 'PeerTube', 89 createdBy: 'PeerTube',
92 announceList: [ 90 announceList: buildAnnounceList(),
93 [ WEBSERVER.WS + '://' + WEBSERVER.HOSTNAME + ':' + WEBSERVER.PORT + '/tracker/socket' ], 91 urlList: buildUrlList(video, videoFile)
94 [ WEBSERVER.URL + '/tracker/announce' ]
95 ],
96 urlList: [ videoFile.getFileUrl(video) ]
97 } 92 }
98 93
99 return VideoPathManager.Instance.makeAvailableVideoFile(videoOrPlaylist, videoFile, async videoPath => { 94 return VideoPathManager.Instance.makeAvailableVideoFile(videoOrPlaylist, videoFile, async videoPath => {
100 const torrent = await createTorrentPromise(videoPath, options) 95 const torrentContent = await createTorrentPromise(videoPath, options)
101 96
102 const torrentFilename = generateTorrentFileName(videoOrPlaylist, videoFile.resolution) 97 const torrentFilename = generateTorrentFileName(videoOrPlaylist, videoFile.resolution)
103 const torrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, torrentFilename) 98 const torrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, torrentFilename)
104 logger.info('Creating torrent %s.', torrentPath) 99 logger.info('Creating torrent %s.', torrentPath)
105 100
106 await writeFile(torrentPath, torrent) 101 await writeFile(torrentPath, torrentContent)
107 102
108 // Remove old torrent file if it existed 103 // Remove old torrent file if it existed
109 if (videoFile.hasTorrent()) { 104 if (videoFile.hasTorrent()) {
110 await remove(join(CONFIG.STORAGE.TORRENTS_DIR, videoFile.torrentFilename)) 105 await remove(join(CONFIG.STORAGE.TORRENTS_DIR, videoFile.torrentFilename))
111 } 106 }
112 107
113 const parsedTorrent = parseTorrent(torrent) 108 const parsedTorrent = parseTorrent(torrentContent)
114 videoFile.infoHash = parsedTorrent.infoHash 109 videoFile.infoHash = parsedTorrent.infoHash
115 videoFile.torrentFilename = torrentFilename 110 videoFile.torrentFilename = torrentFilename
116 }) 111 })
117} 112}
118 113
114async function updateTorrentUrls (videoOrPlaylist: MVideo | MStreamingPlaylistVideo, videoFile: MVideoFile) {
115 const video = extractVideo(videoOrPlaylist)
116
117 const oldTorrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, videoFile.torrentFilename)
118
119 const torrentContent = await readFile(oldTorrentPath)
120 const decoded = bencode.decode(torrentContent)
121
122 decoded['announce-list'] = buildAnnounceList()
123 decoded.announce = decoded['announce-list'][0][0]
124
125 decoded['url-list'] = buildUrlList(video, videoFile)
126
127 const newTorrentFilename = generateTorrentFileName(videoOrPlaylist, videoFile.resolution)
128 const newTorrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, newTorrentFilename)
129
130 logger.info('Updating torrent URLs %s.', newTorrentPath)
131
132 await writeFile(newTorrentPath, bencode.encode(decoded))
133
134 // Remove old torrent file if it existed
135 if (videoFile.hasTorrent()) {
136 await remove(join(CONFIG.STORAGE.TORRENTS_DIR, videoFile.torrentFilename))
137 }
138
139 videoFile.torrentFilename = newTorrentFilename
140}
141
119function generateMagnetUri ( 142function generateMagnetUri (
120 video: MVideo, 143 video: MVideo,
121 videoFile: MVideoFileRedundanciesOpt, 144 videoFile: MVideoFileRedundanciesOpt,
@@ -143,6 +166,7 @@ function generateMagnetUri (
143 166
144export { 167export {
145 createTorrentPromise, 168 createTorrentPromise,
169 updateTorrentUrls,
146 createTorrentAndSetInfoHash, 170 createTorrentAndSetInfoHash,
147 generateMagnetUri, 171 generateMagnetUri,
148 downloadWebTorrentVideo 172 downloadWebTorrentVideo
@@ -186,3 +210,14 @@ function deleteDownloadedFile (downloadedFile: { directoryPath: string, filepath
186 remove(toRemovePath) 210 remove(toRemovePath)
187 .catch(err => logger.error('Cannot remove torrent file %s in webtorrent download.', toRemovePath, { err })) 211 .catch(err => logger.error('Cannot remove torrent file %s in webtorrent download.', toRemovePath, { err }))
188} 212}
213
214function buildAnnounceList () {
215 return [
216 [ WEBSERVER.WS + '://' + WEBSERVER.HOSTNAME + ':' + WEBSERVER.PORT + '/tracker/socket' ],
217 [ WEBSERVER.URL + '/tracker/announce' ]
218 ]
219}
220
221function buildUrlList (video: MVideo, videoFile: MVideoFile) {
222 return [ videoFile.getFileUrl(video) ]
223}