+ private addTorrent (
+ magnetOrTorrentUrl: string,
+ previousVideoFile: VideoFile,
+ options: PlayOptions,
+ done: Function
+ ) {
+ console.log('Adding ' + magnetOrTorrentUrl + '.')
+
+ const oldTorrent = this.torrent
+ const torrentOptions = {
+ store: (chunkLength: number, storeOpts: any) => new CacheChunkStore(new PeertubeChunkStore(chunkLength, storeOpts), {
+ max: 100
+ })
+ }
+
+ this.torrent = this.webtorrent.add(magnetOrTorrentUrl, torrentOptions, torrent => {
+ console.log('Added ' + magnetOrTorrentUrl + '.')
+
+ if (oldTorrent) {
+ // Pause the old torrent
+ this.stopTorrent(oldTorrent)
+
+ // We use a fake renderer so we download correct pieces of the next file
+ if (options.delay) this.renderFileInFakeElement(torrent.files[ 0 ], options.delay)
+ }
+
+ // Render the video in a few seconds? (on resolution change for example, we wait some seconds of the new video resolution)
+ this.addTorrentDelay = setTimeout(() => {
+ // We don't need the fake renderer anymore
+ this.destroyFakeRenderer()
+
+ const paused = this.player.paused()
+
+ this.flushVideoFile(previousVideoFile)
+
+ // Update progress bar (just for the UI), do not wait rendering
+ if (options.seek) this.player.currentTime(options.seek)
+
+ const renderVideoOptions = { autoplay: false, controls: true }
+ renderVideo(torrent.files[ 0 ], this.playerElement, renderVideoOptions, (err, renderer) => {
+ this.renderer = renderer
+
+ if (err) return this.fallbackToHttp(options, done)
+
+ return this.tryToPlay(err => {
+ if (err) return done(err)
+
+ if (options.seek) this.seek(options.seek)
+ if (options.forcePlay === false && paused === true) this.player.pause()
+
+ return done()
+ })
+ })
+ }, options.delay || 0)
+ })
+
+ this.torrent.on('error', (err: any) => console.error(err))
+
+ this.torrent.on('warning', (err: any) => {
+ // We don't support HTTP tracker but we don't care -> we use the web socket tracker
+ if (err.message.indexOf('Unsupported tracker protocol') !== -1) return
+
+ // Users don't care about issues with WebRTC, but developers do so log it in the console
+ if (err.message.indexOf('Ice connection failed') !== -1) {
+ console.log(err)
+ return
+ }
+
+ // Magnet hash is not up to date with the torrent file, add directly the torrent file
+ if (err.message.indexOf('incorrect info hash') !== -1) {
+ console.error('Incorrect info hash detected, falling back to torrent file.')
+ const newOptions = { forcePlay: true, seek: options.seek }
+ return this.addTorrent(this.torrent[ 'xs' ], previousVideoFile, newOptions, done)
+ }
+
+ // Remote instance is down
+ if (err.message.indexOf('from xs param') !== -1) {
+ this.handleError(err)
+ }
+
+ console.warn(err)
+ })
+ }
+
+ private tryToPlay (done?: (err?: Error) => void) {