project_viewer.sh
user@portfolio:~$ cat adobe-analytics-video-demo.project

ADOBE ANALYTICS VIDEO PLAYER DEMO

Multi-environment testing platform for Adobe Analytics video player integration with real-time status monitoring

[STATUS] maintenance
[TYPE] web
[DATE] 04.07.2025

[TECH_STACK]

React Vite Adobe Analytics Google IMA SDK Video.js 8 Material-UI Tailwind CSS Radix UI Framer Motion
[PROJECT_DETAILS]

Adobe Analytics Video Player Demo

A sophisticated testing and demonstration platform built to streamline Adobe Analytics video player integration across multiple deployment environments. This application enables QA teams to validate analytics implementations, facilitates client demonstrations of video tracking capabilities, and accelerates integration testing workflows by providing instant environment switching and real-time status monitoring.

Key Features

  • Multi-Environment Support - Seamlessly switch between Development, Integration, and Production environments with automatic script reloading and configuration management, enabling rapid testing across different deployment stages without manual setup

  • Dynamic Player Script Management - Intelligent script loading system that handles cache invalidation and dependency ordering for Adobe Analytics, Google IMA SDK, and environment-specific player bundles, ensuring clean state transitions when switching environments

  • Real-Time Media Status API Polling - Automated polling system that queries media status endpoints every 15 seconds with intelligent error handling for 404s, 5xx errors, and network failures, providing instant feedback on media availability and active status

  • Searchable Media Library - Integrated combobox component that fetches and displays available media items from environment-specific JSON endpoints, enabling quick media selection with auto-complete functionality for efficient testing workflows

  • Custom Media ID Testing - Flexible input system allowing testers to manually specify media IDs for ad-hoc testing scenarios, supporting validation of new content before it appears in the standard media library

  • Stream Event Tracking - Implements Adobe Analytics stream-end event handlers with duplicate call prevention, demonstrating proper integration of video lifecycle events for accurate analytics reporting

  • Visual Status Indicators - Real-time UI feedback with color-coded status messages (loading, success, warning, error) that communicate API response states, script loading progress, and media availability at a glance

  • Player Lifecycle Management - Comprehensive player disposal and recreation logic that prevents memory leaks and ensures clean state when changing media or environments, critical for long-running test sessions

Technical Implementation

Architecture Design

The application implements a component-based architecture using React 18 with functional components and hooks for state management. The player integration follows a ref-based pattern to maintain direct DOM access while preserving React’s declarative model. This hybrid approach enables fine-grained control over the Video.js player lifecycle while leveraging React’s component reusability.

The environment switching mechanism employs a complete teardown-and-rebuild strategy rather than attempting in-place updates. When users change environments (src/App.jsx:334-361), the system:

  1. Disposes of the existing player instance to prevent memory leaks
  2. Removes all player-related DOM elements
  3. Clears global window references to mobilerider objects
  4. Invalidates cached scripts by removing and re-injecting them
  5. Resets all React state to initial values

This approach guarantees clean state transitions and prevents subtle bugs from cached player instances or stale analytics configurations.

Dynamic Script Loading System

The script loading implementation (src/App.jsx:62-123) handles complex dependency chains for third-party libraries:

// Load order: IMA SDK → Adobe Analytics → Player Script
await loadScript('https://imasdk.googleapis.com/js/sdkloader/ima3.js');
await loadScript('https://www.adobe.com/marketingtech/main.min.js');
await loadScript(getPlayerScript(), true); // Environment-specific

Player scripts receive special treatment with aggressive cache invalidation - the system queries for all scripts matching player.min.js and removes them before injecting the environment-specific version. This prevents browsers from serving cached scripts when switching between environments that use different player builds (Dev uses Video.js 8, Production uses a different build).

API Polling with Intelligent Error Handling

The media status API integration (src/App.jsx:138-196) implements a sophisticated polling strategy that differentiates between expected and unexpected error states:

  • 404 Responses: Treated as valid state (media not found) rather than errors, displayed with warning-level UI feedback
  • 5xx Errors: Immediately thrown as exceptions, triggering error state and halting further processing
  • Network Failures: Caught and displayed with error-level UI feedback, but polling continues
  • Success Responses: Parsed and checked for media ID presence in the active array

The 15-second polling interval balances responsiveness with server load, and the implementation includes proper cleanup using React’s effect return functions to prevent polling after component unmount.

Player Event Integration

The stream-end event handler (src/App.jsx:279-295) demonstrates proper integration with Adobe Analytics tracking:

const tempFunctionFlag = () => {
  if (!streamEndCalledRef.current) {
    streamEndCalledRef.current = true;
    // Trigger API call on first stream end only
    fetch(`${getApiUrl()}?ids=${id1}`)
      .then(response => response.json())
      .then(data => console.log('API response on streamend:', data))
  }
};
window.__mr_player.on("streamend", tempFunctionFlag);

The ref-based duplicate call prevention ensures analytics events fire exactly once per stream, preventing inflated metrics from repeated triggers.

Business Impact and Use Cases

QA Testing Efficiency

The multi-environment architecture reduces QA testing time by eliminating manual environment configuration. Testers can validate analytics implementations across all three environments in minutes rather than hours, switching between them with a single button click. The real-time status API integration provides immediate feedback on media availability, preventing wasted time attempting to load unavailable content.

Client Demonstrations

Sales and integration teams use this platform to demonstrate Adobe Analytics video tracking capabilities to prospective clients. The clean UI and instant environment switching enable live demonstrations of how analytics behave across different deployment stages, building confidence in the implementation process.

Integration Testing Workflow

Development teams leverage the custom media ID input to test new content before it reaches the standard media library. This enables validation of analytics configurations for unreleased content, catching integration issues early in the development cycle.

The application has served as the primary testing tool for Video.js 8 migration testing, enabling rapid validation of the new player version across multiple environments before production deployment.

Development Practices

Component Architecture

The application follows a modular component structure with clear separation of concerns:

  • Presentation Components: Radix UI and custom shadcn/ui components (src/components/ui/) provide accessible, reusable UI primitives
  • Feature Components: MediaSelector, EnvironmentSelector, and CustomMediaId encapsulate specific business logic
  • Container Component: App.jsx orchestrates state management, API interactions, and player lifecycle

State Management Strategy

The application uses React’s built-in useState and useRef hooks rather than external state management libraries. This decision was made because:

  1. State is primarily local to the player component
  2. Prop drilling is minimal with only 2 levels of component hierarchy
  3. The complexity of Redux/Zustand would outweigh benefits for this use case

Refs are used strategically for values that need to persist across renders but shouldn’t trigger re-renders (player instances, event handler flags).

Styling Approach

The project combines three styling methodologies:

  • Tailwind CSS: Utility-first classes for rapid UI development
  • Emotion/styled-components: CSS-in-JS for Material-UI component customization
  • Tailwind Merge: Intelligent class name merging to prevent style conflicts

This hybrid approach provides the developer experience of utility classes while maintaining the theming capabilities required by Material-UI.

Build and Deployment

Built with Vite for sub-second hot module replacement during development and optimized production bundles. The project includes Cloudflare Workers integration via Wrangler for edge deployment, enabling low-latency access for global testing teams.

ESLint configuration enforces React best practices including hooks rules and unused variable detection, maintaining code quality across the team.

EOF: Data loaded