aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib/plugins
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-01-28 15:52:44 +0100
committerChocobozzz <me@florianbigard.com>2021-01-28 15:55:39 +0100
commit1896bca09e088b0da9d5e845407ecebae330618c (patch)
tree56041c445c0cd49aca536d0fd6b586730f4d341e /server/lib/plugins
parent529b37527cff5203a0689a15ce73dcee6e1eece2 (diff)
downloadPeerTube-1896bca09e088b0da9d5e845407ecebae330618c.tar.gz
PeerTube-1896bca09e088b0da9d5e845407ecebae330618c.tar.zst
PeerTube-1896bca09e088b0da9d5e845407ecebae330618c.zip
Support transcoding options/encoders by plugins
Diffstat (limited to 'server/lib/plugins')
-rw-r--r--server/lib/plugins/plugin-helpers-builder.ts (renamed from server/lib/plugins/plugin-helpers.ts)0
-rw-r--r--server/lib/plugins/plugin-manager.ts35
-rw-r--r--server/lib/plugins/register-helpers.ts (renamed from server/lib/plugins/register-helpers-store.ts)91
3 files changed, 107 insertions, 19 deletions
diff --git a/server/lib/plugins/plugin-helpers.ts b/server/lib/plugins/plugin-helpers-builder.ts
index 39773f693..39773f693 100644
--- a/server/lib/plugins/plugin-helpers.ts
+++ b/server/lib/plugins/plugin-helpers-builder.ts
diff --git a/server/lib/plugins/plugin-manager.ts b/server/lib/plugins/plugin-manager.ts
index 8e7491257..c19b40135 100644
--- a/server/lib/plugins/plugin-manager.ts
+++ b/server/lib/plugins/plugin-manager.ts
@@ -20,7 +20,7 @@ import { PLUGIN_GLOBAL_CSS_PATH } from '../../initializers/constants'
20import { PluginModel } from '../../models/server/plugin' 20import { PluginModel } from '../../models/server/plugin'
21import { PluginLibrary, RegisterServerAuthExternalOptions, RegisterServerAuthPassOptions, RegisterServerOptions } from '../../types/plugins' 21import { PluginLibrary, RegisterServerAuthExternalOptions, RegisterServerAuthPassOptions, RegisterServerOptions } from '../../types/plugins'
22import { ClientHtml } from '../client-html' 22import { ClientHtml } from '../client-html'
23import { RegisterHelpersStore } from './register-helpers-store' 23import { RegisterHelpers } from './register-helpers'
24import { installNpmPlugin, installNpmPluginFromDisk, removeNpmPlugin } from './yarn' 24import { installNpmPlugin, installNpmPluginFromDisk, removeNpmPlugin } from './yarn'
25 25
26export interface RegisteredPlugin { 26export interface RegisteredPlugin {
@@ -40,7 +40,7 @@ export interface RegisteredPlugin {
40 css: string[] 40 css: string[]
41 41
42 // Only if this is a plugin 42 // Only if this is a plugin
43 registerHelpersStore?: RegisterHelpersStore 43 registerHelpers?: RegisterHelpers
44 unregister?: Function 44 unregister?: Function
45} 45}
46 46
@@ -109,7 +109,7 @@ export class PluginManager implements ServerHook {
109 npmName: p.npmName, 109 npmName: p.npmName,
110 name: p.name, 110 name: p.name,
111 version: p.version, 111 version: p.version,
112 idAndPassAuths: p.registerHelpersStore.getIdAndPassAuths() 112 idAndPassAuths: p.registerHelpers.getIdAndPassAuths()
113 })) 113 }))
114 .filter(v => v.idAndPassAuths.length !== 0) 114 .filter(v => v.idAndPassAuths.length !== 0)
115 } 115 }
@@ -120,7 +120,7 @@ export class PluginManager implements ServerHook {
120 npmName: p.npmName, 120 npmName: p.npmName,
121 name: p.name, 121 name: p.name,
122 version: p.version, 122 version: p.version,
123 externalAuths: p.registerHelpersStore.getExternalAuths() 123 externalAuths: p.registerHelpers.getExternalAuths()
124 })) 124 }))
125 .filter(v => v.externalAuths.length !== 0) 125 .filter(v => v.externalAuths.length !== 0)
126 } 126 }
@@ -129,14 +129,14 @@ export class PluginManager implements ServerHook {
129 const result = this.getRegisteredPluginOrTheme(npmName) 129 const result = this.getRegisteredPluginOrTheme(npmName)
130 if (!result || result.type !== PluginType.PLUGIN) return [] 130 if (!result || result.type !== PluginType.PLUGIN) return []
131 131
132 return result.registerHelpersStore.getSettings() 132 return result.registerHelpers.getSettings()
133 } 133 }
134 134
135 getRouter (npmName: string) { 135 getRouter (npmName: string) {
136 const result = this.getRegisteredPluginOrTheme(npmName) 136 const result = this.getRegisteredPluginOrTheme(npmName)
137 if (!result || result.type !== PluginType.PLUGIN) return null 137 if (!result || result.type !== PluginType.PLUGIN) return null
138 138
139 return result.registerHelpersStore.getRouter() 139 return result.registerHelpers.getRouter()
140 } 140 }
141 141
142 getTranslations (locale: string) { 142 getTranslations (locale: string) {
@@ -194,7 +194,7 @@ export class PluginManager implements ServerHook {
194 logger.error('Cannot find plugin %s to call on settings changed.', name) 194 logger.error('Cannot find plugin %s to call on settings changed.', name)
195 } 195 }
196 196
197 for (const cb of registered.registerHelpersStore.getOnSettingsChangedCallbacks()) { 197 for (const cb of registered.registerHelpers.getOnSettingsChangedCallbacks()) {
198 try { 198 try {
199 cb(settings) 199 cb(settings)
200 } catch (err) { 200 } catch (err) {
@@ -268,8 +268,9 @@ export class PluginManager implements ServerHook {
268 this.hooks[key] = this.hooks[key].filter(h => h.npmName !== npmName) 268 this.hooks[key] = this.hooks[key].filter(h => h.npmName !== npmName)
269 } 269 }
270 270
271 const store = plugin.registerHelpersStore 271 const store = plugin.registerHelpers
272 store.reinitVideoConstants(plugin.npmName) 272 store.reinitVideoConstants(plugin.npmName)
273 store.reinitTranscodingProfilesAndEncoders(plugin.npmName)
273 274
274 logger.info('Regenerating registered plugin CSS to global file.') 275 logger.info('Regenerating registered plugin CSS to global file.')
275 await this.regeneratePluginGlobalCSS() 276 await this.regeneratePluginGlobalCSS()
@@ -375,11 +376,11 @@ export class PluginManager implements ServerHook {
375 this.sanitizeAndCheckPackageJSONOrThrow(packageJSON, plugin.type) 376 this.sanitizeAndCheckPackageJSONOrThrow(packageJSON, plugin.type)
376 377
377 let library: PluginLibrary 378 let library: PluginLibrary
378 let registerHelpersStore: RegisterHelpersStore 379 let registerHelpers: RegisterHelpers
379 if (plugin.type === PluginType.PLUGIN) { 380 if (plugin.type === PluginType.PLUGIN) {
380 const result = await this.registerPlugin(plugin, pluginPath, packageJSON) 381 const result = await this.registerPlugin(plugin, pluginPath, packageJSON)
381 library = result.library 382 library = result.library
382 registerHelpersStore = result.registerStore 383 registerHelpers = result.registerStore
383 } 384 }
384 385
385 const clientScripts: { [id: string]: ClientScript } = {} 386 const clientScripts: { [id: string]: ClientScript } = {}
@@ -398,7 +399,7 @@ export class PluginManager implements ServerHook {
398 staticDirs: packageJSON.staticDirs, 399 staticDirs: packageJSON.staticDirs,
399 clientScripts, 400 clientScripts,
400 css: packageJSON.css, 401 css: packageJSON.css,
401 registerHelpersStore: registerHelpersStore || undefined, 402 registerHelpers: registerHelpers || undefined,
402 unregister: library ? library.unregister : undefined 403 unregister: library ? library.unregister : undefined
403 } 404 }
404 405
@@ -512,8 +513,8 @@ export class PluginManager implements ServerHook {
512 const plugin = this.getRegisteredPluginOrTheme(npmName) 513 const plugin = this.getRegisteredPluginOrTheme(npmName)
513 if (!plugin || plugin.type !== PluginType.PLUGIN) return null 514 if (!plugin || plugin.type !== PluginType.PLUGIN) return null
514 515
515 let auths: (RegisterServerAuthPassOptions | RegisterServerAuthExternalOptions)[] = plugin.registerHelpersStore.getIdAndPassAuths() 516 let auths: (RegisterServerAuthPassOptions | RegisterServerAuthExternalOptions)[] = plugin.registerHelpers.getIdAndPassAuths()
516 auths = auths.concat(plugin.registerHelpersStore.getExternalAuths()) 517 auths = auths.concat(plugin.registerHelpers.getExternalAuths())
517 518
518 return auths.find(a => a.authName === authName) 519 return auths.find(a => a.authName === authName)
519 } 520 }
@@ -538,7 +539,7 @@ export class PluginManager implements ServerHook {
538 private getRegisterHelpers ( 539 private getRegisterHelpers (
539 npmName: string, 540 npmName: string,
540 plugin: PluginModel 541 plugin: PluginModel
541 ): { registerStore: RegisterHelpersStore, registerOptions: RegisterServerOptions } { 542 ): { registerStore: RegisterHelpers, registerOptions: RegisterServerOptions } {
542 const onHookAdded = (options: RegisterServerHookOptions) => { 543 const onHookAdded = (options: RegisterServerHookOptions) => {
543 if (!this.hooks[options.target]) this.hooks[options.target] = [] 544 if (!this.hooks[options.target]) this.hooks[options.target] = []
544 545
@@ -550,11 +551,11 @@ export class PluginManager implements ServerHook {
550 }) 551 })
551 } 552 }
552 553
553 const registerHelpersStore = new RegisterHelpersStore(npmName, plugin, onHookAdded.bind(this)) 554 const registerHelpers = new RegisterHelpers(npmName, plugin, onHookAdded.bind(this))
554 555
555 return { 556 return {
556 registerStore: registerHelpersStore, 557 registerStore: registerHelpers,
557 registerOptions: registerHelpersStore.buildRegisterHelpers() 558 registerOptions: registerHelpers.buildRegisterHelpers()
558 } 559 }
559 } 560 }
560 561
diff --git a/server/lib/plugins/register-helpers-store.ts b/server/lib/plugins/register-helpers.ts
index c73079302..3a38a4835 100644
--- a/server/lib/plugins/register-helpers-store.ts
+++ b/server/lib/plugins/register-helpers.ts
@@ -17,6 +17,7 @@ import {
17 RegisterServerOptions 17 RegisterServerOptions
18} from '@server/types/plugins' 18} from '@server/types/plugins'
19import { 19import {
20 EncoderOptionsBuilder,
20 PluginPlaylistPrivacyManager, 21 PluginPlaylistPrivacyManager,
21 PluginSettingsManager, 22 PluginSettingsManager,
22 PluginStorageManager, 23 PluginStorageManager,
@@ -28,7 +29,8 @@ import {
28 RegisterServerSettingOptions 29 RegisterServerSettingOptions
29} from '@shared/models' 30} from '@shared/models'
30import { serverHookObject } from '@shared/models/plugins/server-hook.model' 31import { serverHookObject } from '@shared/models/plugins/server-hook.model'
31import { buildPluginHelpers } from './plugin-helpers' 32import { VideoTranscodingProfilesManager } from '../video-transcoding-profiles'
33import { buildPluginHelpers } from './plugin-helpers-builder'
32 34
33type AlterableVideoConstant = 'language' | 'licence' | 'category' | 'privacy' | 'playlistPrivacy' 35type AlterableVideoConstant = 'language' | 'licence' | 'category' | 'privacy' | 'playlistPrivacy'
34type VideoConstant = { [key in number | string]: string } 36type VideoConstant = { [key in number | string]: string }
@@ -40,7 +42,7 @@ type UpdatedVideoConstant = {
40 } 42 }
41} 43}
42 44
43export class RegisterHelpersStore { 45export class RegisterHelpers {
44 private readonly updatedVideoConstants: UpdatedVideoConstant = { 46 private readonly updatedVideoConstants: UpdatedVideoConstant = {
45 playlistPrivacy: { added: [], deleted: [] }, 47 playlistPrivacy: { added: [], deleted: [] },
46 privacy: { added: [], deleted: [] }, 48 privacy: { added: [], deleted: [] },
@@ -49,6 +51,23 @@ export class RegisterHelpersStore {
49 category: { added: [], deleted: [] } 51 category: { added: [], deleted: [] }
50 } 52 }
51 53
54 private readonly transcodingProfiles: {
55 [ npmName: string ]: {
56 type: 'vod' | 'live'
57 encoder: string
58 profile: string
59 }[]
60 } = {}
61
62 private readonly transcodingEncoders: {
63 [ npmName: string ]: {
64 type: 'vod' | 'live'
65 streamType: 'audio' | 'video'
66 encoder: string
67 priority: number
68 }[]
69 } = {}
70
52 private readonly settings: RegisterServerSettingOptions[] = [] 71 private readonly settings: RegisterServerSettingOptions[] = []
53 72
54 private idAndPassAuths: RegisterServerAuthPassOptions[] = [] 73 private idAndPassAuths: RegisterServerAuthPassOptions[] = []
@@ -83,6 +102,8 @@ export class RegisterHelpersStore {
83 const videoPrivacyManager = this.buildVideoPrivacyManager() 102 const videoPrivacyManager = this.buildVideoPrivacyManager()
84 const playlistPrivacyManager = this.buildPlaylistPrivacyManager() 103 const playlistPrivacyManager = this.buildPlaylistPrivacyManager()
85 104
105 const transcodingManager = this.buildTranscodingManager()
106
86 const registerIdAndPassAuth = this.buildRegisterIdAndPassAuth() 107 const registerIdAndPassAuth = this.buildRegisterIdAndPassAuth()
87 const registerExternalAuth = this.buildRegisterExternalAuth() 108 const registerExternalAuth = this.buildRegisterExternalAuth()
88 const unregisterIdAndPassAuth = this.buildUnregisterIdAndPassAuth() 109 const unregisterIdAndPassAuth = this.buildUnregisterIdAndPassAuth()
@@ -106,6 +127,8 @@ export class RegisterHelpersStore {
106 videoPrivacyManager, 127 videoPrivacyManager,
107 playlistPrivacyManager, 128 playlistPrivacyManager,
108 129
130 transcodingManager,
131
109 registerIdAndPassAuth, 132 registerIdAndPassAuth,
110 registerExternalAuth, 133 registerExternalAuth,
111 unregisterIdAndPassAuth, 134 unregisterIdAndPassAuth,
@@ -141,6 +164,22 @@ export class RegisterHelpersStore {
141 } 164 }
142 } 165 }
143 166
167 reinitTranscodingProfilesAndEncoders (npmName: string) {
168 const profiles = this.transcodingProfiles[npmName]
169 if (Array.isArray(profiles)) {
170 for (const profile of profiles) {
171 VideoTranscodingProfilesManager.Instance.removeProfile(profile)
172 }
173 }
174
175 const encoders = this.transcodingEncoders[npmName]
176 if (Array.isArray(encoders)) {
177 for (const o of encoders) {
178 VideoTranscodingProfilesManager.Instance.removeEncoderPriority(o.type, o.streamType, o.encoder, o.priority)
179 }
180 }
181 }
182
144 getSettings () { 183 getSettings () {
145 return this.settings 184 return this.settings
146 } 185 }
@@ -354,4 +393,52 @@ export class RegisterHelpersStore {
354 393
355 return true 394 return true
356 } 395 }
396
397 private buildTranscodingManager () {
398 const self = this
399
400 function addProfile (type: 'live' | 'vod', encoder: string, profile: string, builder: EncoderOptionsBuilder) {
401 if (profile === 'default') {
402 logger.error('A plugin cannot add a default live transcoding profile')
403 return false
404 }
405
406 VideoTranscodingProfilesManager.Instance.addProfile({
407 type,
408 encoder,
409 profile,
410 builder
411 })
412
413 if (!self.transcodingProfiles[self.npmName]) self.transcodingProfiles[self.npmName] = []
414 self.transcodingProfiles[self.npmName].push({ type, encoder, profile })
415
416 return true
417 }
418
419 function addEncoderPriority (type: 'live' | 'vod', streamType: 'audio' | 'video', encoder: string, priority: number) {
420 VideoTranscodingProfilesManager.Instance.addEncoderPriority(type, streamType, encoder, priority)
421
422 if (!self.transcodingEncoders[self.npmName]) self.transcodingEncoders[self.npmName] = []
423 self.transcodingEncoders[self.npmName].push({ type, streamType, encoder, priority })
424 }
425
426 return {
427 addLiveProfile (encoder: string, profile: string, builder: EncoderOptionsBuilder) {
428 return addProfile('live', encoder, profile, builder)
429 },
430
431 addVODProfile (encoder: string, profile: string, builder: EncoderOptionsBuilder) {
432 return addProfile('vod', encoder, profile, builder)
433 },
434
435 addLiveEncoderPriority (streamType: 'audio' | 'video', encoder: string, priority: number) {
436 return addEncoderPriority('live', streamType, encoder, priority)
437 },
438
439 addVODEncoderPriority (streamType: 'audio' | 'video', encoder: string, priority: number) {
440 return addEncoderPriority('vod', streamType, encoder, priority)
441 }
442 }
443 }
357} 444}