UNPKG

@xnstream/player-sdk

Version:

XStream Player SDK - A powerful video player SDK for streaming content

80 lines 3.19 kB
import { WatchtimeCollector } from './WatchtimeCollector'; import { DeliveryCollector } from './DeliveryCollector'; import { generateSignature, base64Encode, generateRandomSalt } from '../utils/crypto'; import { canonicalJSONStringify } from '../utils/utils'; export class AnalyticsCollector { constructor(options) { this.flushTimeout = null; this.collectors = []; this.flushInterval = options.flushIntervalMs || 5000; this.context = options; this.context.ref = this.getDocumentReferer(); // Create collectors this.collectors.push(new DeliveryCollector(this.context.stream_code, this.context.hlsPlayer, this.context.resource, this.context.edge_id, options.userContext)); this.collectors.push(new WatchtimeCollector(this.context.video, this.context.stream_code, this.context.resource, this.context.edge_id, options.userContext)); // Auto-flush events at regular intervals this.flushTimeout = setInterval(() => { this.flush(); }, this.flushInterval); } async flush() { // First flush all collectors const events = this.collectors.flatMap(collector => collector.flush()); if (!events.length) return; const nce = generateRandomSalt(); const at = Math.floor(Date.now() / 1000); const message = [ canonicalJSONStringify(events), nce, at, this.context.appId, this.context.sid, this.context.resource.resource.id, this.context.ref, this.context.resource.resource.organization_id, ].join('|'); const sig = base64Encode(generateSignature(message, this.context.appId)); try { await fetch(`${this.context.host}/player/stats/report`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ app_id: this.context.appId, sid: this.context.sid, nce: nce, at: at, sig: sig, rs: this.context.resource.resource.id, data: { events, device: this.context.device, version: this.context.appVersion, pb_id: this.context.pb_id, ref: this.context.ref, ow: this.context.resource.resource.organization_id, }, }), }); } catch (error) { console.error('Failed to send analytics:', error); } } destroy() { this.flush(); if (this.flushTimeout) { clearInterval(this.flushTimeout); this.collectors.forEach(collector => collector.destroy()); } } getDocumentReferer() { let referer = document.referrer; if (referer === '' || !referer) referer = document.location.href; return referer; } } //# sourceMappingURL=AnalyticsCollector.js.map