PageSourceSearch

https://www.bravotv.com/modules/custom/ls_nielsen/js/nielsen_jw_player_plugin.js

js bravotv.com collected 2026-10-01 08:45:12 UTC 5,437 bytes, 164 lines download raw bytes

1/**
2 * Nielsen analytics plugin for JW player.
3 *
4 * Note that as a JW player plugin, this is not exposed as a Drupal library.
5 * Rather, the JW player plugin will load this when ready.
6 *
7 * @param {object} player
8 *   Instance of the player API with which the plugin is being registered.
9 * @param {object} pluginConfig
10 *   Config block passed in player().setup(). The configuration consists of the
11 *   following:
12 *   - appId: Unique ID assigned to the player/site and configured by product.
13 *   - debug: Turn on debug mode for verbose messaging in the Javascript console
14 *     during initialization and playback.
15 *   - getContentMetadataFromJwPlaylistItem: Function for mapping a JW playlist
16 *     item to the content metadata expected by Nielsen. For details on the
17 *     content metadata requirements see
18 *     https://engineeringportal.nielsen.com/docs/DCR_Video_Browser_SDK#Content_Metadata.
19 *     The function will receive a single argument, a JW playlist item. See
20 *     https://docs.jwplayer.com/players/reference/playlists#playlist. The
21 *     function is expected to return an object that is the Nielsen content
22 *     metadata that will be sent in calls to ggPM('loadMetadata'. <object>).
23 *     See https://engineeringportal.nielsen.com/docs/loadMetadata_(Browser).
24 * @param {Element} container
25 *   DIV created in the DOM for this plugin.
26 *
27 * @see https://docs.jwplayer.com/players/docs/jw8-add-a-custom-or-third-party-plugin
28 */
29function nielsenJwPlayerPlugin(player, pluginConfig, container) {
30  'use strict';
31
32  pluginConfig = pluginConfig || {};
33
34  const {
35    appId,
36    debug = true,
37    getContentMetadataFromJwPlaylistItem,
38  } = pluginConfig;
39  const nielsenSdk = window.NOLBUNDLE.nlsQ(
40    appId,
41    'nlsnInstance',
42    debug ? { nol_sdkDebug: 'debug' } : {},
43  );
44  const playbackStatus = {
45    adMetadataLoaded: false,
46    previousPlayheadSecond: 0,
47    playheadPosition: 0,
48    previousAdPlayheadSecond: 0,
49    adPlayheadPosition: 0,
50  };
51
52  /**
53   * Log a message to the console if development mode.
54   *
55   * @param {string} message
56   *   Message to log to the console.
57   * @param {object} obj
58   *   (optional) Object to log.
59   * @param {object} config
60   *   (optional) Config options including:
61   *   - prefix: Override the prefix for the message logged to the console.
62   */
63  const log = (message, obj = null, { prefix = 'lifestyle nielsen' } = {}) => {
64    if (debug) {
65      const output = `[${prefix}]: ${message}`;
66      if (obj === null) {
67        console.log(output);
68      } else {
69        console.log(output, obj);
70      }
71    }
72  };
73
74  const handlePlaylistItem = ({ item }) => {
75    log('playlistItem', item);
76    // Load content metadata.
77    nielsenSdk.ggPM('loadMetadata', getContentMetadataFromJwPlaylistItem(item));
78  };
79
80  const handleTime = ({ position }) => {
81    log('time', position);
82    const currentSecond = Math.floor(position);
83    if (currentSecond > playbackStatus.previousPlayheadSecond) {
84      nielsenSdk.ggPM('setPlayheadPosition', currentSecond);
85      playbackStatus.previousPlayheadSecond = currentSecond;
86    }
87    playbackStatus.playheadPosition = position;
88  };
89
90  const handleAdTime = ({
91    adposition: adPosition,
92    duration: durationInSeconds,
93    position,
94    freewheel: {
95      ad: { adId },
96    },
97  }) => {
98    log('adTime', { adPosition, durationInSeconds, adId, position });
99    if (!playbackStatus.adMetadataLoaded) {
100      nielsenSdk.ggPM('loadMetadata', {
101        type: getAdType(adPosition),
102        assetid: adId,
103      });
104      playbackStatus.adMetadataLoaded = true;
105    }
106    const currentSecond = Math.floor(position);
107    if (currentSecond > playbackStatus.previousAdPlayheadSecond) {
108      nielsenSdk.ggPM('setPlayheadPosition', currentSecond);
109      playbackStatus.previousAdPlayheadSecond = currentSecond;
110    }
111    playbackStatus.adPlayheadPosition = position;
112  };
113
114  const handleAdComplete = () => {
115    log('adComplete');
116    nielsenSdk.ggPM('stop', playbackStatus.adPlayheadPosition);
117    playbackStatus.adPlayheadPosition = 0;
118    playbackStatus.adMetadataLoaded = false;
119  };
120
121  const handleFirstFrame = () => {
122    log('firstFrame');
123    const item = player.getPlaylistItem(player.getPlaylistIndex());
124    nielsenSdk.ggPM('loadMetadata', getContentMetadataFromJwPlaylistItem(item));
125  };
126
127  const handleComplete = () => {
128    log('complete');
129    nielsenSdk.ggPM('stop', playbackStatus.playheadPosition);
130    playbackStatus.previousPlayheadSecond = 0;
131    playbackStatus.playheadPosition = 0;
132  };
133
134  const getAdType = (jwAdPosition) => {
135    /* eslint-disable no-nested-ternary */
136    return jwAdPosition === 'pre'
137      ? 'preroll'
138      : jwAdPosition === 'mid'
139        ? 'midroll'
140        : jwAdPosition === 'post'
141          ? 'postroll'
142          : 'ad';
143    /* eslint-enable no-nested-ternary */
144  };
145
146  // Setup all or our event handlers when the player is ready.
147  player.on('ready', () => {
148    log('ready');
149    player.on('playlistItem', handlePlaylistItem);
150    player.on('adTime', handleAdTime);
151    player.on('adComplete', handleAdComplete);
152    player.on('firstFrame', handleFirstFrame);
153    player.on('complete', handleComplete);
154    player.on('time', handleTime);
155  });
156  log('pluginConfig', pluginConfig);
157}
158
159// Plug entrypoint into player plugin architecture.
160(window.jwplayerPluginJsonp || window.jwplayer().registerPlugin)(
161  'nielsen_jw_player_plugin',
162  '8.24',
163  nielsenJwPlayerPlugin,
164);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.