Correctly implement p2p-media-loader
authorChocobozzz <me@florianbigard.com>
Thu, 24 Jan 2019 09:16:30 +0000 (10:16 +0100)
committerChocobozzz <chocobozzz@cpy.re>
Mon, 11 Feb 2019 08:13:02 +0000 (09:13 +0100)
12 files changed:
client/package.json
client/src/assets/player/p2p-media-loader-plugin.ts
client/src/assets/player/peertube-player-manager.ts
client/src/assets/player/peertube-plugin.ts
client/src/assets/player/peertube-videojs-typings.ts
client/src/assets/player/videojs-components/p2p-info-button.ts
client/src/assets/player/videojs-components/resolution-menu-button.ts
client/src/assets/player/videojs-components/resolution-menu-item.ts
client/src/assets/player/videojs-components/settings-menu-item.ts
client/src/assets/player/webtorrent-plugin.ts
client/src/standalone/videos/embed.ts
client/yarn.lock

index 9da7c102575211bd4a42d6dad5d3de56d678817e..a455653fe4a3e8be6a8aaa6ce25913978a623a49 100644 (file)
@@ -87,6 +87,7 @@
     "@ngx-translate/i18n-polyfill": "^1.0.0",
     "@streamroot/videojs-hlsjs-plugin": "^1.0.7",
     "@types/core-js": "^2.5.0",
+    "@types/hls.js": "^0.12.0",
     "@types/jasmine": "^2.8.7",
     "@types/jasminewd2": "^2.0.3",
     "@types/jest": "^23.3.1",
     "extract-text-webpack-plugin": "4.0.0-beta.0",
     "file-loader": "^2.0.0",
     "focus-visible": "^4.1.5",
+    "hls.js": "^0.12.2",
     "html-loader": "^0.5.5",
     "html-webpack-plugin": "^3.2.0",
     "https-browserify": "^1.0.0",
index 6d07a2c9ccb1944e726b42caa46534e5b36f3193..25117e51e4a5ae63ca1d5132d70ce063e7aab786 100644 (file)
@@ -1,25 +1,45 @@
 // FIXME: something weird with our path definition in tsconfig and typings
 // @ts-ignore
 import * as videojs from 'video.js'
-import { P2PMediaLoaderPluginOptions, VideoJSComponentInterface } from './peertube-videojs-typings'
+import { P2PMediaLoaderPluginOptions, PlayerNetworkInfo, VideoJSComponentInterface } from './peertube-videojs-typings'
 
 // videojs-hlsjs-plugin needs videojs in window
 window['videojs'] = videojs
 import '@streamroot/videojs-hlsjs-plugin'
 
-import { initVideoJsContribHlsJsPlayer } from 'p2p-media-loader-hlsjs'
-
-// import { Events } from '../p2p-media-loader/p2p-media-loader-core/lib'
+import { Engine, initVideoJsContribHlsJsPlayer } from 'p2p-media-loader-hlsjs'
+import * as Hls from 'hls.js'
+import { Events } from 'p2p-media-loader-core'
 
 const Plugin: VideoJSComponentInterface = videojs.getPlugin('plugin')
 class P2pMediaLoaderPlugin extends Plugin {
 
+  private readonly CONSTANTS = {
+    INFO_SCHEDULER: 1000 // Don't change this
+  }
+
+  private hlsjs: Hls
+  private p2pEngine: Engine
+  private statsP2PBytes = {
+    pendingDownload: [] as number[],
+    pendingUpload: [] as number[],
+    numPeers: 0,
+    totalDownload: 0,
+    totalUpload: 0
+  }
+
+  private networkInfoInterval: any
+
   constructor (player: videojs.Player, options: P2PMediaLoaderPluginOptions) {
     super(player, options)
 
-    initVideoJsContribHlsJsPlayer(player)
+    videojs.Html5Hlsjs.addHook('beforeinitialize', (videojsPlayer: any, hlsjs: Hls) => {
+      this.hlsjs = hlsjs
 
-    console.log(options)
+      this.initialize()
+    })
+
+    initVideoJsContribHlsJsPlayer(player)
 
     player.src({
       type: options.type,
@@ -27,6 +47,56 @@ class P2pMediaLoaderPlugin extends Plugin {
     })
   }
 
+  dispose () {
+    clearInterval(this.networkInfoInterval)
+  }
+
+  private initialize () {
+    this.p2pEngine = this.player.tech_.options_.hlsjsConfig.loader.getEngine()
+
+    this.hlsjs.on(Hls.Events.LEVEL_SWITCHING, (_, data: Hls.levelSwitchingData) => {
+      this.trigger('resolutionChange', { auto: this.hlsjs.autoLevelEnabled, resolutionId: data.height })
+    })
+
+    this.runStats()
+  }
+
+  private runStats () {
+    this.p2pEngine.on(Events.PieceBytesDownloaded, (method: string, size: number) => {
+      if (method === 'p2p') {
+        this.statsP2PBytes.pendingDownload.push(size)
+        this.statsP2PBytes.totalDownload += size
+      }
+    })
+
+    this.p2pEngine.on(Events.PieceBytesUploaded, (method: string, size: number) => {
+      if (method === 'p2p') {
+        this.statsP2PBytes.pendingUpload.push(size)
+        this.statsP2PBytes.totalUpload += size
+      }
+    })
+
+    this.p2pEngine.on(Events.PeerConnect, () => this.statsP2PBytes.numPeers++)
+    this.p2pEngine.on(Events.PeerClose, () => this.statsP2PBytes.numPeers--)
+
+    this.networkInfoInterval = setInterval(() => {
+      let downloadSpeed = this.statsP2PBytes.pendingDownload.reduce((a: number, b: number) => a + b, 0)
+      let uploadSpeed = this.statsP2PBytes.pendingUpload.reduce((a: number, b: number) => a + b, 0)
+
+      this.statsP2PBytes.pendingDownload = []
+      this.statsP2PBytes.pendingUpload = []
+
+      return this.player.trigger('p2pInfo', {
+        p2p: {
+          downloadSpeed,
+          uploadSpeed,
+          numPeers: this.statsP2PBytes.numPeers,
+          downloaded: this.statsP2PBytes.totalDownload,
+          uploaded: this.statsP2PBytes.totalUpload
+        }
+      } as PlayerNetworkInfo)
+    }, this.CONSTANTS.INFO_SCHEDULER)
+  }
 }
 
 videojs.registerPlugin('p2pMediaLoader', P2pMediaLoaderPlugin)
index 9155c0698f841b4ed86e6e1f8b47367050fe5990..2e090847ccba2a0355ae824eb85e00ba041dde5b 100644 (file)
@@ -24,17 +24,17 @@ videojsUntyped.getComponent('CaptionsButton').prototype.controlText_ = 'Subtitle
 // We just want to display 'Off' instead of 'captions off', keep a space so the variable == true (hacky I know)
 videojsUntyped.getComponent('CaptionsButton').prototype.label_ = ' '
 
-type PlayerMode = 'webtorrent' | 'p2p-media-loader'
+export type PlayerMode = 'webtorrent' | 'p2p-media-loader'
 
-type WebtorrentOptions = {
+export type WebtorrentOptions = {
   videoFiles: VideoFile[]
 }
 
-type P2PMediaLoaderOptions = {
+export type P2PMediaLoaderOptions = {
   playlistUrl: string
 }
 
-type CommonOptions = {
+export type CommonOptions = {
   playerElement: HTMLVideoElement
 
   autoplay: boolean
@@ -137,6 +137,7 @@ export class PeertubePlayerManager {
     const commonOptions = options.common
     const webtorrentOptions = options.webtorrent
     const p2pMediaLoaderOptions = options.p2pMediaLoader
+    let html5 = {}
 
     const plugins: VideoJSPluginOptions = {
       peertube: {
@@ -171,6 +172,7 @@ export class PeertubePlayerManager {
       }
 
       Object.assign(plugins, { p2pMediaLoader, streamrootHls })
+      html5 = streamrootHls.html5
     }
 
     if (webtorrentOptions) {
@@ -184,6 +186,8 @@ export class PeertubePlayerManager {
     }
 
     const videojsOptions = {
+      html5,
+
       // We don't use text track settings for now
       textTrackSettings: false,
       controls: commonOptions.controls !== undefined ? commonOptions.controls : true,
index 0bd607697fc43cc8b6f263b18aa028ede7ad0b3b..f83d9094a40124763806a493aa8306859e8bcc33 100644 (file)
@@ -2,7 +2,14 @@
 // @ts-ignore
 import * as videojs from 'video.js'
 import './videojs-components/settings-menu-button'
-import { PeerTubePluginOptions, UserWatching, VideoJSCaption, VideoJSComponentInterface, videojsUntyped } from './peertube-videojs-typings'
+import {
+  PeerTubePluginOptions,
+  ResolutionUpdateData,
+  UserWatching,
+  VideoJSCaption,
+  VideoJSComponentInterface,
+  videojsUntyped
+} from './peertube-videojs-typings'
 import { isMobile, timeToInt } from './utils'
 import {
   getStoredLastSubtitle,
@@ -30,6 +37,7 @@ class PeerTubePlugin extends Plugin {
   private videoViewInterval: any
   private userWatchingVideoInterval: any
   private qualityObservationTimer: any
+  private lastResolutionChange: ResolutionUpdateData
 
   constructor (player: videojs.Player, options: PeerTubePluginOptions) {
     super(player, options)
@@ -44,6 +52,22 @@ class PeerTubePlugin extends Plugin {
     this.player.ready(() => {
       const playerOptions = this.player.options_
 
+      if (this.player.webtorrent) {
+        this.player.webtorrent().on('resolutionChange', (_: any, d: any) => this.handleResolutionChange(d))
+        this.player.webtorrent().on('autoResolutionChange', (_: any, d: any) => this.trigger('autoResolutionChange', d))
+      }
+
+      if (this.player.p2pMediaLoader) {
+        this.player.p2pMediaLoader().on('resolutionChange', (_: any, d: any) => this.handleResolutionChange(d))
+      }
+
+      this.player.tech_.on('loadedqualitydata', () => {
+        setTimeout(() => {
+          // Replay a resolution change, now we loaded all quality data
+          if (this.lastResolutionChange) this.handleResolutionChange(this.lastResolutionChange)
+        }, 0)
+      })
+
       const volume = getStoredVolume()
       if (volume !== undefined) this.player.volume(volume)
 
@@ -158,6 +182,21 @@ class PeerTubePlugin extends Plugin {
     return fetch(url, { method: 'PUT', body, headers })
   }
 
+  private handleResolutionChange (data: ResolutionUpdateData) {
+    this.lastResolutionChange = data
+
+    const qualityLevels = this.player.qualityLevels()
+
+    for (let i = 0; i < qualityLevels.length; i++) {
+      if (qualityLevels[i].height === data.resolutionId) {
+        data.id = qualityLevels[i].id
+        break
+      }
+    }
+
+    this.trigger('resolutionChange', data)
+  }
+
   private alterInactivity () {
     let saveInactivityTimeout: number
 
index 060ea4dce4d49f96de16ed4d4cb0794e19befc4e..fff992a6f37985a42ea3389aa76760fc145d6eaa 100644 (file)
@@ -83,13 +83,25 @@ type LoadedQualityData = {
 type ResolutionUpdateData = {
   auto: boolean,
   resolutionId: number
+  id?: number
 }
 
 type AutoResolutionUpdateData = {
   possible: boolean
 }
 
+type PlayerNetworkInfo = {
+  p2p: {
+    downloadSpeed: number
+    uploadSpeed: number
+    downloaded: number
+    uploaded: number
+    numPeers: number
+  }
+}
+
 export {
+  PlayerNetworkInfo,
   ResolutionUpdateData,
   AutoResolutionUpdateData,
   VideoJSComponentInterface,
index 03a5d29f0b7dacbe4d9be759da7ed088a09d1cd2..2fc4c456207a8c61e539175af88df184ea568234 100644 (file)
@@ -1,4 +1,4 @@
-import { VideoJSComponentInterface, videojsUntyped } from '../peertube-videojs-typings'
+import { PlayerNetworkInfo, VideoJSComponentInterface, videojsUntyped } from '../peertube-videojs-typings'
 import { bytes } from '../utils'
 
 const Button: VideoJSComponentInterface = videojsUntyped.getComponent('Button')
@@ -65,7 +65,7 @@ class P2pInfoButton extends Button {
     subDivHttp.appendChild(subDivHttpText)
     div.appendChild(subDivHttp)
 
-    this.player_.on('p2pInfo', (event: any, data: any) => {
+    this.player_.on('p2pInfo', (event: any, data: PlayerNetworkInfo) => {
       // We are in HTTP fallback
       if (!data) {
         subDivHttp.className = 'vjs-peertube-displayed'
@@ -74,11 +74,13 @@ class P2pInfoButton extends Button {
         return
       }
 
-      const downloadSpeed = bytes(data.downloadSpeed)
-      const uploadSpeed = bytes(data.uploadSpeed)
-      const totalDownloaded = bytes(data.downloaded)
-      const totalUploaded = bytes(data.uploaded)
-      const numPeers = data.numPeers
+      const p2pStats = data.p2p
+
+      const downloadSpeed = bytes(p2pStats.downloadSpeed)
+      const uploadSpeed = bytes(p2pStats.uploadSpeed)
+      const totalDownloaded = bytes(p2pStats.downloaded)
+      const totalUploaded = bytes(p2pStats.uploaded)
+      const numPeers = p2pStats.numPeers
 
       subDivWebtorrent.title = this.player_.localize('Total downloaded: ') + totalDownloaded.join(' ') + '\n' +
         this.player_.localize('Total uploaded: ' + totalUploaded.join(' '))
index 2847de4709d92601f43beaaa56e6dcbde5edadcb..abcc16411df0b7727d821947b515316cd074137e 100644 (file)
@@ -14,11 +14,9 @@ class ResolutionMenuButton extends MenuButton {
     super(player, options)
     this.player = player
 
-    player.on('loadedqualitydata', (e: any, data: any) => this.buildQualities(data))
+    player.tech_.on('loadedqualitydata', (e: any, data: any) => this.buildQualities(data))
 
-    if (player.webtorrent) {
-      player.webtorrent().on('videoFileUpdate', () => setTimeout(() => this.trigger('updateLabel'), 0))
-    }
+    player.peertube().on('resolutionChange', () => setTimeout(() => this.trigger('updateLabel'), 0))
   }
 
   createEl () {
@@ -49,11 +47,32 @@ class ResolutionMenuButton extends MenuButton {
     return 'vjs-resolution-control ' + super.buildWrapperCSSClass()
   }
 
+  private addClickListener (component: any) {
+    component.on('click', () => {
+      let children = this.menu.children()
+
+      for (const child of children) {
+        if (component !== child) {
+          child.selected(false)
+        }
+      }
+    })
+  }
+
   private buildQualities (data: LoadedQualityData) {
     // The automatic resolution item will need other labels
     const labels: { [ id: number ]: string } = {}
 
+    data.qualityData.video.sort((a, b) => {
+      if (a.id > b.id) return -1
+      if (a.id === b.id) return 0
+      return 1
+    })
+
     for (const d of data.qualityData.video) {
+      // Skip auto resolution, we'll add it ourselves
+      if (d.id === -1) continue
+
       this.menu.addChild(new ResolutionMenuItem(
         this.player_,
         {
@@ -77,6 +96,12 @@ class ResolutionMenuButton extends MenuButton {
         selected: true // By default, in auto mode
       }
     ))
+
+    for (const m of this.menu.children()) {
+      this.addClickListener(m)
+    }
+
+    this.trigger('menuChanged')
   }
 }
 ResolutionMenuButton.prototype.controlText_ = 'Quality'
index cc1c797395b3725d29b750be694e2aa1cbb6271d..6c42fefd2f1eb60109c9e4ada9ac44ac1ee413e3 100644 (file)
@@ -28,16 +28,12 @@ class ResolutionMenuItem extends MenuItem {
     this.id = options.id
     this.callback = options.callback
 
-    if (player.webtorrent) {
-      player.webtorrent().on('videoFileUpdate', (_: any, data: ResolutionUpdateData) => this.updateSelection(data))
+    player.peertube().on('resolutionChange', (_: any, data: ResolutionUpdateData) => this.updateSelection(data))
 
-      // We only want to disable the "Auto" item
-      if (this.id === -1) {
-        player.webtorrent().on('autoResolutionUpdate', (_: any, data: AutoResolutionUpdateData) => this.updateAutoResolution(data))
-      }
+    // We only want to disable the "Auto" item
+    if (this.id === -1) {
+      player.peertube().on('autoResolutionChange', (_: any, data: AutoResolutionUpdateData) => this.updateAutoResolution(data))
     }
-
-    // TODO: update on HLS change
   }
 
   handleClick (event: any) {
@@ -46,12 +42,12 @@ class ResolutionMenuItem extends MenuItem {
 
     super.handleClick(event)
 
-    this.callback(this.id)
+    this.callback(this.id, 'video')
   }
 
   updateSelection (data: ResolutionUpdateData) {
     if (this.id === -1) {
-      this.currentResolutionLabel = this.labels[data.resolutionId]
+      this.currentResolutionLabel = this.labels[data.id]
     }
 
     // Automatic resolution only
@@ -60,7 +56,7 @@ class ResolutionMenuItem extends MenuItem {
       return
     }
 
-    this.selected(this.id === data.resolutionId)
+    this.selected(this.id === data.id)
   }
 
   updateAutoResolution (data: AutoResolutionUpdateData) {
index b9a4302900e2a13a032624ad0fe5c41251a50fba..f14959f9cf4e0b958933cd0ff9e7fd3d63364796 100644 (file)
@@ -223,6 +223,11 @@ class SettingsMenuItem extends MenuItem {
     this.subMenu.on('updateLabel', () => {
       this.update()
     })
+    this.subMenu.on('menuChanged', () => {
+      this.bindClickEvents()
+      this.setSize()
+      this.update()
+    })
 
     this.settingsSubMenuTitleEl_.innerHTML = this.player_.localize(this.subMenu.controlText_)
     this.settingsSubMenuEl_.appendChild(this.subMenu.menu.el_)
@@ -230,7 +235,7 @@ class SettingsMenuItem extends MenuItem {
     this.update()
 
     this.createBackButton()
-    this.getSize()
+    this.setSize()
     this.bindClickEvents()
 
     // prefixed event listeners for CSS TransitionEnd
@@ -292,8 +297,9 @@ class SettingsMenuItem extends MenuItem {
 
   // save size of submenus on first init
   // if number of submenu items change dynamically more logic will be needed
-  getSize () {
+  setSize () {
     this.dialog.removeClass('vjs-hidden')
+    videojsUntyped.dom.removeClass(this.settingsSubMenuEl_, 'vjs-hidden')
     this.size = this.settingsButton.getComponentSize(this.settingsSubMenuEl_)
     this.setMargin()
     this.dialog.addClass('vjs-hidden')
index c3d990aed6697e03d9a03776156bdfe2c7ebc46d..47f169e24d1f7c802f9ed945bc4800e48027f8f8 100644 (file)
@@ -5,7 +5,7 @@ import * as videojs from 'video.js'
 import * as WebTorrent from 'webtorrent'
 import { VideoFile } from '../../../../shared/models/videos/video.model'
 import { renderVideo } from './webtorrent/video-renderer'
-import { LoadedQualityData, VideoJSComponentInterface, WebtorrentPluginOptions } from './peertube-videojs-typings'
+import { LoadedQualityData, PlayerNetworkInfo, VideoJSComponentInterface, WebtorrentPluginOptions } from './peertube-videojs-typings'
 import { videoFileMaxByResolution, videoFileMinByResolution } from './utils'
 import { PeertubeChunkStore } from './webtorrent/peertube-chunk-store'
 import {
@@ -180,7 +180,7 @@ class WebTorrentPlugin extends Plugin {
     })
 
     this.changeQuality()
-    this.trigger('videoFileUpdate', { auto: this.autoResolution, resolutionId: this.currentVideoFile.resolution.id })
+    this.trigger('resolutionChange', { auto: this.autoResolution, resolutionId: this.currentVideoFile.resolution.id })
   }
 
   updateResolution (resolutionId: number, delay = 0) {
@@ -216,15 +216,15 @@ class WebTorrentPlugin extends Plugin {
 
   enableAutoResolution () {
     this.autoResolution = true
-    this.trigger('videoFileUpdate', { auto: this.autoResolution, resolutionId: this.getCurrentResolutionId() })
+    this.trigger('resolutionChange', { auto: this.autoResolution, resolutionId: this.getCurrentResolutionId() })
   }
 
   disableAutoResolution (forbid = false) {
     if (forbid === true) this.autoResolutionPossible = false
 
     this.autoResolution = false
-    this.trigger('autoResolutionUpdate', { possible: this.autoResolutionPossible })
-    this.trigger('videoFileUpdate', { auto: this.autoResolution, resolutionId: this.getCurrentResolutionId() })
+    this.trigger('autoResolutionChange', { possible: this.autoResolutionPossible })
+    this.trigger('resolutionChange', { auto: this.autoResolution, resolutionId: this.getCurrentResolutionId() })
   }
 
   getTorrent () {
@@ -472,12 +472,14 @@ class WebTorrentPlugin extends Plugin {
       if (this.webtorrent.downloadSpeed !== 0) this.downloadSpeeds.push(this.webtorrent.downloadSpeed)
 
       return this.player.trigger('p2pInfo', {
-        downloadSpeed: this.torrent.downloadSpeed,
-        numPeers: this.torrent.numPeers,
-        uploadSpeed: this.torrent.uploadSpeed,
-        downloaded: this.torrent.downloaded,
-        uploaded: this.torrent.uploaded
-      })
+        p2p: {
+          downloadSpeed: this.torrent.downloadSpeed,
+          numPeers: this.torrent.numPeers,
+          uploadSpeed: this.torrent.uploadSpeed,
+          downloaded: this.torrent.downloaded,
+          uploaded: this.torrent.uploaded
+        }
+      } as PlayerNetworkInfo)
     }, this.CONSTANTS.INFO_SCHEDULER)
   }
 
@@ -597,7 +599,7 @@ class WebTorrentPlugin extends Plugin {
         video: qualityLevelsPayload
       }
     }
-    this.player.trigger('loadedqualitydata', payload)
+    this.player.tech_.trigger('loadedqualitydata', payload)
   }
 
   private buildQualityLabel (file: VideoFile) {
index b1261c4a2e08d88455523a4dd3fe61852519f44b..0d165ea7b10631582cd84d6fb029089ccbded3b7 100644 (file)
@@ -23,7 +23,7 @@ import { peertubeTranslate, ResultList, VideoDetails } from '../../../../shared'
 import { PeerTubeResolution } from '../player/definitions'
 import { VideoJSCaption } from '../../assets/player/peertube-videojs-typings'
 import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model'
-import { PeertubePlayerManager, PeertubePlayerManagerOptions } from '../../assets/player/peertube-player-manager'
+import { PeertubePlayerManager, PeertubePlayerManagerOptions, PlayerMode } from '../../assets/player/peertube-player-manager'
 
 /**
  * Embed API exposes control of the embed player to the outside world via
@@ -162,6 +162,7 @@ class PeerTubeEmbed {
   subtitle: string
   enableApi = false
   startTime: number | string = 0
+  mode: PlayerMode
   scope = 'peertube'
 
   static async main () {
@@ -255,6 +256,8 @@ class PeerTubeEmbed {
       this.scope = this.getParamString(params, 'scope', this.scope)
       this.subtitle = this.getParamString(params, 'subtitle')
       this.startTime = this.getParamString(params, 'start')
+
+      this.mode = this.getParamToggle(params, 'p2p-media-loader') ? 'p2p-media-loader' : 'webtorrent'
     } catch (err) {
       console.error('Cannot get params from URL.', err)
     }
@@ -312,20 +315,26 @@ class PeerTubeEmbed {
         serverUrl: window.location.origin,
         language: navigator.language,
         embedUrl: window.location.origin + videoInfo.embedPath
-      },
-
-      webtorrent: {
-        videoFiles: videoInfo.files
       }
+    }
 
-      // p2pMediaLoader: {
-      //   // playlistUrl: 'https://akamai-axtest.akamaized.net/routes/lapd-v1-acceptance/www_c4/Manifest.m3u8'
-      //   // playlistUrl: 'https://d2zihajmogu5jn.cloudfront.net/bipbop-advanced/bipbop_16x9_variant.m3u8'
-      //   playlistUrl: 'https://cdn.theoplayer.com/video/elephants-dream/playlist.m3u8'
-      // }
+    if (this.mode === 'p2p-media-loader') {
+      Object.assign(options, {
+        p2pMediaLoader: {
+          // playlistUrl: 'https://akamai-axtest.akamaized.net/routes/lapd-v1-acceptance/www_c4/Manifest.m3u8'
+          // playlistUrl: 'https://d2zihajmogu5jn.cloudfront.net/bipbop-advanced/bipbop_16x9_variant.m3u8'
+          playlistUrl: 'https://cdn.theoplayer.com/video/elephants-dream/playlist.m3u8'
+        }
+      })
+    } else {
+      Object.assign(options, {
+        webtorrent: {
+          videoFiles: videoInfo.files
+        }
+      })
     }
 
-    this.player = await PeertubePlayerManager.initialize('webtorrent', options)
+    this.player = await PeertubePlayerManager.initialize(this.mode, options)
 
     this.player.on('customError', (event: any, data: any) => this.handleError(data.err, serverTranslations))
 
index 0698ca501c4654aa18a0f6e079082483cb163fa0..ced35688f80a736a12f7ead23066119daf9b0f28 100644 (file)
   resolved "https://registry.yarnpkg.com/@types/core-js/-/core-js-2.5.0.tgz#35cc282488de6f10af1d92902899a3b8ca3fbc47"
   integrity sha512-qjkHL3wF0JMHMqgm/kmL8Pf8rIiqvueEiZ0g6NVTcBX1WN46GWDr+V5z+gsHUeL0n8TfAmXnYmF7ajsxmBp4PQ==
 
+"@types/hls.js@^0.12.0":
+  version "0.12.0"
+  resolved "https://registry.yarnpkg.com/@types/hls.js/-/hls.js-0.12.0.tgz#33f73e542201a766fa56792cb81fe9f97d7097ed"
+  integrity sha512-hJ7eJAQVEazAANK4Ay0YbXlZF36SDy9c8kcHTF7//77ylgV6hV/JrlwhVmobsSacr5aZcbw5MbZ2bSHbS36eOQ==
+
 "@types/jasmine@*":
   version "3.3.1"
   resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.3.1.tgz#b6c4f356013364e98b583647c7b3b6de6fccd2cc"
@@ -3300,7 +3305,7 @@ etag@~1.8.1:
   resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
   integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
 
-eventemitter3@^3.0.0:
+eventemitter3@3.1.0, eventemitter3@^3.0.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163"
   integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==
@@ -4236,6 +4241,14 @@ he@1.2.x:
   resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
   integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
 
+hls.js@^0.12.2:
+  version "0.12.2"
+  resolved "https://registry.yarnpkg.com/hls.js/-/hls.js-0.12.2.tgz#64a969a78cc25991ed5de19357b1dc3f178ac23b"
+  integrity sha512-lQBSXggw9OzEuaUllUBoSxPcf7neFgnEiDRfCdCNdIPtUeV7vXZ0OeASx6EWtZTBiqSSPigoOX1Y+AR5dA1Feg==
+  dependencies:
+    eventemitter3 "3.1.0"
+    url-toolkit "^2.1.6"
+
 hmac-drbg@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
@@ -9976,7 +9989,7 @@ url-parse@^1.4.3:
     querystringify "^2.0.0"
     requires-port "^1.0.0"
 
-url-toolkit@^2.1.1, url-toolkit@^2.1.3:
+url-toolkit@^2.1.1, url-toolkit@^2.1.3, url-toolkit@^2.1.6:
   version "2.1.6"
   resolved "https://registry.yarnpkg.com/url-toolkit/-/url-toolkit-2.1.6.tgz#6d03246499e519aad224c44044a4ae20544154f2"
   integrity sha512-UaZ2+50am4HwrV2crR/JAf63Q4VvPYphe63WGeoJxeu8gmOm0qxPt+KsukfakPNrX9aymGNEkkaoICwn+OuvBw==