From 50383e226991a9a8df9562f453762648168d7106 Mon Sep 17 00:00:00 2001 From: mister-ben Date: Mon, 4 Dec 2023 20:38:13 +0100 Subject: [PATCH] feat: Add exclusion rules (#72) Co-authored-by: bcbclifford --- README.md | 8 ++++++- src/plugin.js | 28 ++++++++++++++++++++++-- test/plugin.test.js | 53 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d6932d7..9ab6267 100644 --- a/README.md +++ b/README.md @@ -43,12 +43,18 @@ Defaults to `https://players.brightcove.net/{accountId}/{playerId}_{embedId}/ind `keywords` - if `true`, include tags as keywords. Default is `false`. -`excludeTags` - array of tags to not include as keywords, e.g. `["youtubesync"]` +`excludeTags` - array of tags to not include as keywords in the schema metadata, e.g. `["youtubesync"]` `baseObject` - an option object of properties onto which to build the video specific metadata. For example this could be used to include a publisher object: `includeEmbedUrl` - if `false`, no embed url is included. Inlcuding thisURL may be expected by search engines. Default is `true`. +`skipRules` - used to exclude videos from having schema metadata generated, based on their video cloud metadata. Can be tags and / or custom fields. If multiple tags, fields or both are specified, matching any excludes. + +`skipRules.customFields` - any object of field-value pairs. If a field present and set to the value in the video's custom fields, no schema metadata is created. e.g. `{category: 'unlisted'}` + +`skipRules.tags` - any array of one or more tags. If any one is present in the video's metadata, no schema metadata is created. e.g. `['notthistag']` + `transcript` - if `true`, a captions or subtitles track with a matching language will be added as a transcript. Default is `false`. `transcriptMatchAny` - if `true` and `transcript` is also `true`, a transcript will be added from the first usable track, if there is no language match. Default is `false`. diff --git a/src/plugin.js b/src/plugin.js index c000496..57957e6 100644 --- a/src/plugin.js +++ b/src/plugin.js @@ -12,7 +12,11 @@ const defaults = { includeEmbedUrl: true, preferLongDescription: false, transcript: false, - transcriptMatchAny: false + transcriptMatchAny: false, + skipRules: { + tags: [], + customFields: {} + } }; const mergeOptions = videojs.obj ? videojs.obj.merge : videojs.mergeOptions; @@ -30,7 +34,7 @@ const mergeOptions = videojs.obj ? videojs.obj.merge : videojs.mergeOptions; * @param {boolean} [options.keywords] * Whether to include tags as keywords * @param {Array} [options.excludeTags] - * If including tags, an array of tags to exclude + * If including tags, an array of tags to exclude from the schema metadata * @param {Object} [options.baseObject] * A template object to build the schema onto * @param {boolean} [options.includeEmbedUrl] @@ -41,6 +45,13 @@ const mergeOptions = videojs.obj ? videojs.obj.merge : videojs.mergeOptions; * Whether to include a transcript from a subtitles or captions track * @param {boolean} [options.transcriptMatchAny] * Whether to return a transcript if there's a track but no language match + * @param {Object} [options.skipRules] + * An object that defines whether to not generate metadata based on metadata rules + * @param {string[]} [options.skipRules.tags] + * If any tag is present, do not generate metadata + * @param {Object} [options.skipRules.customFields] + * An object of custom fields e.g. `{ fieldName: "value" }`. If any field is set to its + * specified value, then schema metadata is not generated for the video */ const schema = function(options) { // Add element for this player to DOM @@ -60,6 +71,19 @@ const schema = function(options) { const mediainfo = this.catalog.getMetadata ? this.catalog.getMetadata({lang: this.language()}) : this.mediainfo; + if ( + (options.skipRules.tags && options.skipRules.tags.some((t) => { + return mediainfo.tags.includes(t); + })) || + (options.skipRules.customFields && Object.keys(options.skipRules.customFields).some((f) => { + return mediainfo.customFields[f] === options.skipRules.customFields[f]; + })) + ) { + videojs.log.debug('Skipping generating schema metadata based on skip rule.'); + this.schemaEl_.textContent = ''; + return; + } + const ld = mergeOptions(options.baseObject, { '@context': 'http://schema.org/', '@type': 'VideoObject', diff --git a/test/plugin.test.js b/test/plugin.test.js index 88de9b0..42f5ad7 100644 --- a/test/plugin.test.js +++ b/test/plugin.test.js @@ -349,3 +349,56 @@ QUnit.test('can add transcript', function(assert) { mo.observe(this.player.schemaEl_, {childList: true}); }); + +QUnit.test('skips videos that should be skipped because of tags', function(assert) { + this.player.mediainfo = { + id: 1234, + referenceId: 'xyz', + name: 'NAME', + description: '', + duration: 3661, + publishedAt: '2019-02-12T09:07:44', + poster: 'https://loremflickr.com/1280/720', + tags: ['one', 'two', 'three'] + }; + this.player.schema({ + skipRules: { + tags: ['two'] + } + }); + // Setting dummy test, just to verify that it gets cleared + this.player.schemaEl_.textContent = 'xxx'; + this.player.trigger('error'); + this.clock.tick(1); + + assert.equal(this.player.schemaEl_.textContent, '', 'no metadata for video with matching tag'); +}); + +QUnit.test('skips videos that should be skipped because of custom fields', function(assert) { + this.player.mediainfo = { + id: 1234, + referenceId: 'xyz', + name: 'NAME', + description: '', + duration: 3661, + publishedAt: '2019-02-12T09:07:44', + poster: 'https://loremflickr.com/1280/720', + tags: ['one', 'two', 'three'], + customFields: { + field1: 'value' + } + }; + this.player.schema({ + skipRules: { + customFields: { + field1: 'value' + } + } + }); + // Setting dummy test, just to verify that it gets cleared + this.player.schemaEl_.textContent = 'xxx'; + this.player.trigger('error'); + this.clock.tick(1); + + assert.equal(this.player.schemaEl_.textContent, '', 'no metadata for video with matching custom field'); +});