@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
JavaScript
/**
*
* 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
*
*/
;
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"
});
}
};
}
});