diff options
Diffstat (limited to 'server/helpers')
-rw-r--r-- | server/helpers/webtorrent.ts | 61 |
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 @@ | |||
1 | import * as bencode from 'bencode' | ||
1 | import * as createTorrent from 'create-torrent' | 2 | import * as createTorrent from 'create-torrent' |
2 | import { createWriteStream, ensureDir, remove, writeFile } from 'fs-extra' | 3 | import { createWriteStream, ensureDir, readFile, remove, writeFile } from 'fs-extra' |
3 | import * as magnetUtil from 'magnet-uri' | 4 | import * as magnetUtil from 'magnet-uri' |
4 | import * as parseTorrent from 'parse-torrent' | 5 | import * as parseTorrent from 'parse-torrent' |
5 | import { dirname, join } from 'path' | 6 | import { dirname, join } from 'path' |
@@ -79,43 +80,65 @@ async function downloadWebTorrentVideo (target: { magnetUri: string, torrentName | |||
79 | }) | 80 | }) |
80 | } | 81 | } |
81 | 82 | ||
82 | function createTorrentAndSetInfoHash ( | 83 | function 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 | ||
114 | async 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 | |||
119 | function generateMagnetUri ( | 142 | function generateMagnetUri ( |
120 | video: MVideo, | 143 | video: MVideo, |
121 | videoFile: MVideoFileRedundanciesOpt, | 144 | videoFile: MVideoFileRedundanciesOpt, |
@@ -143,6 +166,7 @@ function generateMagnetUri ( | |||
143 | 166 | ||
144 | export { | 167 | export { |
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 | |||
214 | function buildAnnounceList () { | ||
215 | return [ | ||
216 | [ WEBSERVER.WS + '://' + WEBSERVER.HOSTNAME + ':' + WEBSERVER.PORT + '/tracker/socket' ], | ||
217 | [ WEBSERVER.URL + '/tracker/announce' ] | ||
218 | ] | ||
219 | } | ||
220 | |||
221 | function buildUrlList (video: MVideo, videoFile: MVideoFile) { | ||
222 | return [ videoFile.getFileUrl(video) ] | ||
223 | } | ||