{"version":3,"sources":["webpack:///./src/assets/player/webtorrent/peertube-chunk-store.ts","webpack:///./src/assets/player/webtorrent/video-renderer.ts","webpack:///./src/assets/player/webtorrent/webtorrent-plugin.ts","webpack:///util (ignored)?8364","webpack:///./get-files (ignored)","webpack:///bittorrent-dht/client (ignored)","webpack:///load-ip-set (ignored)","webpack:///fs (ignored)?bede","webpack:///decompress-response (ignored)","webpack:///util (ignored)","webpack:///util (ignored)?f15f","webpack:///util (ignored)?e240","webpack:///util (ignored)?5554","webpack:///util (ignored)?7b2c","webpack:///./lib/conn-pool (ignored)","webpack:///util (ignored)?ddd9","webpack:///util (ignored)?3bf5","webpack:///bittorrent-dht/client (ignored)?3128","webpack:///./common-node (ignored)","webpack:///./lib/client/http-tracker (ignored)","webpack:///./lib/client/udp-tracker (ignored)","webpack:///util (ignored)?2d5f","webpack:///util (ignored)?00bc","webpack:///ws (ignored)","webpack:///util (ignored)?4bcd","webpack:///bittorrent-lsd (ignored)","webpack:///fs (ignored)?7e56","webpack:///net (ignored)","webpack:///os (ignored)","webpack:///fs (ignored)","webpack:///utp-native (ignored)","webpack:///ut_pex (ignored)","webpack:///util (ignored)?b8a2","webpack:///util (ignored)?c3ce","webpack:///util (ignored)?1ed3","webpack:///util (ignored)?9742","webpack:///util (ignored)?418a","webpack:///util (ignored)?4d6a","webpack:///util (ignored)?05b1","webpack:///util (ignored)?c408","webpack:///util (ignored)?2af4","webpack:///util (ignored)?c0cf","webpack:///util (ignored)?71ec","webpack:///./server (ignored)","webpack:///util (ignored)?02b5","webpack:///is-file (ignored)","webpack:///util (ignored)?f32b","webpack:///util (ignored)?9333","webpack:///util (ignored)?fd47"],"names":[],"mappings":"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","file":"4.chunk.js?v=8582","sourcesContent":["// From https://github.com/MinEduTDF/idb-chunk-store\r\n// We use temporary IndexDB (all data are removed on destroy) to avoid RAM issues\r\n// Thanks @santiagogil and @Feross\r\n\r\nimport { EventEmitter } from 'events'\r\nimport Dexie from 'dexie'\r\n\r\nclass ChunkDatabase extends Dexie {\r\n chunks: Dexie.Table<{ id: number, buf: Buffer }, number>\r\n\r\n constructor (dbname: string) {\r\n super(dbname)\r\n\r\n this.version(1).stores({\r\n chunks: 'id'\r\n })\r\n }\r\n}\r\n\r\nclass ExpirationDatabase extends Dexie {\r\n databases: Dexie.Table<{ name: string, expiration: number }, number>\r\n\r\n constructor () {\r\n super('webtorrent-expiration')\r\n\r\n this.version(1).stores({\r\n databases: 'name,expiration'\r\n })\r\n }\r\n}\r\n\r\nexport class PeertubeChunkStore extends EventEmitter {\r\n private static readonly BUFFERING_PUT_MS = 1000\r\n private static readonly CLEANER_INTERVAL_MS = 1000 * 60 // 1 minute\r\n private static readonly CLEANER_EXPIRATION_MS = 1000 * 60 * 5 // 5 minutes\r\n\r\n chunkLength: number\r\n\r\n private pendingPut: { id: number, buf: Buffer, cb: Function }[] = []\r\n // If the store is full\r\n private memoryChunks: { [ id: number ]: Buffer | true } = {}\r\n private databaseName: string\r\n private putBulkTimeout: any\r\n private cleanerInterval: any\r\n private db: ChunkDatabase\r\n private expirationDB: ExpirationDatabase\r\n private readonly length: number\r\n private readonly lastChunkLength: number\r\n private readonly lastChunkIndex: number\r\n\r\n constructor (chunkLength: number, opts: any) {\r\n super()\r\n\r\n this.databaseName = 'webtorrent-chunks-'\r\n\r\n if (!opts) opts = {}\r\n if (opts.torrent && opts.torrent.infoHash) this.databaseName += opts.torrent.infoHash\r\n else this.databaseName += '-default'\r\n\r\n this.setMaxListeners(100)\r\n\r\n this.chunkLength = Number(chunkLength)\r\n if (!this.chunkLength) throw new Error('First argument must be a chunk length')\r\n\r\n this.length = Number(opts.length) || Infinity\r\n\r\n if (this.length !== Infinity) {\r\n this.lastChunkLength = (this.length % this.chunkLength) || this.chunkLength\r\n this.lastChunkIndex = Math.ceil(this.length / this.chunkLength) - 1\r\n }\r\n\r\n this.db = new ChunkDatabase(this.databaseName)\r\n // Track databases that expired\r\n this.expirationDB = new ExpirationDatabase()\r\n\r\n this.runCleaner()\r\n }\r\n\r\n put (index: number, buf: Buffer, cb: (err?: Error) => void) {\r\n const isLastChunk = (index === this.lastChunkIndex)\r\n if (isLastChunk && buf.length !== this.lastChunkLength) {\r\n return this.nextTick(cb, new Error('Last chunk length must be ' + this.lastChunkLength))\r\n }\r\n if (!isLastChunk && buf.length !== this.chunkLength) {\r\n return this.nextTick(cb, new Error('Chunk length must be ' + this.chunkLength))\r\n }\r\n\r\n // Specify we have this chunk\r\n this.memoryChunks[index] = true\r\n\r\n // Add it to the pending put\r\n this.pendingPut.push({ id: index, buf, cb })\r\n // If it's already planned, return\r\n if (this.putBulkTimeout) return\r\n\r\n // Plan a future bulk insert\r\n this.putBulkTimeout = setTimeout(async () => {\r\n const processing = this.pendingPut\r\n this.pendingPut = []\r\n this.putBulkTimeout = undefined\r\n\r\n try {\r\n await this.db.transaction('rw', this.db.chunks, () => {\r\n return this.db.chunks.bulkPut(processing.map(p => ({ id: p.id, buf: p.buf })))\r\n })\r\n } catch (err) {\r\n console.log('Cannot bulk insert chunks. Store them in memory.', { err })\r\n\r\n processing.forEach(p => this.memoryChunks[ p.id ] = p.buf)\r\n } finally {\r\n processing.forEach(p => p.cb())\r\n }\r\n }, PeertubeChunkStore.BUFFERING_PUT_MS)\r\n }\r\n\r\n get (index: number, opts: any, cb: (err?: Error, buf?: Buffer) => void): void {\r\n if (typeof opts === 'function') return this.get(index, null, opts)\r\n\r\n // IndexDB could be slow, use our memory index first\r\n const memoryChunk = this.memoryChunks[index]\r\n if (memoryChunk === undefined) {\r\n const err = new Error('Chunk not found') as any\r\n err['notFound'] = true\r\n\r\n return process.nextTick(() => cb(err))\r\n }\r\n\r\n // Chunk in memory\r\n if (memoryChunk !== true) return cb(null, memoryChunk)\r\n\r\n // Chunk in store\r\n this.db.transaction('r', this.db.chunks, async () => {\r\n const result = await this.db.chunks.get({ id: index })\r\n if (result === undefined) return cb(null, Buffer.alloc(0))\r\n\r\n const buf = result.buf\r\n if (!opts) return this.nextTick(cb, null, buf)\r\n\r\n const offset = opts.offset || 0\r\n const len = opts.length || (buf.length - offset)\r\n return cb(null, buf.slice(offset, len + offset))\r\n })\r\n .catch(err => {\r\n console.error(err)\r\n return cb(err)\r\n })\r\n }\r\n\r\n close (cb: (err?: Error) => void) {\r\n return this.destroy(cb)\r\n }\r\n\r\n async destroy (cb: (err?: Error) => void) {\r\n try {\r\n if (this.pendingPut) {\r\n clearTimeout(this.putBulkTimeout)\r\n this.pendingPut = null\r\n }\r\n if (this.cleanerInterval) {\r\n clearInterval(this.cleanerInterval)\r\n this.cleanerInterval = null\r\n }\r\n\r\n if (this.db) {\r\n this.db.close()\r\n\r\n await this.dropDatabase(this.databaseName)\r\n }\r\n\r\n if (this.expirationDB) {\r\n this.expirationDB.close()\r\n this.expirationDB = null\r\n }\r\n\r\n return cb()\r\n } catch (err) {\r\n console.error('Cannot destroy peertube chunk store.', err)\r\n return cb(err)\r\n }\r\n }\r\n\r\n private runCleaner () {\r\n this.checkExpiration()\r\n\r\n this.cleanerInterval = setInterval(async () => {\r\n this.checkExpiration()\r\n }, PeertubeChunkStore.CLEANER_INTERVAL_MS)\r\n }\r\n\r\n private async checkExpiration () {\r\n let databasesToDeleteInfo: { name: string }[] = []\r\n\r\n try {\r\n await this.expirationDB.transaction('rw', this.expirationDB.databases, async () => {\r\n // Update our database expiration since we are alive\r\n await this.expirationDB.databases.put({\r\n name: this.databaseName,\r\n expiration: new Date().getTime() + PeertubeChunkStore.CLEANER_EXPIRATION_MS\r\n })\r\n\r\n const now = new Date().getTime()\r\n databasesToDeleteInfo = await this.expirationDB.databases.where('expiration').below(now).toArray()\r\n })\r\n } catch (err) {\r\n console.error('Cannot update expiration of fetch expired databases.', err)\r\n }\r\n\r\n for (const databaseToDeleteInfo of databasesToDeleteInfo) {\r\n await this.dropDatabase(databaseToDeleteInfo.name)\r\n }\r\n }\r\n\r\n private async dropDatabase (databaseName: string) {\r\n const dbToDelete = new ChunkDatabase(databaseName)\r\n console.log('Destroying IndexDB database %s.', databaseName)\r\n\r\n try {\r\n await dbToDelete.delete()\r\n\r\n await this.expirationDB.transaction('rw', this.expirationDB.databases, () => {\r\n return this.expirationDB.databases.where({ name: databaseName }).delete()\r\n })\r\n } catch (err) {\r\n console.error('Cannot delete %s.', databaseName, err)\r\n }\r\n }\r\n\r\n private nextTick (cb: (err?: Error, val?: T) => void, err: Error, val?: T) {\r\n process.nextTick(() => cb(err, val), undefined)\r\n }\r\n}\r\n","// Thanks: https://github.com/feross/render-media\r\n// TODO: use render-media once https://github.com/feross/render-media/issues/32 is fixed\r\n\r\nconst MediaElementWrapper = require('mediasource')\r\nimport { extname } from 'path'\r\nconst videostream = require('videostream')\r\n\r\nconst VIDEOSTREAM_EXTS = [\r\n '.m4a',\r\n '.m4v',\r\n '.mp4'\r\n]\r\n\r\ntype RenderMediaOptions = {\r\n controls: boolean\r\n autoplay: boolean\r\n}\r\n\r\nfunction renderVideo (\r\n file: any,\r\n elem: HTMLVideoElement,\r\n opts: RenderMediaOptions,\r\n callback: (err: Error, renderer: any) => void\r\n) {\r\n validateFile(file)\r\n\r\n return renderMedia(file, elem, opts, callback)\r\n}\r\n\r\nfunction renderMedia (file: any, elem: HTMLVideoElement, opts: RenderMediaOptions, callback: (err: Error, renderer?: any) => void) {\r\n const extension = extname(file.name).toLowerCase()\r\n let preparedElem: any\r\n let currentTime = 0\r\n let renderer: any\r\n\r\n try {\r\n if (VIDEOSTREAM_EXTS.indexOf(extension) >= 0) {\r\n renderer = useVideostream()\r\n } else {\r\n renderer = useMediaSource()\r\n }\r\n } catch (err) {\r\n return callback(err)\r\n }\r\n\r\n function useVideostream () {\r\n prepareElem()\r\n\r\n\r\n preparedElem.addEventListener('error', function onError (err: Error) {\r\n preparedElem.removeEventListener('error', onError)\r\n\r\n return callback(err)\r\n })\r\n\r\n\r\n preparedElem.addEventListener('loadedmetadata', onLoadStart)\r\n return new videostream(file, preparedElem)\r\n }\r\n\r\n function useMediaSource (useVP9 = false) {\r\n const codecs = getCodec(file.name, useVP9)\r\n\r\n\r\n prepareElem()\r\n preparedElem.addEventListener('error', function onError (err: Error) {\r\n preparedElem.removeEventListener('error', onError)\r\n\r\n // Try with vp9 before returning an error\r\n if (codecs.indexOf('vp8') !== -1) return fallbackToMediaSource(true)\r\n\r\n return callback(err)\r\n })\r\n preparedElem.addEventListener('loadedmetadata', onLoadStart)\r\n\r\n const wrapper = new MediaElementWrapper(preparedElem)\r\n const writable = wrapper.createWriteStream(codecs)\r\n file.createReadStream().pipe(writable)\r\n\r\n if (currentTime) preparedElem.currentTime = currentTime\r\n\r\n return wrapper\r\n }\r\n\r\n function fallbackToMediaSource (useVP9 = false) {\r\n if (useVP9 === true) console.log('Falling back to media source with VP9 enabled.')\r\n else console.log('Falling back to media source..')\r\n\r\n useMediaSource(useVP9)\r\n }\r\n\r\n function prepareElem () {\r\n if (preparedElem === undefined) {\r\n preparedElem = elem\r\n\r\n preparedElem.addEventListener('progress', function () {\r\n currentTime = elem.currentTime\r\n })\r\n }\r\n }\r\n\r\n function onLoadStart () {\r\n preparedElem.removeEventListener('loadedmetadata', onLoadStart)\r\n\r\n\r\n if (opts.autoplay) preparedElem.play()\r\n\r\n callback(null, renderer)\r\n }\r\n}\r\n\r\nfunction validateFile (file: any) {\r\n if (file == null) {\r\n throw new Error('file cannot be null or undefined')\r\n }\r\n if (typeof file.name !== 'string') {\r\n throw new Error('missing or invalid file.name property')\r\n }\r\n if (typeof file.createReadStream !== 'function') {\r\n throw new Error('missing or invalid file.createReadStream property')\r\n }\r\n}\r\n\r\nfunction getCodec (name: string, useVP9 = false) {\r\n const ext = extname(name).toLowerCase()\r\n if (ext === '.mp4') {\r\n return 'video/mp4; codecs=\"avc1.640029, mp4a.40.5\"'\r\n }\r\n\r\n if (ext === '.webm') {\r\n if (useVP9 === true) return 'video/webm; codecs=\"vp9, opus\"'\r\n\r\n return 'video/webm; codecs=\"vp8, vorbis\"'\r\n }\r\n\r\n return undefined\r\n}\r\n\r\nexport {\r\n renderVideo\r\n}\r\n","import videojs from 'video.js'\r\nimport * as WebTorrent from 'webtorrent'\r\nimport { renderVideo } from './video-renderer'\r\nimport { LoadedQualityData, PlayerNetworkInfo, WebtorrentPluginOptions } from '../peertube-videojs-typings'\r\nimport { getRtcConfig, timeToInt, videoFileMaxByResolution, videoFileMinByResolution, isIOS, isSafari } from '../utils'\r\nimport { PeertubeChunkStore } from './peertube-chunk-store'\r\nimport {\r\n getAverageBandwidthInStore,\r\n getStoredMute,\r\n getStoredP2PEnabled,\r\n getStoredVolume,\r\n saveAverageBandwidth\r\n} from '../peertube-player-local-storage'\r\nimport { VideoFile } from '@shared/models'\r\n\r\nconst CacheChunkStore = require('cache-chunk-store')\r\n\r\ntype PlayOptions = {\r\n forcePlay?: boolean,\r\n seek?: number,\r\n delay?: number\r\n}\r\n\r\nconst Plugin = videojs.getPlugin('plugin')\r\n\r\nclass WebTorrentPlugin extends Plugin {\r\n readonly videoFiles: VideoFile[]\r\n\r\n private readonly playerElement: HTMLVideoElement\r\n\r\n private readonly autoplay: boolean = false\r\n private readonly startTime: number = 0\r\n private readonly savePlayerSrcFunction: videojs.Player['src']\r\n private readonly videoDuration: number\r\n private readonly CONSTANTS = {\r\n INFO_SCHEDULER: 1000, // Don't change this\r\n AUTO_QUALITY_SCHEDULER: 3000, // Check quality every 3 seconds\r\n AUTO_QUALITY_THRESHOLD_PERCENT: 30, // Bandwidth should be 30% more important than a resolution bitrate to change to it\r\n AUTO_QUALITY_OBSERVATION_TIME: 10000, // Wait 10 seconds after having change the resolution before another check\r\n AUTO_QUALITY_HIGHER_RESOLUTION_DELAY: 5000, // Buffering higher resolution during 5 seconds\r\n BANDWIDTH_AVERAGE_NUMBER_OF_VALUES: 5 // Last 5 seconds to build average bandwidth\r\n }\r\n\r\n private readonly webtorrent = new WebTorrent({\r\n tracker: {\r\n rtcConfig: getRtcConfig()\r\n },\r\n dht: false\r\n })\r\n\r\n private currentVideoFile: VideoFile\r\n private torrent: WebTorrent.Torrent\r\n\r\n private renderer: any\r\n private fakeRenderer: any\r\n private destroyingFakeRenderer = false\r\n\r\n private autoResolution = true\r\n private autoResolutionPossible = true\r\n private isAutoResolutionObservation = false\r\n private playerRefusedP2P = false\r\n\r\n private torrentInfoInterval: any\r\n private autoQualityInterval: any\r\n private addTorrentDelay: any\r\n private qualityObservationTimer: any\r\n private runAutoQualitySchedulerTimer: any\r\n\r\n private downloadSpeeds: number[] = []\r\n\r\n constructor (player: videojs.Player, options?: WebtorrentPluginOptions) {\r\n super(player)\r\n\r\n this.startTime = timeToInt(options.startTime)\r\n\r\n // Disable auto play on iOS\r\n this.autoplay = options.autoplay\r\n this.playerRefusedP2P = !getStoredP2PEnabled()\r\n\r\n this.videoFiles = options.videoFiles\r\n this.videoDuration = options.videoDuration\r\n\r\n this.savePlayerSrcFunction = this.player.src\r\n this.playerElement = options.playerElement\r\n\r\n this.player.ready(() => {\r\n const playerOptions = this.player.options_\r\n\r\n /*const volume = getStoredVolume()\r\n if (volume !== undefined) this.player.volume(volume)\r\n\r\n const muted = playerOptions.muted !== undefined ? playerOptions.muted : getStoredMute()\r\n if (muted !== undefined) this.player.muted(muted)*/\r\n\r\n this.player.duration(options.videoDuration)\r\n\r\n this.initializePlayer()\r\n this.runTorrentInfoScheduler()\r\n\r\n this.player.one('play', () => {\r\n // Don't run immediately scheduler, wait some seconds the TCP connections are made\r\n this.runAutoQualitySchedulerTimer = setTimeout(() => this.runAutoQualityScheduler(), this.CONSTANTS.AUTO_QUALITY_SCHEDULER)\r\n })\r\n })\r\n }\r\n\r\n dispose () {\r\n clearTimeout(this.addTorrentDelay)\r\n clearTimeout(this.qualityObservationTimer)\r\n clearTimeout(this.runAutoQualitySchedulerTimer)\r\n\r\n clearInterval(this.torrentInfoInterval)\r\n clearInterval(this.autoQualityInterval)\r\n\r\n // Don't need to destroy renderer, video player will be destroyed\r\n this.flushVideoFile(this.currentVideoFile, false)\r\n\r\n this.destroyFakeRenderer()\r\n }\r\n\r\n getCurrentResolutionId () {\r\n return this.currentVideoFile ? this.currentVideoFile.resolution.id : -1\r\n }\r\n\r\n updateVideoFile (\r\n videoFile?: VideoFile,\r\n options: {\r\n forcePlay?: boolean,\r\n seek?: number,\r\n delay?: number\r\n } = {},\r\n done: () => void = () => { /* empty */ }\r\n ) {\r\n // Automatically choose the adapted video file\r\n if (!videoFile) {\r\n const savedAverageBandwidth = getAverageBandwidthInStore()\r\n videoFile = savedAverageBandwidth\r\n ? this.getAppropriateFile(savedAverageBandwidth)\r\n : this.pickAverageVideoFile()\r\n }\r\n\r\n if (!videoFile) {\r\n \r\n throw Error(`Can't update video file since videoFile is undefined.`)\r\n\r\n /*\r\n\r\n const error: { message: string, code?: number } = {\r\n message: \"Can't update video file since videoFile is undefined.\"\r\n }\r\n\r\n this.player.tech(true).error = () => error as any\r\n this.player.tech(true).trigger('error')\r\n\r\n return\r\n\r\n\r\n */\r\n }\r\n\r\n // Don't add the same video file once again\r\n if (this.currentVideoFile !== undefined && this.currentVideoFile.magnetUri === videoFile.magnetUri) {\r\n return\r\n }\r\n\r\n // Do not display error to user because we will have multiple fallback\r\n this.disableErrorDisplay();\r\n\r\n // Hack to \"simulate\" src link in video.js >= 6\r\n // Without this, we can't play the video after pausing it\r\n // https://github.com/videojs/video.js/blob/master/src/js/player.js#L1633\r\n (this.player as any).src = () => true\r\n const oldPlaybackRate = this.player.playbackRate()\r\n\r\n const previousVideoFile = this.currentVideoFile\r\n this.currentVideoFile = videoFile\r\n\r\n // Don't try on iOS that does not support MediaSource\r\n // Or don't use P2P if webtorrent is disabled\r\n if (isIOS() || this.playerRefusedP2P) {\r\n return this.fallbackToHttp(options, () => {\r\n this.player.playbackRate(oldPlaybackRate)\r\n return done()\r\n })\r\n }\r\n\r\n\r\n this.addTorrent(this.currentVideoFile.magnetUri, previousVideoFile, options, () => {\r\n this.player.playbackRate(oldPlaybackRate)\r\n return done()\r\n })\r\n\r\n this.changeQuality()\r\n this.trigger('resolutionChange', { auto: this.autoResolution, resolutionId: this.currentVideoFile.resolution.id })\r\n }\r\n\r\n updateResolution (resolutionId: number, delay = 0) {\r\n // Remember player state\r\n const currentTime = this.player.currentTime()\r\n const isPaused = this.player.paused()\r\n\r\n // Hide bigPlayButton\r\n if (!isPaused) {\r\n this.player.bigPlayButton.hide()\r\n }\r\n\r\n // Audio-only (resolutionId === 0) gets special treatment\r\n if (resolutionId === 0) {\r\n // Audio-only: show poster, do not auto-hide controls\r\n this.player.addClass('vjs-playing-audio-only-content')\r\n this.player.posterImage.show()\r\n } else {\r\n // Hide poster to have black background\r\n this.player.removeClass('vjs-playing-audio-only-content')\r\n this.player.posterImage.hide()\r\n }\r\n\r\n const newVideoFile = this.videoFiles.find(f => f.resolution.id === resolutionId)\r\n const options = {\r\n forcePlay: false,\r\n delay,\r\n seek: currentTime + (delay / 1000)\r\n }\r\n\r\n this.updateVideoFile(newVideoFile, options)\r\n }\r\n\r\n flushVideoFile (videoFile: VideoFile, destroyRenderer = true) {\r\n if (videoFile !== undefined && this.webtorrent.get(videoFile.magnetUri)) {\r\n if (destroyRenderer === true && this.renderer && this.renderer.destroy) this.renderer.destroy()\r\n\r\n this.webtorrent.remove(videoFile.magnetUri)\r\n }\r\n }\r\n\r\n enableAutoResolution () {\r\n this.autoResolution = true\r\n this.trigger('resolutionChange', { auto: this.autoResolution, resolutionId: this.getCurrentResolutionId() })\r\n }\r\n\r\n disableAutoResolution (forbid = false) {\r\n if (forbid === true) this.autoResolutionPossible = false\r\n\r\n this.autoResolution = false\r\n this.trigger('autoResolutionChange', { possible: this.autoResolutionPossible })\r\n this.trigger('resolutionChange', { auto: this.autoResolution, resolutionId: this.getCurrentResolutionId() })\r\n }\r\n\r\n isAutoResolutionPossible () {\r\n return this.autoResolutionPossible\r\n }\r\n\r\n getTorrent () {\r\n return this.torrent\r\n }\r\n\r\n getCurrentVideoFile () {\r\n return this.currentVideoFile\r\n }\r\n\r\n private addTorrent (\r\n magnetOrTorrentUrl: string,\r\n previousVideoFile: VideoFile,\r\n options: PlayOptions,\r\n done: Function\r\n ) {\r\n if (!magnetOrTorrentUrl) return this.fallbackToHttp(options, done)\r\n\r\n const oldTorrent = this.torrent\r\n const torrentOptions = {\r\n // Don't use arrow function: it breaks webtorrent (that uses `new` keyword)\r\n store: function (chunkLength: number, storeOpts: any) {\r\n return new CacheChunkStore(new PeertubeChunkStore(chunkLength, storeOpts), {\r\n max: 100\r\n })\r\n }\r\n }\r\n\r\n this.torrent = this.webtorrent.add(magnetOrTorrentUrl, torrentOptions, torrent => {\r\n if (oldTorrent) {\r\n // Pause the old torrent\r\n this.stopTorrent(oldTorrent)\r\n\r\n // We use a fake renderer so we download correct pieces of the next file\r\n if(options.delay) \r\n this.renderFileInFakeElement(torrent.files[ 0 ], options.delay)\r\n }\r\n\r\n // Render the video in a few seconds? (on resolution change for example, we wait some seconds of the new video resolution)\r\n this.addTorrentDelay = setTimeout(() => {\r\n\r\n // We don't need the fake renderer anymore\r\n this.destroyFakeRenderer()\r\n\r\n const paused = this.player.paused()\r\n\r\n this.flushVideoFile(previousVideoFile)\r\n\r\n // Update progress bar (just for the UI), do not wait rendering\r\n if (options.seek) this.player.currentTime(options.seek)\r\n\r\n const renderVideoOptions = { autoplay: false, controls: true }\r\n renderVideo(torrent.files[ 0 ], this.playerElement, renderVideoOptions, (err, renderer) => {\r\n this.renderer = renderer\r\n\r\n if (err) return this.fallbackToHttp(options, done)\r\n\r\n //this.playerElement.play()\r\n\r\n setTimeout(() => {\r\n return this.tryToPlay(err => {\r\n\r\n if (err) return done(err)\r\n \r\n if (options.seek) this.seek(options.seek)\r\n if (options.forcePlay === false && paused === true) this.player.pause()\r\n \r\n return done()\r\n })\r\n }, 10)\r\n \r\n })\r\n }, options.delay || 0)\r\n })\r\n\r\n this.torrent.on('error', (err: any) => console.error(err))\r\n\r\n this.torrent.on('warning', (err: any) => {\r\n\r\n //// TEMP, TO DO\r\n\r\n /*if (err.message.indexOf('Error connecting to wss') !== -1 || err.message.indexOf('Unsupported tracker protocol') !== -1) {\r\n this.fallbackToHttp(options, done)\r\n return\r\n }*/\r\n\r\n // We don't support HTTP tracker but we don't care -> we use the web socket tracker\r\n if (err.message.indexOf('Unsupported tracker protocol') !== -1) return\r\n\r\n // Users don't care about issues with WebRTC, but developers do so log it in the console\r\n if (err.message.indexOf('Ice connection failed') !== -1) {\r\n console.log(err)\r\n return\r\n }\r\n\r\n // Magnet hash is not up to date with the torrent file, add directly the torrent file\r\n if (err.message.indexOf('incorrect info hash') !== -1) {\r\n console.error('Incorrect info hash detected, falling back to torrent file.')\r\n const newOptions = { forcePlay: true, seek: options.seek }\r\n return this.addTorrent(this.torrent[ 'xs' ], previousVideoFile, newOptions, done)\r\n }\r\n\r\n // Remote instance is down\r\n if (err.message.indexOf('from xs param') !== -1) {\r\n this.handleError(err)\r\n }\r\n\r\n })\r\n }\r\n\r\n private tryToPlay (done?: (err?: Error) => void) {\r\n\r\n if (!done) done = function () {}\r\n\r\n const playPromise = this.player.play()\r\n\r\n if (playPromise !== undefined) {\r\n\r\n return playPromise.then(() => done()).catch((err: Error) => {\r\n if (err.message.indexOf('The play() request') !== -1) {\r\n return\r\n }\r\n\r\n console.log(\"PAUSE\")\r\n this.player.pause()\r\n this.player.posterImage.show()\r\n this.player.removeClass('vjs-has-autoplay')\r\n this.player.removeClass('vjs-has-big-play-button-clicked')\r\n this.player.removeClass('vjs-playing-audio-only-content')\r\n\r\n return done()\r\n })\r\n }\r\n\r\n return done()\r\n\r\n \r\n }\r\n\r\n private seek (time: number) {\r\n this.player.currentTime(time)\r\n this.player.handleTechSeeked_()\r\n }\r\n\r\n private getAppropriateFile (averageDownloadSpeed?: number): VideoFile {\r\n if (this.videoFiles === undefined) return undefined\r\n\r\n const files = this.videoFiles.filter(f => f.resolution.id !== 0)\r\n\r\n if (files.length === 0) return undefined\r\n if (files.length === 1) return files[0]\r\n\r\n // Don't change the torrent if the player ended\r\n if (this.torrent && this.torrent.progress === 1 && this.player.ended()) return this.currentVideoFile\r\n\r\n if (!averageDownloadSpeed) averageDownloadSpeed = this.getAndSaveActualDownloadSpeed()\r\n\r\n // Limit resolution according to player height\r\n const playerHeight = this.playerElement.offsetHeight\r\n\r\n // We take the first resolution just above the player height\r\n // Example: player height is 530px, we want the 720p file instead of 480p\r\n let maxResolution = files[0].resolution.id\r\n for (let i = files.length - 1; i >= 0; i--) {\r\n const resolutionId = files[i].resolution.id\r\n if (resolutionId !== 0 && resolutionId >= playerHeight) {\r\n maxResolution = resolutionId\r\n break\r\n }\r\n }\r\n\r\n // Filter videos we can play according to our screen resolution and bandwidth\r\n const filteredFiles = files.filter(f => f.resolution.id <= maxResolution)\r\n .filter(f => {\r\n const fileBitrate = (f.size / this.videoDuration)\r\n let threshold = fileBitrate\r\n\r\n // If this is for a higher resolution or an initial load: add a margin\r\n if (!this.currentVideoFile || f.resolution.id > this.currentVideoFile.resolution.id) {\r\n threshold += ((fileBitrate * this.CONSTANTS.AUTO_QUALITY_THRESHOLD_PERCENT) / 100)\r\n }\r\n\r\n return averageDownloadSpeed > threshold\r\n })\r\n\r\n // If the download speed is too bad, return the lowest resolution we have\r\n if (filteredFiles.length === 0) return videoFileMinByResolution(files)\r\n\r\n return videoFileMaxByResolution(filteredFiles)\r\n }\r\n\r\n private getAndSaveActualDownloadSpeed () {\r\n const start = Math.max(this.downloadSpeeds.length - this.CONSTANTS.BANDWIDTH_AVERAGE_NUMBER_OF_VALUES, 0)\r\n const lastDownloadSpeeds = this.downloadSpeeds.slice(start, this.downloadSpeeds.length)\r\n if (lastDownloadSpeeds.length === 0) return -1\r\n\r\n const sum = lastDownloadSpeeds.reduce((a, b) => a + b)\r\n const averageBandwidth = Math.round(sum / lastDownloadSpeeds.length)\r\n\r\n // Save the average bandwidth for future use\r\n saveAverageBandwidth(averageBandwidth)\r\n\r\n return averageBandwidth\r\n }\r\n\r\n private initializePlayer () {\r\n this.buildQualities()\r\n\r\n if (this.autoplay) {\r\n this.player.posterImage.hide()\r\n\r\n return this.updateVideoFile(undefined, { forcePlay: true, seek: this.startTime })\r\n }\r\n\r\n // Proxy first play\r\n const oldPlay = this.player.play.bind(this.player);\r\n (this.player as any).play = () => {\r\n this.player.addClass('vjs-has-big-play-button-clicked')\r\n this.player.play = oldPlay\r\n\r\n this.updateVideoFile(undefined, { forcePlay: true, seek: this.startTime })\r\n }\r\n }\r\n\r\n private runAutoQualityScheduler () {\r\n this.autoQualityInterval = setInterval(() => {\r\n\r\n // Not initialized or in HTTP fallback\r\n if (this.torrent === undefined || this.torrent === null) return\r\n if (this.autoResolution === false) return\r\n if (this.isAutoResolutionObservation === true) return\r\n\r\n const file = this.getAppropriateFile()\r\n let changeResolution = false\r\n let changeResolutionDelay = 0\r\n\r\n // Lower resolution\r\n if (this.isPlayerWaiting() && file.resolution.id < this.currentVideoFile.resolution.id) {\r\n changeResolution = true\r\n } else if (file.resolution.id > this.currentVideoFile.resolution.id) { // Higher resolution\r\n changeResolution = true\r\n changeResolutionDelay = this.CONSTANTS.AUTO_QUALITY_HIGHER_RESOLUTION_DELAY\r\n }\r\n\r\n if (changeResolution === true) {\r\n this.updateResolution(file.resolution.id, changeResolutionDelay)\r\n\r\n // Wait some seconds in observation of our new resolution\r\n this.isAutoResolutionObservation = true\r\n\r\n this.qualityObservationTimer = setTimeout(() => {\r\n this.isAutoResolutionObservation = false\r\n }, this.CONSTANTS.AUTO_QUALITY_OBSERVATION_TIME)\r\n }\r\n }, this.CONSTANTS.AUTO_QUALITY_SCHEDULER)\r\n }\r\n\r\n private isPlayerWaiting () {\r\n return this.player && this.player.hasClass('vjs-waiting')\r\n }\r\n\r\n private runTorrentInfoScheduler () {\r\n this.torrentInfoInterval = setInterval(() => {\r\n \r\n\r\n // Not initialized yet\r\n if (this.torrent === undefined) return\r\n\r\n // Http fallback\r\n if (this.torrent === null) return this.player.trigger('p2pInfo', false)\r\n\r\n // this.webtorrent.downloadSpeed because we need to take into account the potential old torrent too\r\n if (this.webtorrent.downloadSpeed !== 0) this.downloadSpeeds.push(this.webtorrent.downloadSpeed)\r\n\r\n \r\n\r\n return this.player.trigger('p2pInfo', {\r\n source: 'webtorrent',\r\n http: {\r\n downloadSpeed: 0,\r\n uploadSpeed: 0,\r\n downloaded: 0,\r\n uploaded: 0\r\n },\r\n p2p: {\r\n downloadSpeed: this.torrent.downloadSpeed,\r\n numPeers: this.torrent.numPeers,\r\n uploadSpeed: this.torrent.uploadSpeed,\r\n downloaded: this.torrent.downloaded,\r\n uploaded: this.torrent.uploaded\r\n }\r\n } as PlayerNetworkInfo)\r\n }, this.CONSTANTS.INFO_SCHEDULER)\r\n }\r\n\r\n private fallbackToHttp (options: PlayOptions, done?: Function) {\r\n\r\n\r\n const paused = this.player.paused()\r\n\r\n this.disableAutoResolution(true)\r\n\r\n this.flushVideoFile(this.currentVideoFile, true)\r\n this.torrent = null\r\n\r\n // Enable error display now this is our last fallback\r\n this.player.one('error', () => this.enableErrorDisplay())\r\n\r\n const httpUrl = this.currentVideoFile.fileUrl\r\n this.player.src = this.savePlayerSrcFunction\r\n this.player.src(httpUrl)\r\n\r\n this.changeQuality()\r\n\r\n // We changed the source, so reinit captions\r\n this.player.trigger('sourcechange')\r\n\r\n return this.tryToPlay(err => {\r\n\r\n if (err && done) return done(err)\r\n\r\n if (options.seek) this.seek(options.seek)\r\n if (options.forcePlay === false && paused === true) {\r\n console.log(\"PLAUSE\")\r\n this.player.pause()\r\n }\r\n\r\n if (done) return done()\r\n })\r\n }\r\n\r\n private handleError (err: Error | string) {\r\n return this.player.trigger('customError', { err })\r\n }\r\n\r\n private enableErrorDisplay () {\r\n this.player.addClass('vjs-error-display-enabled')\r\n }\r\n\r\n private disableErrorDisplay () {\r\n this.player.removeClass('vjs-error-display-enabled')\r\n }\r\n\r\n private pickAverageVideoFile () {\r\n if (this.videoFiles.length === 1) return this.videoFiles[0]\r\n\r\n return this.videoFiles[Math.floor(this.videoFiles.length / 2)]\r\n }\r\n\r\n private stopTorrent (torrent: WebTorrent.Torrent) {\r\n torrent.pause()\r\n // Pause does not remove actual peers (in particular the webseed peer)\r\n torrent.removePeer(torrent[ 'ws' ])\r\n }\r\n\r\n private renderFileInFakeElement (file: WebTorrent.TorrentFile, delay: number) {\r\n this.destroyingFakeRenderer = false\r\n\r\n const fakeVideoElem = document.createElement('video')\r\n renderVideo(file, fakeVideoElem, { autoplay: false, controls: false }, (err, renderer) => {\r\n this.fakeRenderer = renderer\r\n\r\n // The renderer returns an error when we destroy it, so skip them\r\n if (this.destroyingFakeRenderer === false && err) {\r\n console.error('Cannot render new torrent in fake video element.', err)\r\n }\r\n\r\n // Load the future file at the correct time (in delay MS - 2 seconds)\r\n fakeVideoElem.currentTime = this.player.currentTime() + (delay - 2000)\r\n })\r\n }\r\n\r\n private destroyFakeRenderer () {\r\n if (this.fakeRenderer) {\r\n this.destroyingFakeRenderer = true\r\n\r\n if (this.fakeRenderer.destroy) {\r\n try {\r\n this.fakeRenderer.destroy()\r\n } catch (err) {\r\n console.log('Cannot destroy correctly fake renderer.', err)\r\n }\r\n }\r\n this.fakeRenderer = undefined\r\n }\r\n }\r\n\r\n private buildQualities () {\r\n const qualityLevelsPayload = []\r\n\r\n for (const file of this.videoFiles) {\r\n const representation = {\r\n id: file.resolution.id,\r\n label: this.buildQualityLabel(file),\r\n height: file.resolution.id,\r\n _enabled: true\r\n }\r\n\r\n this.player.qualityLevels().addQualityLevel(representation)\r\n\r\n qualityLevelsPayload.push({\r\n id: representation.id,\r\n label: representation.label,\r\n selected: false\r\n })\r\n }\r\n\r\n const payload: LoadedQualityData = {\r\n qualitySwitchCallback: (d: any) => this.qualitySwitchCallback(d),\r\n qualityData: {\r\n video: qualityLevelsPayload\r\n }\r\n }\r\n this.player.tech(true).trigger('loadedqualitydata', payload)\r\n }\r\n\r\n private buildQualityLabel (file: VideoFile) {\r\n let label = file.resolution.label\r\n\r\n if (file.fps && file.fps >= 50) {\r\n label += file.fps\r\n }\r\n\r\n return label\r\n }\r\n\r\n private qualitySwitchCallback (id: number) {\r\n if (id === -1) {\r\n if (this.autoResolutionPossible === true) this.enableAutoResolution()\r\n return\r\n }\r\n\r\n this.disableAutoResolution()\r\n this.updateResolution(id)\r\n }\r\n\r\n private changeQuality () {\r\n const resolutionId = this.currentVideoFile.resolution.id\r\n const qualityLevels = this.player.qualityLevels()\r\n\r\n if (resolutionId === -1) {\r\n qualityLevels.selectedIndex = -1\r\n return\r\n }\r\n\r\n for (let i = 0; i < qualityLevels.length; i++) {\r\n const q = qualityLevels[i]\r\n if (q.height === resolutionId) qualityLevels.selectedIndex_ = i\r\n }\r\n }\r\n}\r\n\r\nvideojs.registerPlugin('webtorrent', WebTorrentPlugin)\r\nexport { WebTorrentPlugin }\r\n","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */","/* (ignored) */"],"sourceRoot":""}