From 989a2c08f2c8418ef564c7143cc267504111ac28 Mon Sep 17 00:00:00 2001 From: JonathanTGold <62672270+JonathanTGold@users.noreply.github.com> Date: Mon, 27 Sep 2021 17:43:42 +0200 Subject: [PATCH] fix(FEC-11547): The thumbnalils images should be relative to the VTT file adress by default (#607) Currently the thumbnalils images URL is relative to the application domain by default, Although the convention is that they should be relative to the vtt file adress solves: FEC-11547 related pr: https://github.com/kaltura/kaltura-player-js/pull/494 --- .../types/exteranl-thumbnails-object.js | 1 - src/thumbnail/external-thumbnails-handler.js | 11 ++++-- test/src/assets/thumbnails1.vtt | 13 ++++--- test/src/assets/thumbnails2.vtt | 15 +++----- test/src/assets/thumbnails3.vtt | 18 +++++----- .../external-thumbnails-handler.spec.js | 34 +++++++++---------- 6 files changed, 46 insertions(+), 46 deletions(-) diff --git a/flow-typed/types/exteranl-thumbnails-object.js b/flow-typed/types/exteranl-thumbnails-object.js index c5ceb0be5..208bde82d 100644 --- a/flow-typed/types/exteranl-thumbnails-object.js +++ b/flow-typed/types/exteranl-thumbnails-object.js @@ -1,5 +1,4 @@ // @flow declare type PKExternalThumbnailsConfig = { - imgBaseUrl?: string, vttUrl: string }; diff --git a/src/thumbnail/external-thumbnails-handler.js b/src/thumbnail/external-thumbnails-handler.js index c536ab2ae..e94d55f55 100644 --- a/src/thumbnail/external-thumbnails-handler.js +++ b/src/thumbnail/external-thumbnails-handler.js @@ -12,6 +12,8 @@ import {Html5EventType} from '../event/event-type'; const VTT_INCLUDES_SIZE_ONLY: RegExp = /#wh=/i; const VTT_INCLUDES_SIZE_AND_COORDS: RegExp = /#xywh=/i; +const RELATIVE_PATH_PATTERN: RegExp = new RegExp('^/[^/].+'); + class ExternalThumbnailsHandler extends FakeEventTarget { constructor() { super(); @@ -218,7 +220,7 @@ class ExternalThumbnailsHandler extends FakeEventTarget { */ _extractCueMetadata(vttCue: VTTCue, thumbnailsConfig: PKExternalThumbnailsConfig): PKThumbnailVttCue { const {startTime, endTime, text} = vttCue; - const {imgBaseUrl} = thumbnailsConfig; + const imgBaseUrl = thumbnailsConfig.vttUrl.substring(0, thumbnailsConfig.vttUrl.lastIndexOf('/')); const isVTTIncludesImgSizeOnly: boolean = VTT_INCLUDES_SIZE_ONLY.test(text); const isVTTIncludesImgSizeAndCoords: boolean = VTT_INCLUDES_SIZE_AND_COORDS.test(text); let isValidThumbnailVTTFormat: boolean = false; @@ -244,7 +246,12 @@ class ExternalThumbnailsHandler extends FakeEventTarget { imgUrl = text; isValidThumbnailVTTFormat = !!text; } - imgUrl = imgBaseUrl ? `${imgBaseUrl}/${imgUrl}` : imgUrl; + + if (!(imgUrl.indexOf('http://') === 0 || imgUrl.indexOf('https://') === 0)) { + imgUrl = RELATIVE_PATH_PATTERN.test(imgUrl) ? imgUrl.substring(1) : imgUrl; + imgUrl = `${imgBaseUrl}/${imgUrl}`; + } + if (!isValidThumbnailVTTFormat) { throw new Error(Error.Severity.RECOVERABLE, Error.Category.TEXT, Error.Code.INVALID_VTT_THUMBNAILS_FILE, { message: 'error while parsing the vtt cues - invalid cue', diff --git a/test/src/assets/thumbnails1.vtt b/test/src/assets/thumbnails1.vtt index 9a924eb02..7d5f73fd9 100644 --- a/test/src/assets/thumbnails1.vtt +++ b/test/src/assets/thumbnails1.vtt @@ -1,20 +1,19 @@ WEBVTT 00:00:00.000 --> 00:00:05.000 -base/test/src/assets/00000002.jpg +00000002.jpg 00:00:05.000 --> 00:00:10.000 -base/test/src/assets/00000003.jpg +00000003.jpg 00:00:10.000 --> 00:00:15.000 -base/test/src/assets/00000004.jpg +00000004.jpg 00:00:15.000 --> 00:00:20.000 -base/test/src/assets/00000005.jpg +00000005.jpg 00:00:20.000 --> 00:00:25.000 -base/test/src/assets/00000006.jpg +00000006.jpg 00:00:25.000 --> 00:00:30.000 -base/test/src/assets/00000007.jpg - +00000007.jpg diff --git a/test/src/assets/thumbnails2.vtt b/test/src/assets/thumbnails2.vtt index edeb52569..74beeb846 100644 --- a/test/src/assets/thumbnails2.vtt +++ b/test/src/assets/thumbnails2.vtt @@ -1,21 +1,16 @@ WEBVTT 00:00.000 --> 00:05.000 -base/test/src/assets/00000002.jpg#wh=200,80 +00000002.jpg#wh=200,80 00:05.000 --> 00:10.000 -base/test/src/assets/00000003.jpg#wh=200,80 +00000003.jpg#wh=200,80 00:10.000 --> 00:15.000 -base/test/src/assets/00000004.jpg#wh=200,80 +00000004.jpg#wh=200,80 00:15.000 --> 00:20.000 -base/test/src/assets/00000005.jpg#wh=200,80 +00000005.jpg#wh=200,80 00:20.000 --> 00:25.000 -base/test/src/assets/00000006.jpg#wh=200,80 - - - - - +00000006.jpg#wh=200,80 diff --git a/test/src/assets/thumbnails3.vtt b/test/src/assets/thumbnails3.vtt index fff02d4e2..3f4b884e7 100644 --- a/test/src/assets/thumbnails3.vtt +++ b/test/src/assets/thumbnails3.vtt @@ -1,31 +1,31 @@ WEBVTT 00:00.000 --> 00:05.000 -base/test/src/assets/bbb-sprite.jpeg#xywh=0,0,128,72 +bbb-sprite.jpeg#xywh=0,0,128,72 00:05.000 --> 00:10.000 -base/test/src/assets/bbb-sprite.jpeg#xywh=128,0,128,72 +bbb-sprite.jpeg#xywh=128,0,128,72 00:10.000 --> 00:15.000 -base/test/src/assets/bbb-sprite.jpeg#xywh=256,0,128,72 +bbb-sprite.jpeg#xywh=256,0,128,72 00:15.000 --> 00:20.000 -base/test/src/assets/bbb-sprite.jpeg#xywh=384,0,128,72 +bbb-sprite.jpeg#xywh=384,0,128,72 00:20.000 --> 00:25.000 -base/test/src/assets/bbb-sprite.jpeg#xywh=512,0,128,72 +bbb-sprite.jpeg#xywh=512,0,128,72 00:25.000 --> 00:30.000 -base/test/src/assets/bbb-sprite.jpeg#xywh=640,0,128,72 +bbb-sprite.jpeg#xywh=640,0,128,72 00:30.000 --> 00:35.000 -base/test/src/assets/bbb-sprite.jpeg#xywh=768,0,128,72 +bbb-sprite.jpeg#xywh=768,0,128,72 00:35.000 --> 00:40.000 -base/test/src/assets/bbb-sprite.jpeg#xywh=896,0,128,72 +bbb-sprite.jpeg#xywh=896,0,128,72 00:40.000 --> 00:45.000 -base/test/src/assets/bbb-sprite.jpeg#xywh=1024,0,128,72 +bbb-sprite.jpeg#xywh=1024,0,128,72 diff --git a/test/src/thumbnail/external-thumbnails-handler.spec.js b/test/src/thumbnail/external-thumbnails-handler.spec.js index fded0b1c1..92ca3857d 100644 --- a/test/src/thumbnail/external-thumbnails-handler.spec.js +++ b/test/src/thumbnail/external-thumbnails-handler.spec.js @@ -6,15 +6,15 @@ import {ThumbnailInfo} from '../../../src/thumbnail/thumbnail-info'; let externalThumbnailsHandler: ExternalThumbnailsHandler; const thumbnailsCues = [ - {startTime: 0, endTime: 5, imgUrl: 'base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 0, y: 0}}, - {startTime: 5, endTime: 10, imgUrl: 'base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 128, y: 0}}, - {startTime: 10, endTime: 15, imgUrl: 'base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 256, y: 0}}, - {startTime: 15, endTime: 20, imgUrl: 'base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 384, y: 0}}, - {startTime: 20, endTime: 25, imgUrl: 'base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 512, y: 0}}, - {startTime: 25, endTime: 30, imgUrl: 'base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 640, y: 0}}, - {startTime: 30, endTime: 35, imgUrl: 'base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 768, y: 0}}, - {startTime: 35, endTime: 40, imgUrl: 'base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 896, y: 0}}, - {startTime: 40, endTime: 45, imgUrl: 'base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 1024, y: 0}} + {startTime: 0, endTime: 5, imgUrl: '/base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 0, y: 0}}, + {startTime: 5, endTime: 10, imgUrl: '/base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 128, y: 0}}, + {startTime: 10, endTime: 15, imgUrl: '/base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 256, y: 0}}, + {startTime: 15, endTime: 20, imgUrl: '/base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 384, y: 0}}, + {startTime: 20, endTime: 25, imgUrl: '/base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 512, y: 0}}, + {startTime: 25, endTime: 30, imgUrl: '/base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 640, y: 0}}, + {startTime: 30, endTime: 35, imgUrl: '/base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 768, y: 0}}, + {startTime: 35, endTime: 40, imgUrl: '/base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 896, y: 0}}, + {startTime: 40, endTime: 45, imgUrl: '/base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 1024, y: 0}} ]; describe('ExternalThumbnailsHandler', () => { @@ -43,7 +43,7 @@ describe('ExternalThumbnailsHandler', () => { let time = 0; let x = -128; const nativeVttCues: VTTCue[] = [...thumbnailsCues].map(() => { - return new VTTCue(time, (time += 5), `base/test/src/assets/bbb-sprite.jpeg#xywh=${(x += 128)},0,128,72`); + return new VTTCue(time, (time += 5), `bbb-sprite.jpeg#xywh=${(x += 128)},0,128,72`); }); const thumbnailsConfig: PKExternalThumbnailsConfig = { vttUrl: '/base/test/src/assets/thumbnails3.vtt' @@ -76,12 +76,12 @@ describe('ExternalThumbnailsHandler', () => { }; it('should turn a vtt cue into a thumbnail cue - vtt cue with size and coords options', async () => { - const nativeVTTCue: VTTCue = new VTTCue(0, 5, 'base/test/src/assets/bbb-sprite.jpeg#xywh=0,0,128,72'); + const nativeVTTCue: VTTCue = new VTTCue(0, 5, 'bbb-sprite.jpeg#xywh=0,0,128,72'); const actualParsedCue: ThumbnailInfo = await externalThumbnailsHandler._extractCueMetadata(nativeVTTCue, thumbnailsConfig); const expectedParsedCue: ThumbnailInfo = { startTime: 0, endTime: 5, - imgUrl: 'base/test/src/assets/bbb-sprite.jpeg', + imgUrl: '/base/test/src/assets/bbb-sprite.jpeg', size: {width: 128, height: 72}, coordinates: {x: 0, y: 0} }; @@ -89,12 +89,12 @@ describe('ExternalThumbnailsHandler', () => { }); it('should turn a vtt cue into a thumbnail cue - vtt cue with size options only - (the size options should be ignored) and size and coordinates should be null', async () => { - const nativeVTTCue: VTTCue = new VTTCue(0, 5, 'base/test/src/assets/bbb-sprite.jpeg#wh=128,72'); + const nativeVTTCue: VTTCue = new VTTCue(0, 5, 'bbb-sprite.jpeg#wh=128,72'); const actualParsedCue: ThumbnailInfo = await externalThumbnailsHandler._extractCueMetadata(nativeVTTCue, thumbnailsConfig); const expectedParsedCue: ThumbnailInfo = { startTime: 0, endTime: 5, - imgUrl: 'base/test/src/assets/bbb-sprite.jpeg', + imgUrl: '/base/test/src/assets/bbb-sprite.jpeg', size: null, coordinates: null }; @@ -102,12 +102,12 @@ describe('ExternalThumbnailsHandler', () => { }); it('should turn a vtt cue into a thumbnail cue - vtt cue with url options only - the size options should be should be null', async () => { - const nativeVTTCue: VTTCue = new VTTCue(0, 5, 'base/test/src/assets/bbb-sprite.jpeg#wh=128,72'); + const nativeVTTCue: VTTCue = new VTTCue(0, 5, 'bbb-sprite.jpeg#wh=128,72'); const actualParsedCue: ThumbnailInfo = await externalThumbnailsHandler._extractCueMetadata(nativeVTTCue, thumbnailsConfig); const expectedParsedCue: ThumbnailInfo = { startTime: 0, endTime: 5, - imgUrl: 'base/test/src/assets/bbb-sprite.jpeg', + imgUrl: '/base/test/src/assets/bbb-sprite.jpeg', size: null, coordinates: null }; @@ -115,7 +115,7 @@ describe('ExternalThumbnailsHandler', () => { }); it('should throw an error - invalid thumbnail cue format', () => { - const invalidVttThumbnailFormat: VTTCue = new VTTCue(0, 5, 'base/test/src/assets/bbb-sprite.jpeg#xywh=0,128,72'); + const invalidVttThumbnailFormat: VTTCue = new VTTCue(0, 5, 'bbb-sprite.jpeg#xywh=0,128,72'); expect(() => externalThumbnailsHandler._extractCueMetadata(invalidVttThumbnailFormat, thumbnailsConfig)).to.throw(); }); });