diff options
author | Chocobozzz <me@florianbigard.com> | 2022-12-02 14:47:21 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2022-12-02 15:25:20 +0100 |
commit | 71e3e879c0616882ee82a0e44f8c2e5ee9698a3e (patch) | |
tree | 14452d26d240eb6d44178b76fc2dabda4cfc9428 /client/src/assets/player | |
parent | 04509c43254dc232c61681ac4bb98e09fd126115 (diff) | |
download | PeerTube-71e3e879c0616882ee82a0e44f8c2e5ee9698a3e.tar.gz PeerTube-71e3e879c0616882ee82a0e44f8c2e5ee9698a3e.tar.zst PeerTube-71e3e879c0616882ee82a0e44f8c2e5ee9698a3e.zip |
Support reinjecting token in private m3u8 playlist
Diffstat (limited to 'client/src/assets/player')
4 files changed, 46 insertions, 35 deletions
diff --git a/client/src/assets/player/shared/manager-options/hls-options-builder.ts b/client/src/assets/player/shared/manager-options/hls-options-builder.ts index 497a97436..63e9fa8c8 100644 --- a/client/src/assets/player/shared/manager-options/hls-options-builder.ts +++ b/client/src/assets/player/shared/manager-options/hls-options-builder.ts | |||
@@ -32,6 +32,7 @@ export class HLSOptionsBuilder { | |||
32 | 32 | ||
33 | const p2pMediaLoader: P2PMediaLoaderPluginOptions = { | 33 | const p2pMediaLoader: P2PMediaLoaderPluginOptions = { |
34 | requiresAuth: commonOptions.requiresAuth, | 34 | requiresAuth: commonOptions.requiresAuth, |
35 | videoFileToken: commonOptions.videoFileToken, | ||
35 | 36 | ||
36 | redundancyUrlManager, | 37 | redundancyUrlManager, |
37 | type: 'application/x-mpegURL', | 38 | type: 'application/x-mpegURL', |
diff --git a/client/src/assets/player/shared/p2p-media-loader/p2p-media-loader-plugin.ts b/client/src/assets/player/shared/p2p-media-loader/p2p-media-loader-plugin.ts index b608ee3e2..e6f525fea 100644 --- a/client/src/assets/player/shared/p2p-media-loader/p2p-media-loader-plugin.ts +++ b/client/src/assets/player/shared/p2p-media-loader/p2p-media-loader-plugin.ts | |||
@@ -3,7 +3,7 @@ import videojs from 'video.js' | |||
3 | import { Events, Segment } from '@peertube/p2p-media-loader-core' | 3 | import { Events, Segment } from '@peertube/p2p-media-loader-core' |
4 | import { Engine, initHlsJsPlayer, initVideoJsContribHlsJsPlayer } from '@peertube/p2p-media-loader-hlsjs' | 4 | import { Engine, initHlsJsPlayer, initVideoJsContribHlsJsPlayer } from '@peertube/p2p-media-loader-hlsjs' |
5 | import { logger } from '@root-helpers/logger' | 5 | import { logger } from '@root-helpers/logger' |
6 | import { timeToInt } from '@shared/core-utils' | 6 | import { addQueryParams, timeToInt } from '@shared/core-utils' |
7 | import { P2PMediaLoaderPluginOptions, PlayerNetworkInfo } from '../../types' | 7 | import { P2PMediaLoaderPluginOptions, PlayerNetworkInfo } from '../../types' |
8 | import { registerConfigPlugin, registerSourceHandler } from './hls-plugin' | 8 | import { registerConfigPlugin, registerSourceHandler } from './hls-plugin' |
9 | 9 | ||
@@ -39,46 +39,37 @@ class P2pMediaLoaderPlugin extends Plugin { | |||
39 | super(player) | 39 | super(player) |
40 | 40 | ||
41 | this.options = options | 41 | this.options = options |
42 | this.startTime = timeToInt(options.startTime) | ||
42 | 43 | ||
43 | // FIXME: typings https://github.com/Microsoft/TypeScript/issues/14080 | 44 | // FIXME: typings https://github.com/Microsoft/TypeScript/issues/14080 |
44 | if (!(videojs as any).Html5Hlsjs) { | 45 | if (!(videojs as any).Html5Hlsjs) { |
45 | logger.warn('HLS.js does not seem to be supported. Try to fallback to built in HLS.') | 46 | if (player.canPlayType('application/vnd.apple.mpegurl')) { |
46 | 47 | this.fallbackToBuiltInIOS() | |
47 | let message: string | 48 | return |
48 | if (!player.canPlayType('application/vnd.apple.mpegurl')) { | ||
49 | message = 'Cannot fallback to built-in HLS' | ||
50 | } else if (options.requiresAuth) { | ||
51 | message = 'Video requires auth which is not compatible to build-in HLS player' | ||
52 | } | 49 | } |
53 | 50 | ||
54 | if (message) { | 51 | const message = 'HLS.js does not seem to be supported. Cannot fallback to built-in HLS' |
55 | logger.warn(message) | 52 | logger.warn(message) |
56 | 53 | ||
57 | const error: MediaError = { | 54 | const error: MediaError = { |
58 | code: MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED, | 55 | code: MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED, |
59 | message, | 56 | message, |
60 | MEDIA_ERR_ABORTED: MediaError.MEDIA_ERR_ABORTED, | 57 | MEDIA_ERR_ABORTED: MediaError.MEDIA_ERR_ABORTED, |
61 | MEDIA_ERR_DECODE: MediaError.MEDIA_ERR_DECODE, | 58 | MEDIA_ERR_DECODE: MediaError.MEDIA_ERR_DECODE, |
62 | MEDIA_ERR_NETWORK: MediaError.MEDIA_ERR_NETWORK, | 59 | MEDIA_ERR_NETWORK: MediaError.MEDIA_ERR_NETWORK, |
63 | MEDIA_ERR_SRC_NOT_SUPPORTED: MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED | 60 | MEDIA_ERR_SRC_NOT_SUPPORTED: MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED |
64 | } | ||
65 | |||
66 | player.ready(() => player.error(error)) | ||
67 | return | ||
68 | } | 61 | } |
69 | 62 | ||
70 | // Workaround to force video.js to not re create a video element | 63 | player.ready(() => player.error(error)) |
71 | (this.player as any).playerElIngest_ = this.player.el().parentNode | 64 | return |
72 | } else { | ||
73 | // FIXME: typings https://github.com/Microsoft/TypeScript/issues/14080 | ||
74 | (videojs as any).Html5Hlsjs.addHook('beforeinitialize', (videojsPlayer: any, hlsjs: any) => { | ||
75 | this.hlsjs = hlsjs | ||
76 | }) | ||
77 | |||
78 | initVideoJsContribHlsJsPlayer(player) | ||
79 | } | 65 | } |
80 | 66 | ||
81 | this.startTime = timeToInt(options.startTime) | 67 | // FIXME: typings https://github.com/Microsoft/TypeScript/issues/14080 |
68 | (videojs as any).Html5Hlsjs.addHook('beforeinitialize', (_videojsPlayer: any, hlsjs: any) => { | ||
69 | this.hlsjs = hlsjs | ||
70 | }) | ||
71 | |||
72 | initVideoJsContribHlsJsPlayer(player) | ||
82 | 73 | ||
83 | player.src({ | 74 | player.src({ |
84 | type: options.type, | 75 | type: options.type, |
@@ -88,9 +79,7 @@ class P2pMediaLoaderPlugin extends Plugin { | |||
88 | player.ready(() => { | 79 | player.ready(() => { |
89 | this.initializeCore() | 80 | this.initializeCore() |
90 | 81 | ||
91 | if ((videojs as any).Html5Hlsjs) { | 82 | this.initializePlugin() |
92 | this.initializePlugin() | ||
93 | } | ||
94 | }) | 83 | }) |
95 | } | 84 | } |
96 | 85 | ||
@@ -199,6 +188,25 @@ class P2pMediaLoaderPlugin extends Plugin { | |||
199 | private arraySum (data: number[]) { | 188 | private arraySum (data: number[]) { |
200 | return data.reduce((a: number, b: number) => a + b, 0) | 189 | return data.reduce((a: number, b: number) => a + b, 0) |
201 | } | 190 | } |
191 | |||
192 | private fallbackToBuiltInIOS () { | ||
193 | logger.info('HLS.js does not seem to be supported. Fallback to built-in HLS.'); | ||
194 | |||
195 | // Workaround to force video.js to not re create a video element | ||
196 | (this.player as any).playerElIngest_ = this.player.el().parentNode | ||
197 | |||
198 | this.player.src({ | ||
199 | type: this.options.type, | ||
200 | src: addQueryParams(this.options.src, { | ||
201 | videoFileToken: this.options.videoFileToken(), | ||
202 | reinjectVideoFileToken: 'true' | ||
203 | }) | ||
204 | }) | ||
205 | |||
206 | this.player.ready(() => { | ||
207 | this.initializeCore() | ||
208 | }) | ||
209 | } | ||
202 | } | 210 | } |
203 | 211 | ||
204 | videojs.registerPlugin('p2pMediaLoader', P2pMediaLoaderPlugin) | 212 | videojs.registerPlugin('p2pMediaLoader', P2pMediaLoaderPlugin) |
diff --git a/client/src/assets/player/shared/p2p-media-loader/segment-validator.ts b/client/src/assets/player/shared/p2p-media-loader/segment-validator.ts index a7ee91950..3c76d63f7 100644 --- a/client/src/assets/player/shared/p2p-media-loader/segment-validator.ts +++ b/client/src/assets/player/shared/p2p-media-loader/segment-validator.ts | |||
@@ -2,6 +2,7 @@ import { basename } from 'path' | |||
2 | import { Segment } from '@peertube/p2p-media-loader-core' | 2 | import { Segment } from '@peertube/p2p-media-loader-core' |
3 | import { logger } from '@root-helpers/logger' | 3 | import { logger } from '@root-helpers/logger' |
4 | import { wait } from '@root-helpers/utils' | 4 | import { wait } from '@root-helpers/utils' |
5 | import { removeQueryParams } from '@shared/core-utils' | ||
5 | import { isSameOrigin } from '../common' | 6 | import { isSameOrigin } from '../common' |
6 | 7 | ||
7 | type SegmentsJSON = { [filename: string]: string | { [byterange: string]: string } } | 8 | type SegmentsJSON = { [filename: string]: string | { [byterange: string]: string } } |
@@ -24,7 +25,7 @@ function segmentValidatorFactory (options: { | |||
24 | // Wait for hash generation from the server | 25 | // Wait for hash generation from the server |
25 | if (isLive) await wait(1000) | 26 | if (isLive) await wait(1000) |
26 | 27 | ||
27 | const filename = basename(segment.url) | 28 | const filename = basename(removeQueryParams(segment.url)) |
28 | 29 | ||
29 | const segmentValue = (await segmentsJSON)[filename] | 30 | const segmentValue = (await segmentsJSON)[filename] |
30 | 31 | ||
diff --git a/client/src/assets/player/types/peertube-videojs-typings.ts b/client/src/assets/player/types/peertube-videojs-typings.ts index 3d9d5270e..c60154f3b 100644 --- a/client/src/assets/player/types/peertube-videojs-typings.ts +++ b/client/src/assets/player/types/peertube-videojs-typings.ts | |||
@@ -168,6 +168,7 @@ type P2PMediaLoaderPluginOptions = { | |||
168 | loader: P2PMediaLoader | 168 | loader: P2PMediaLoader |
169 | 169 | ||
170 | requiresAuth: boolean | 170 | requiresAuth: boolean |
171 | videoFileToken: () => string | ||
171 | } | 172 | } |
172 | 173 | ||
173 | export type P2PMediaLoader = { | 174 | export type P2PMediaLoader = { |