UNPKG

@interactive-video-labs/vue

Version:

Thin Vue wrapper for the @interactive-video-labs/core engine. Enables cue-based interactive video playback in Vue 3 applications.

177 lines (174 loc) 5.37 kB
/** * * Thin Vue wrapper for the @interactive-video-labs/core engine. Enables cue-based interactive video playback in Vue 3 applications. * @interactive-video-labs/vue v0.2.0 * @author Taj * @license MIT * */ "use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { default: () => index_default }); module.exports = __toCommonJS(index_exports); var import_vue = require("vue"); var import_core = require("@interactive-video-labs/core"); var index_default = (0, import_vue.defineComponent)({ name: "InteractiveVideo", props: { /** * The URL of the video to be loaded. */ videoUrl: { type: String, required: true }, /** * Callback function for analytics events. */ onAnalyticsEvent: { type: Function }, /** * An array of cue points for interactive events. */ cues: { type: Array }, /** * An object containing translations for the player. */ translations: { type: Object }, /** * Whether the video should start playing automatically. */ autoplay: { type: Boolean, default: false }, /** * Whether the video should loop. */ loop: { type: Boolean, default: false }, /** * The locale to be used for the player. */ locale: { type: String, default: "en" }, /** * The ID of the target HTML element where the player will be mounted. */ targetElementId: { type: String } }, /** * The setup function for the component. * @param props The component's props. * @param attrs The component's attributes. * @param expose Function to expose properties to the parent component. * @returns A render function that creates the component's DOM structure. */ setup(props, { attrs, expose }) { const containerRef = (0, import_vue.ref)(null); const playerRef = (0, import_vue.ref)(null); const playerTargetId = props.targetElementId || `ivlabs-player-${Math.random().toString(36).substr(2, 9)}`; const initializePlayer = () => { if (playerRef.value) { return; } const targetElement = document.getElementById(playerTargetId); if (!targetElement) { console.error(`IVLabsPlayer target element with ID '${playerTargetId}' not found.`); return; } const playerConfig = { ...attrs, videoUrl: props.videoUrl, autoplay: props.autoplay, loop: props.loop, locale: props.locale }; try { const player = new import_core.IVLabsPlayer(playerTargetId, playerConfig); playerRef.value = player; if (props.onAnalyticsEvent) { const analyticsHandler = props.onAnalyticsEvent; const eventsToRegister = [ "PLAYER_LOADED", "VIDEO_STARTED", "VIDEO_PAUSED", "VIDEO_ENDED", "CUE_TRIGGERED", "INTERACTION_COMPLETED", "ERROR" ]; eventsToRegister.forEach((event) => { player.on(event, (payload) => { analyticsHandler(event, payload); }); }); } if (props.cues) { player.loadCues(props.cues); } if (props.translations) { player.loadTranslations(props.locale, props.translations); } } catch (error) { console.error("Error initializing IVLabsPlayer:", error); } }; (0, import_vue.onMounted)(() => { (0, import_vue.nextTick)(() => { initializePlayer(); }); }); (0, import_vue.onUnmounted)(() => { if (playerRef.value) { playerRef.value.destroy(); playerRef.value = null; } }); (0, import_vue.watch)( () => props.cues, (newCues) => { if (playerRef.value && newCues) { playerRef.value.loadCues(newCues); } }, { deep: true } ); (0, import_vue.watch)( () => props.translations, (newTranslations) => { if (playerRef.value && newTranslations) { playerRef.value.loadTranslations(props.locale, newTranslations); } }, { deep: true } ); expose({ playerRef }); return () => { if (props.targetElementId) { return null; } else { return (0, import_vue.h)("div", { ref: containerRef, id: playerTargetId, // Use the generated ID for this div style: { width: "100%", height: "auto" }, "data-testid": "interactive-video-container" }); } }; } });