HLS v1 support

pull/4317/head
Chocobozzz 2021-08-03 11:51:49 +02:00 committed by Chocobozzz
parent ff4de38385
commit 3e254de8be
9 changed files with 122 additions and 83 deletions

View File

@ -48,6 +48,8 @@
"@ngx-loading-bar/core": "^5.0.0", "@ngx-loading-bar/core": "^5.0.0",
"@ngx-loading-bar/http-client": "^5.0.0", "@ngx-loading-bar/http-client": "^5.0.0",
"@ngx-loading-bar/router": "^5.0.0", "@ngx-loading-bar/router": "^5.0.0",
"@peertube/p2p-media-loader-core": "^1.0.2",
"@peertube/p2p-media-loader-hlsjs": "^1.0.4",
"@types/chart.js": "^2.9.16", "@types/chart.js": "^2.9.16",
"@types/core-js": "^2.5.2", "@types/core-js": "^2.5.2",
"@types/debug": "^4.1.5", "@types/debug": "^4.1.5",
@ -76,7 +78,7 @@
"dexie": "^3.0.0", "dexie": "^3.0.0",
"file-loader": "^6.0.0", "file-loader": "^6.0.0",
"focus-visible": "^5.0.2", "focus-visible": "^5.0.2",
"hls.js": "^0.14.16", "hls.js": "^1.0.7",
"html-loader": "^2.1.2", "html-loader": "^2.1.2",
"html-webpack-plugin": "^5.3.1", "html-webpack-plugin": "^5.3.1",
"https-browserify": "^1.0.0", "https-browserify": "^1.0.0",
@ -93,7 +95,6 @@
"markdown-it": "12.0.6", "markdown-it": "12.0.6",
"mini-css-extract-plugin": "^1.6.0", "mini-css-extract-plugin": "^1.6.0",
"ngx-uploadx": "^4.1.0", "ngx-uploadx": "^4.1.0",
"p2p-media-loader-hlsjs": "^0.6.2",
"path-browserify": "^1.0.0", "path-browserify": "^1.0.0",
"primeng": "^12.0.0-rc.1", "primeng": "^12.0.0-rc.1",
"process": "^0.11.10", "process": "^0.11.10",

View File

@ -264,20 +264,16 @@ class Html5Hlsjs {
if (this.errorCounts[ data.type ]) this.errorCounts[ data.type ] += 1 if (this.errorCounts[ data.type ]) this.errorCounts[ data.type ] += 1
else this.errorCounts[ data.type ] = 1 else this.errorCounts[ data.type ] = 1
if (!data.fatal) { if (data.fatal) console.warn(error.message)
console.warn(error.message) else console.error(error.message, data)
return
}
console.error(error.message)
if (data.type === Hlsjs.ErrorTypes.NETWORK_ERROR) { if (data.type === Hlsjs.ErrorTypes.NETWORK_ERROR) {
error.code = 2 error.code = 2
this._handleNetworkError(error) this._handleNetworkError(error)
} else if (data.type === Hlsjs.ErrorTypes.MEDIA_ERROR && data.details !== 'manifestIncompatibleCodecsError') { } else if (data.fatal && data.type === Hlsjs.ErrorTypes.MEDIA_ERROR && data.details !== 'manifestIncompatibleCodecsError') {
error.code = 3 error.code = 3
this._handleMediaError(error) this._handleMediaError(error)
} else { } else if (data.fatal) {
this.hls.destroy() this.hls.destroy()
console.info('bubbling error up to VIDEOJS') console.info('bubbling error up to VIDEOJS')
this.tech.error = () => error as any this.tech.error = () => error as any
@ -286,12 +282,12 @@ class Html5Hlsjs {
} }
private switchQuality (qualityId: number) { private switchQuality (qualityId: number) {
this.hls.nextLevel = qualityId this.hls.currentLevel = qualityId
} }
private _levelLabel (level: Hlsjs.Level) { private _levelLabel (level: Hlsjs.Level) {
if (this.player.srOptions_.levelLabelHandler) { if (this.player.srOptions_.levelLabelHandler) {
return this.player.srOptions_.levelLabelHandler(level) return this.player.srOptions_.levelLabelHandler(level as any)
} }
if (level.height) return level.height + 'p' if (level.height) return level.height + 'p'

View File

@ -1,7 +1,7 @@
import * as Hlsjs from 'hls.js/dist/hls.light.js' import * as Hlsjs from 'hls.js/dist/hls.light.js'
import { Events, Segment } from 'p2p-media-loader-core'
import { Engine, initHlsJsPlayer, initVideoJsContribHlsJsPlayer } from 'p2p-media-loader-hlsjs'
import videojs from 'video.js' import videojs from 'video.js'
import { Events, Segment } from '@peertube/p2p-media-loader-core'
import { Engine, initHlsJsPlayer, initVideoJsContribHlsJsPlayer } from '@peertube/p2p-media-loader-hlsjs'
import { timeToInt } from '@shared/core-utils' import { timeToInt } from '@shared/core-utils'
import { P2PMediaLoaderPluginOptions, PlayerNetworkInfo } from '../peertube-videojs-typings' import { P2PMediaLoaderPluginOptions, PlayerNetworkInfo } from '../peertube-videojs-typings'
import { registerConfigPlugin, registerSourceHandler } from './hls-plugin' import { registerConfigPlugin, registerSourceHandler } from './hls-plugin'
@ -36,9 +36,6 @@ class P2pMediaLoaderPlugin extends Plugin {
private networkInfoInterval: any private networkInfoInterval: any
private hlsjsCurrentLevel: number
private hlsjsLevels: Hlsjs.Level[]
constructor (player: videojs.Player, options?: P2PMediaLoaderPluginOptions) { constructor (player: videojs.Player, options?: P2PMediaLoaderPluginOptions) {
super(player) super(player)
@ -88,13 +85,12 @@ class P2pMediaLoaderPlugin extends Plugin {
} }
getCurrentLevel () { getCurrentLevel () {
return this.hlsjsLevels.find(l => l.level === this.hlsjsCurrentLevel) return this.hlsjs.levels[this.hlsjs.currentLevel]
} }
getLiveLatency () { getLiveLatency () {
return undefined as number // FIXME: typings
// FIXME: Use latency when hls >= V1 return Math.round((this.hlsjs as any).latency)
// return this.hlsjs.latency
} }
getHLSJS () { getHLSJS () {
@ -140,31 +136,23 @@ class P2pMediaLoaderPlugin extends Plugin {
} }
private runStats () { private runStats () {
this.p2pEngine.on(Events.PieceBytesDownloaded, (method: string, size: number) => { this.p2pEngine.on(Events.PieceBytesDownloaded, (method: string, _segment, bytes: number) => {
const elem = method === 'p2p' ? this.statsP2PBytes : this.statsHTTPBytes const elem = method === 'p2p' ? this.statsP2PBytes : this.statsHTTPBytes
elem.pendingDownload.push(size) elem.pendingDownload.push(bytes)
elem.totalDownload += size elem.totalDownload += bytes
}) })
this.p2pEngine.on(Events.PieceBytesUploaded, (method: string, size: number) => { this.p2pEngine.on(Events.PieceBytesUploaded, (method: string, _segment, bytes: number) => {
const elem = method === 'p2p' ? this.statsP2PBytes : this.statsHTTPBytes const elem = method === 'p2p' ? this.statsP2PBytes : this.statsHTTPBytes
elem.pendingUpload.push(size) elem.pendingUpload.push(bytes)
elem.totalUpload += size elem.totalUpload += bytes
}) })
this.p2pEngine.on(Events.PeerConnect, () => this.statsP2PBytes.numPeers++) this.p2pEngine.on(Events.PeerConnect, () => this.statsP2PBytes.numPeers++)
this.p2pEngine.on(Events.PeerClose, () => this.statsP2PBytes.numPeers--) this.p2pEngine.on(Events.PeerClose, () => this.statsP2PBytes.numPeers--)
this.hlsjs.on(Hlsjs.Events.MANIFEST_PARSED, (_e, manifest) => {
this.hlsjsCurrentLevel = manifest.firstLevel
this.hlsjsLevels = manifest.levels
})
this.hlsjs.on(Hlsjs.Events.LEVEL_LOADED, (_e, level) => {
this.hlsjsCurrentLevel = level.levelId || (level as any).id
})
this.networkInfoInterval = setInterval(() => { this.networkInfoInterval = setInterval(() => {
const p2pDownloadSpeed = this.arraySum(this.statsP2PBytes.pendingDownload) const p2pDownloadSpeed = this.arraySum(this.statsP2PBytes.pendingDownload)
const p2pUploadSpeed = this.arraySum(this.statsP2PBytes.pendingUpload) const p2pUploadSpeed = this.arraySum(this.statsP2PBytes.pendingUpload)

View File

@ -1,4 +1,4 @@
import { Segment } from 'p2p-media-loader-core' import { Segment } from '@peertube/p2p-media-loader-core'
import { RedundancyUrlManager } from './redundancy-url-manager' import { RedundancyUrlManager } from './redundancy-url-manager'
function segmentUrlBuilderFactory (redundancyUrlManager: RedundancyUrlManager) { function segmentUrlBuilderFactory (redundancyUrlManager: RedundancyUrlManager) {

View File

@ -1,5 +1,5 @@
import { wait } from '@root-helpers/utils' import { wait } from '@root-helpers/utils'
import { Segment } from 'p2p-media-loader-core' import { Segment } from '@peertube/p2p-media-loader-core'
import { basename } from 'path' import { basename } from 'path'
type SegmentsJSON = { [filename: string]: string | { [byterange: string]: string } } type SegmentsJSON = { [filename: string]: string | { [byterange: string]: string } }

View File

@ -22,6 +22,7 @@ import './videojs-components/settings-panel-child'
import './videojs-components/theater-button' import './videojs-components/theater-button'
import './playlist/playlist-plugin' import './playlist/playlist-plugin'
import videojs from 'video.js' import videojs from 'video.js'
import { HlsJsEngineSettings } from '@peertube/p2p-media-loader-hlsjs'
import { PluginsManager } from '@root-helpers/plugins-manager' import { PluginsManager } from '@root-helpers/plugins-manager'
import { buildVideoLink, decorateVideoLink } from '@shared/core-utils' import { buildVideoLink, decorateVideoLink } from '@shared/core-utils'
import { isDefaultLocale } from '@shared/core-utils/i18n' import { isDefaultLocale } from '@shared/core-utils/i18n'
@ -30,11 +31,12 @@ import { copyToClipboard } from '../../root-helpers/utils'
import { RedundancyUrlManager } from './p2p-media-loader/redundancy-url-manager' import { RedundancyUrlManager } from './p2p-media-loader/redundancy-url-manager'
import { segmentUrlBuilderFactory } from './p2p-media-loader/segment-url-builder' import { segmentUrlBuilderFactory } from './p2p-media-loader/segment-url-builder'
import { segmentValidatorFactory } from './p2p-media-loader/segment-validator' import { segmentValidatorFactory } from './p2p-media-loader/segment-validator'
import { getStoredP2PEnabled } from './peertube-player-local-storage' import { getAverageBandwidthInStore, getStoredP2PEnabled, saveAverageBandwidth } from './peertube-player-local-storage'
import { import {
NextPreviousVideoButtonOptions, NextPreviousVideoButtonOptions,
P2PMediaLoaderPluginOptions, P2PMediaLoaderPluginOptions,
PeerTubeLinkButtonOptions, PeerTubeLinkButtonOptions,
PlayerNetworkInfo,
PlaylistPluginOptions, PlaylistPluginOptions,
UserWatching, UserWatching,
VideoJSCaption, VideoJSCaption,
@ -148,7 +150,7 @@ export class PeertubePlayerManager {
if (mode === 'webtorrent') await import('./webtorrent/webtorrent-plugin') if (mode === 'webtorrent') await import('./webtorrent/webtorrent-plugin')
if (mode === 'p2p-media-loader') { if (mode === 'p2p-media-loader') {
[ p2pMediaLoader ] = await Promise.all([ [ p2pMediaLoader ] = await Promise.all([
import('p2p-media-loader-hlsjs'), import('@peertube/p2p-media-loader-hlsjs'),
import('./p2p-media-loader/p2p-media-loader-plugin') import('./p2p-media-loader/p2p-media-loader-plugin')
]) ])
} }
@ -193,6 +195,12 @@ export class PeertubePlayerManager {
mode mode
}) })
player.on('p2pInfo', (_, data: PlayerNetworkInfo) => {
if (data.source !== 'p2p-media-loader' || isNaN(data.bandwidthEstimate)) return
saveAverageBandwidth(data.bandwidthEstimate)
})
return res(player) return res(player)
}) })
}) })
@ -359,12 +367,13 @@ export class PeertubePlayerManager {
consumeOnly = true consumeOnly = true
} }
const p2pMediaLoaderConfig = { const p2pMediaLoaderConfig: HlsJsEngineSettings = {
loader: { loader: {
trackerAnnounce, trackerAnnounce,
segmentValidator: segmentValidatorFactory(options.p2pMediaLoader.segmentsSha256Url, options.common.isLive), segmentValidator: segmentValidatorFactory(options.p2pMediaLoader.segmentsSha256Url, options.common.isLive),
rtcConfig: getRtcConfig(), rtcConfig: getRtcConfig(),
requiredSegmentsPriority: 1, requiredSegmentsPriority: 1,
simultaneousHttpDownloads: 1,
segmentUrlBuilder: segmentUrlBuilderFactory(redundancyUrlManager), segmentUrlBuilder: segmentUrlBuilderFactory(redundancyUrlManager),
useP2P: getStoredP2PEnabled(), useP2P: getStoredP2PEnabled(),
consumeOnly consumeOnly
@ -373,6 +382,7 @@ export class PeertubePlayerManager {
swarmId: p2pMediaLoaderOptions.playlistUrl swarmId: p2pMediaLoaderOptions.playlistUrl
} }
} }
const hlsjs = { const hlsjs = {
levelLabelHandler: (level: { height: number, width: number }) => { levelLabelHandler: (level: { height: number, width: number }) => {
const resolution = Math.min(level.height || 0, level.width || 0) const resolution = Math.min(level.height || 0, level.width || 0)
@ -387,12 +397,7 @@ export class PeertubePlayerManager {
return label return label
}, },
html5: { html5: {
hlsjsConfig: { hlsjsConfig: this.getHLSOptions(p2pMediaLoaderModule, p2pMediaLoaderConfig)
capLevelToPlayerSize: true,
autoStartLoad: false,
liveSyncDurationCount: 5,
loader: new p2pMediaLoaderModule.Engine(p2pMediaLoaderConfig).createLoaderClass()
}
} }
} }
@ -402,6 +407,28 @@ export class PeertubePlayerManager {
return toAssign return toAssign
} }
private static getHLSOptions (p2pMediaLoaderModule: any, p2pMediaLoaderConfig: HlsJsEngineSettings) {
const base = {
capLevelToPlayerSize: true,
autoStartLoad: false,
liveSyncDurationCount: 5,
loader: new p2pMediaLoaderModule.Engine(p2pMediaLoaderConfig).createLoaderClass()
}
const averageBandwidth = getAverageBandwidthInStore()
if (!averageBandwidth) return base
return {
...base,
abrEwmaDefaultEstimate: averageBandwidth * 8, // We want bit/s
startLevel: -1,
testBandwidth: false,
debug: false
}
}
private static addWebTorrentOptions (plugins: VideoJSPluginOptions, options: PeertubePlayerManagerOptions) { private static addWebTorrentOptions (plugins: VideoJSPluginOptions, options: PeertubePlayerManagerOptions) {
const commonOptions = options.common const commonOptions = options.common
const webtorrentOptions = options.webtorrent const webtorrentOptions = options.webtorrent

View File

@ -228,6 +228,7 @@ class PeerTubePlugin extends Plugin {
} }
} }
console.log('Resolution changed.', data)
this.trigger('resolutionChange', data) this.trigger('resolutionChange', data)
} }

View File

@ -1,4 +1,4 @@
import { Config, Level } from 'hls.js' import { HlsConfig, Level } from 'hls.js'
import videojs from 'video.js' import videojs from 'video.js'
import { VideoFile, VideoPlaylist, VideoPlaylistElement } from '@shared/models' import { VideoFile, VideoPlaylist, VideoPlaylistElement } from '@shared/models'
import { P2pMediaLoaderPlugin } from './p2p-media-loader/p2p-media-loader-plugin' import { P2pMediaLoaderPlugin } from './p2p-media-loader/p2p-media-loader-plugin'
@ -60,7 +60,7 @@ export interface VideoJSTechHLS extends videojs.Tech {
} }
export interface HlsjsConfigHandlerOptions { export interface HlsjsConfigHandlerOptions {
hlsjsConfig?: Config & { cueHandler: any }// FIXME: typings hlsjsConfig?: HlsConfig & { cueHandler: any }// FIXME: typings
captionConfig?: any // FIXME: typings captionConfig?: any // FIXME: typings
levelLabelHandler?: (level: Level) => string levelLabelHandler?: (level: Level) => string

View File

@ -1333,6 +1333,26 @@
node-gyp "^7.1.0" node-gyp "^7.1.0"
read-package-json-fast "^2.0.1" read-package-json-fast "^2.0.1"
"@peertube/p2p-media-loader-core@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@peertube/p2p-media-loader-core/-/p2p-media-loader-core-1.0.2.tgz#ef36a23df5a5393cc5d180a45dfb70d2c3ecff87"
integrity sha512-2F6Cx2ncXe+ySaaGiAWf7jJ8snJpyd7WNCxYbJ5Zadst1mNSQlxUqH4/qEl/bai4DiuzzhudlzXS8U3SX9c9Jw==
dependencies:
bittorrent-tracker "^9.16.1"
debug "^4.3.1"
events "^3.3.0"
sha.js "^2.4.11"
simple-peer "^9.10.0"
"@peertube/p2p-media-loader-hlsjs@^1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@peertube/p2p-media-loader-hlsjs/-/p2p-media-loader-hlsjs-1.0.4.tgz#849809067886e41bf2ba7e71a2da33478863bc66"
integrity sha512-FFFlYPFwTGxB3CPChqlzPqJw65ajIjCCxCn4IQRNuagYpo0fdaxrgepMHNPW3Zl5DmvEppv+ohUfYyr98U1wiw==
dependencies:
"@peertube/p2p-media-loader-core" "^1.0.2"
events "^3.3.0"
m3u8-parser "^4.6.0"
"@polka/url@^1.0.0-next.15": "@polka/url@^1.0.0-next.15":
version "1.0.0-next.15" version "1.0.0-next.15"
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.15.tgz#6a9d143f7f4f49db2d782f9e1c8839a29b43ae23" resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.15.tgz#6a9d143f7f4f49db2d782f9e1c8839a29b43ae23"
@ -2445,7 +2465,7 @@ bittorrent-protocol@^3.2.0:
speedometer "^1.1.0" speedometer "^1.1.0"
unordered-array-remove "^1.0.2" unordered-array-remove "^1.0.2"
bittorrent-tracker@^9.0.0, bittorrent-tracker@^9.14.4: bittorrent-tracker@^9.0.0:
version "9.17.2" version "9.17.2"
resolved "https://registry.yarnpkg.com/bittorrent-tracker/-/bittorrent-tracker-9.17.2.tgz#1afb02d3d2fb474c13389c45e8a2b6919bff40bd" resolved "https://registry.yarnpkg.com/bittorrent-tracker/-/bittorrent-tracker-9.17.2.tgz#1afb02d3d2fb474c13389c45e8a2b6919bff40bd"
integrity sha512-hXjed0OnB16da+ScJUZnrAZbf9gMgSLKqh5rJebtYnTRgN4o1mX0DOPH3Nf5RFCs935ibhSmZN5nwbkh+3MdEA== integrity sha512-hXjed0OnB16da+ScJUZnrAZbf9gMgSLKqh5rJebtYnTRgN4o1mX0DOPH3Nf5RFCs935ibhSmZN5nwbkh+3MdEA==
@ -2475,6 +2495,36 @@ bittorrent-tracker@^9.0.0, bittorrent-tracker@^9.14.4:
bufferutil "^4.0.3" bufferutil "^4.0.3"
utf-8-validate "^5.0.5" utf-8-validate "^5.0.5"
bittorrent-tracker@^9.16.1:
version "9.17.4"
resolved "https://registry.yarnpkg.com/bittorrent-tracker/-/bittorrent-tracker-9.17.4.tgz#663f51064a924e945cb6ca19a0c293aca258128b"
integrity sha512-ykhdVQHtLfn4DYSJUQD/zFAbP8YwnF6nGlj2SBnCY4xkW5bhwXPeFZUhryAtdITl0qNL/FpmFOamBZfxIwkbxg==
dependencies:
bencode "^2.0.1"
bittorrent-peerid "^1.3.3"
bn.js "^5.2.0"
chrome-dgram "^3.0.6"
compact2string "^1.4.1"
debug "^4.1.1"
ip "^1.1.5"
lru "^3.1.0"
minimist "^1.2.5"
once "^1.4.0"
queue-microtask "^1.2.3"
random-iterate "^1.0.1"
randombytes "^2.1.0"
run-parallel "^1.2.0"
run-series "^1.1.9"
simple-get "^4.0.0"
simple-peer "^9.11.0"
simple-websocket "^9.1.0"
string2compact "^1.3.0"
unordered-array-remove "^1.0.2"
ws "^7.4.5"
optionalDependencies:
bufferutil "^4.0.3"
utf-8-validate "^5.0.5"
bl@^4.1.0: bl@^4.1.0:
version "4.1.0" version "4.1.0"
resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
@ -4179,12 +4229,12 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
eventemitter3@^4.0.0, eventemitter3@^4.0.3: eventemitter3@^4.0.0:
version "4.0.7" version "4.0.7"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
events@^3.0.0, events@^3.2.0: events@^3.2.0, events@^3.3.0:
version "3.3.0" version "3.3.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
@ -4642,7 +4692,7 @@ gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2:
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
get-browser-rtc@^1.0.2, get-browser-rtc@^1.1.0: get-browser-rtc@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/get-browser-rtc/-/get-browser-rtc-1.1.0.tgz#d1494e299b00f33fc8e9d6d3343ba4ba99711a2c" resolved "https://registry.yarnpkg.com/get-browser-rtc/-/get-browser-rtc-1.1.0.tgz#d1494e299b00f33fc8e9d6d3343ba4ba99711a2c"
integrity sha512-MghbMJ61EJrRsDe7w1Bvqt3ZsBuqhce5nrn/XAwgwOXhcsz53/ltdxOse1h/8eKXj5slzxdsz56g5rzOFSGwfQ== integrity sha512-MghbMJ61EJrRsDe7w1Bvqt3ZsBuqhce5nrn/XAwgwOXhcsz53/ltdxOse1h/8eKXj5slzxdsz56g5rzOFSGwfQ==
@ -4930,13 +4980,10 @@ hex-color-regex@^1.1.0:
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
hls.js@^0.14.16: hls.js@^1.0.7:
version "0.14.17" version "1.0.7"
resolved "https://registry.yarnpkg.com/hls.js/-/hls.js-0.14.17.tgz#0127cff2ec2f994a54eb955fe669ef6153a8e317" resolved "https://registry.yarnpkg.com/hls.js/-/hls.js-1.0.7.tgz#b4ab75e7a46650d02245a1da091efd15f07d16eb"
integrity sha512-25A7+m6qqp6UVkuzUQ//VVh2EEOPYlOBg32ypr34bcPO7liBMOkKFvbjbCBfiPAOTA/7BSx1Dujft3Th57WyFg== integrity sha512-NsGaksvOuYNyTmu/w239EtYFMadFzIoDkmStc1FDRcrGmvxOfMGKad/hLj4NHoE8H1S+Q8dT7HufMJJ6yiht7g==
dependencies:
eventemitter3 "^4.0.3"
url-toolkit "^2.1.6"
hosted-git-info@^2.1.4: hosted-git-info@^2.1.4:
version "2.8.9" version "2.8.9"
@ -6341,7 +6388,7 @@ lru@^3.1.0:
dependencies: dependencies:
inherits "^2.0.1" inherits "^2.0.1"
m3u8-parser@4.7.0, m3u8-parser@^4.4.0: m3u8-parser@4.7.0, m3u8-parser@^4.6.0:
version "4.7.0" version "4.7.0"
resolved "https://registry.yarnpkg.com/m3u8-parser/-/m3u8-parser-4.7.0.tgz#e01e8ce136098ade1b14ee691ea20fc4dc60abf6" resolved "https://registry.yarnpkg.com/m3u8-parser/-/m3u8-parser-4.7.0.tgz#e01e8ce136098ade1b14ee691ea20fc4dc60abf6"
integrity sha512-48l/OwRyjBm+QhNNigEEcRcgbRvnUjL7rxs597HmW9QSNbyNvt+RcZ9T/d9vxi9A9z7EZrB1POtZYhdRlwYQkQ== integrity sha512-48l/OwRyjBm+QhNNigEEcRcgbRvnUjL7rxs597HmW9QSNbyNvt+RcZ9T/d9vxi9A9z7EZrB1POtZYhdRlwYQkQ==
@ -7374,27 +7421,6 @@ p-try@^2.0.0:
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
p2p-media-loader-core@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/p2p-media-loader-core/-/p2p-media-loader-core-0.6.2.tgz#7e46cf8fc4357596f389e106bee850908cc974ef"
integrity sha512-yspgCOrVVYitVNece5CA6W/kcVA0UybvbD4kyBE5ooyhCAXQK5/q6JsIpXiVQ3VkQw8Qs4mfZjU39Vt6vEk6aw==
dependencies:
bittorrent-tracker "^9.14.4"
debug "^4.1.1"
events "^3.0.0"
get-browser-rtc "^1.0.2"
sha.js "^2.4.11"
simple-peer "^9.5.0"
p2p-media-loader-hlsjs@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/p2p-media-loader-hlsjs/-/p2p-media-loader-hlsjs-0.6.2.tgz#b66f977a5d28986c8f6e62d2ffa297aec3c05186"
integrity sha512-5LgqWPDsgyST9rxoHGDpExZU1rIDZIT0qft2wAnlg8Cb8aVeaBxUsmF4Sj692Qb5/GBDsi8vLE03LW8gpvlh1g==
dependencies:
events "^3.0.0"
m3u8-parser "^4.4.0"
p2p-media-loader-core "^0.6.2"
package-json-versionify@^1.0.4: package-json-versionify@^1.0.4:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/package-json-versionify/-/package-json-versionify-1.0.4.tgz#5860587a944873a6b7e6d26e8e51ffb22315bf17" resolved "https://registry.yarnpkg.com/package-json-versionify/-/package-json-versionify-1.0.4.tgz#5860587a944873a6b7e6d26e8e51ffb22315bf17"
@ -9313,7 +9339,7 @@ simple-get@^4.0.0:
once "^1.3.1" once "^1.3.1"
simple-concat "^1.0.0" simple-concat "^1.0.0"
simple-peer@^9.11.0, simple-peer@^9.5.0, simple-peer@^9.9.3: simple-peer@^9.10.0, simple-peer@^9.11.0, simple-peer@^9.9.3:
version "9.11.0" version "9.11.0"
resolved "https://registry.yarnpkg.com/simple-peer/-/simple-peer-9.11.0.tgz#e8d27609c7a610c3ddd75767da868e8daab67571" resolved "https://registry.yarnpkg.com/simple-peer/-/simple-peer-9.11.0.tgz#e8d27609c7a610c3ddd75767da868e8daab67571"
integrity sha512-qvdNu/dGMHBm2uQ7oLhQBMhYlrOZC1ywXNCH/i8I4etxR1vrjCnU6ZSQBptndB1gcakjo2+w4OHo7Sjza1SHxg== integrity sha512-qvdNu/dGMHBm2uQ7oLhQBMhYlrOZC1ywXNCH/i8I4etxR1vrjCnU6ZSQBptndB1gcakjo2+w4OHo7Sjza1SHxg==
@ -10538,7 +10564,7 @@ url-parse@^1.4.3, url-parse@^1.5.1:
querystringify "^2.1.1" querystringify "^2.1.1"
requires-port "^1.0.0" requires-port "^1.0.0"
url-toolkit@^2.1.6, url-toolkit@^2.2.1: url-toolkit@^2.2.1:
version "2.2.2" version "2.2.2"
resolved "https://registry.yarnpkg.com/url-toolkit/-/url-toolkit-2.2.2.tgz#51ef27b56d3187185f9ecf4a8ac7e8f55203c89d" resolved "https://registry.yarnpkg.com/url-toolkit/-/url-toolkit-2.2.2.tgz#51ef27b56d3187185f9ecf4a8ac7e8f55203c89d"
integrity sha512-l25w6Sy+Iy3/IbogunxhWwljPaDnqpiKvrQRoLBm6DfISco7NyRIS7Zf6+Oxhy1T8kHxWdwLND7ZZba6NjXMug== integrity sha512-l25w6Sy+Iy3/IbogunxhWwljPaDnqpiKvrQRoLBm6DfISco7NyRIS7Zf6+Oxhy1T8kHxWdwLND7ZZba6NjXMug==