Correctly implement p2p-media-loader
This commit is contained in:
parent
2adfc7ea9a
commit
3b6f205c34
12 changed files with 241 additions and 61 deletions
|
@ -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",
|
||||
|
@ -110,6 +111,7 @@
|
|||
"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",
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(' '))
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -28,30 +28,26 @@ 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))
|
||||
player.peertube().on('autoResolutionChange', (_: any, data: AutoResolutionUpdateData) => this.updateAutoResolution(data))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: update on HLS change
|
||||
}
|
||||
|
||||
handleClick (event: any) {
|
||||
// Auto button disabled?
|
||||
if (this.autoResolutionPossible === false && this.id === -1) return
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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', {
|
||||
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) {
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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'
|
||||
// }
|
||||
})
|
||||
}
|
||||
|
||||
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))
|
||||
|
||||
|
|
|
@ -411,6 +411,11 @@
|
|||
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==
|
||||
|
|
Loading…
Reference in a new issue