1- # Simple Freewheel web player
1+ # 🎬 Freewheel HTML5 Video Player
22
3- ## Demo
4- You can see the live player here: [ GitHub Pages Demo] ( https://pzanella.github.io/freewheel-html5-video-player/ )
3+ ** Exploration & Documentation** - A simple demo and documentation project exploring the Freewheel client-side library integration with HLS streaming.
54
6- ## Quickstart
7- The project requires Node.js version 20 or higher, you can use [ NVM] ( https://github.com/nvm-sh/nvm ) .
8- <br />
9- First, you need to install the dependencies. Run the following command:
5+ ## ℹ️ Project Purpose
6+
7+ This project serves as a learning resource for understanding:
8+ - Freewheel client-side ad insertion
9+ - HLS streaming with adaptive bitrate
10+ - State management patterns
11+ - Building video players with Preact
12+
13+ ** Note** : This is a basic implementation for educational purposes, not production-ready.
14+
15+ ## 🎮 Features
16+
17+ - ** HLS Streaming** : Adaptive bitrate streaming via HLS.js
18+ - ** Freewheel Integration** : Client-side ad request and insertion
19+ - ** Basic Controls** : Play/pause and mute/unmute buttons
20+ - ** Click-to-Play** : Manual playback initiation
21+ - ** Debug Logging** : Query parameter ` ?log ` for console output
22+
23+ ## 🚀 Quick Start
24+
25+ ### Prerequisites
26+ - Node.js 18+ ([ install NVM] ( https://github.com/nvm-sh/nvm ) )
27+ - pnpm package manager
28+
29+ ### Development
30+
31+ 1 . Install dependencies:
32+ ``` bash
33+ pnpm install
34+ ```
35+
36+ 2 . Start development server:
1037``` bash
11- npm i
38+ pnpm dev
1239```
13- After that, run this command to preview the project locally:
40+
41+ The app will be available at ` http://localhost:5173 `
42+
43+ ### Production Build
44+
1445``` bash
15- npm run dev
46+ pnpm build
1647```
1748
18- ## Building for Production
19- To build the project for production:
49+ Output will be in the ` dist ` directory.
50+
51+ ### Preview Production Build
52+
2053``` bash
21- npm run build
54+ pnpm preview
2255```
2356
24- The output will be in the ` dist ` directory.
57+ ## 🌐 Live Demo
2558
26- ## GitHub Pages Deployment
27- This project is configured to automatically deploy to GitHub Pages on every push to the ` main ` branch.
59+ ** [ View the demo] ( https://pzanella.github.io/freewheel-html5-video-player/ ) **
2860
29- ### Setup
30- 1 . Push your changes to the ` main ` branch
31- 2 . The GitHub Actions workflow (` .github/workflows/deploy.yml ` ) will automatically:
32- - Install dependencies
33- - Build the project
34- - Deploy to GitHub Pages
61+ The project is automatically deployed to GitHub Pages on each push to ` main ` .
3562
36- ### Enabling GitHub Pages
37- If it's your first time deploying:
38- 1 . Go to your repository settings on GitHub
39- 2 . Navigate to ** Pages** section
40- 3 . Under "Source", select ** Deploy from a branch**
41- 4 . Choose ** gh-pages** branch and ** /(root)** folder
42- 5 . Click ** Save**
63+ ## 🔧 Configuration
4364
44- The workflow will automatically create the ` gh-pages ` branch on first deployment.
65+ Update the player configuration in the HTML page or pass it directly:
4566
46- ### Access Your Player
47- Once deployed, your player will be available at:
48- ```
49- https://pzanella.github.io/freewheel-html5-video-player/
67+ ``` javascript
68+ const playerConfig = {
69+ assetId: " your-asset-id" ,
70+ manifestUrl: " https://your-hls-manifest.m3u8"
71+ };
72+
73+ const player = new Player ();
74+ player .init (playerConfig);
5075```
5176
52- ## Query Parameters
53- You can enable logging by adding ` ?log ` to the URL:
77+ ## 🐛 Debug & Demo Controls
78+
79+ ### Query Parameters
80+
81+ The demo page provides controls to manage query parameters:
82+
83+ - ** ` ?log ` ** - Enable console debug logging
84+ - Click "Toggle Logging" button to add/remove
85+ - Page reloads when toggled
86+
87+ ### Examples
88+
5489```
90+ # Enable logging
5591https://pzanella.github.io/freewheel-html5-video-player/?log
5692```
5793
58- ## Events
94+ ## 📊 State Management
95+
96+ The player uses ** Zustand** for reactive state management:
97+
98+ ``` typescript
99+ // Store state
100+ {
101+ type : CONTENT_TYPE , // ADS | VOD
102+ playbackStatus : PLAYBACK_STATUS , // PLAYING | PAUSED
103+ mute : boolean // Mute state
104+ }
105+
106+ // Available actions
107+ togglePlayback () // Toggle between PLAYING/PAUSED
108+ toggleMute () // Toggle mute state
109+ setType (type ) // Set content type
110+ ```
111+
112+ ## 🎮 Controls
113+
114+ The player includes:
115+
116+ - ** Playback Button** : Play/pause toggle with visual feedback
117+ - ** Volume Button** : Mute/unmute toggle
118+ - ** Responsive Design** : Works on desktop, tablet, and mobile
119+
120+ ## 🏗️ Project Structure
121+
122+ ```
123+ src/
124+ ├── main.ts # Player initialization & orchestration
125+ ├── store.ts # Zustand state management
126+ ├── logger.ts # Debug logging utility
127+ ├── model.ts # TypeScript types & enums
128+ ├── emitter.ts # Event emitter base class
129+ ├── controls/ # UI components
130+ │ ├── components/
131+ │ │ ├── Icon/ # SVG icon component system
132+ │ │ ├── Playback/ # Play/pause button
133+ │ │ └── Volume/ # Volume button
134+ │ └── index.ts # Controls coordinator
135+ ├── ad-content/ # Freewheel ad integration
136+ │ ├── index.ts
137+ │ ├── model.ts
138+ │ └── config.ts
139+ └── media-content/ # HLS video content
140+ ├── index.ts
141+ └── model.ts
142+
143+ index.html # Landing page with demo controls
144+ ```
145+
146+ ## 📚 Technology Stack
147+
148+ | Component | Version | Purpose |
149+ | -----------| ---------| ---------|
150+ | ** Preact** | 10.27.2 | Lightweight UI framework |
151+ | ** Zustand** | 5.0.8 | State management |
152+ | ** Vite** | 6.2.0 | Build tool & dev server |
153+ | ** TypeScript** | ~ 5.7.2 | Type safety |
154+ | ** HLS.js** | 1.6.2 | HTTP Live Streaming |
155+ | ** Tailwind CSS** | CDN | Styling |
156+ | ** pnpm** | Latest | Package manager |
157+
158+ ## 🔌 Integration
159+
160+ ### Using in Your Application
161+
162+ ``` javascript
163+ // Import Player class
164+ import Player from ' ./path/to/player' ;
165+
166+ // Configure and initialize
167+ const playerConfig = {
168+ assetId: " your-asset-id" ,
169+ manifestUrl: " https://your-stream.m3u8"
170+ };
171+
172+ const container = document .getElementById (' player-container' );
173+ const player = new Player ();
174+ player .init (playerConfig);
175+
176+ // Listen to events
177+ player .on (' play' , () => console .log (' Playing' ));
178+ player .on (' pause' , () => console .log (' Paused' ));
179+ ```
180+
181+ ### Event System
182+
183+ The player fires events throughout its lifecycle:
184+
185+ - ` ADS_REQUEST_COMPLETE ` - Ad request finished
186+ - ` ADS_COMPLETE ` - All ads played
187+ - ` VIDEO_LOADEDMETADATA ` - Video metadata loaded
188+ - ` VIDEO_PLAYING ` - Video started playing
189+ - ` PLAYBACK_STATUS_CHANGED ` - Play/pause state changed
190+
191+ ## Freewheel events
59192### onRequestInitiated
60193Exposed as:
61194``` bash
@@ -345,8 +478,6 @@ Exposed as:
345478``` bash
346479window.tv.freewheel.SDK.EVENT_AD_IMPRESSION_END
347480```
348- <a style =" font-weight : bold ; color : red ;" >TODO</a >
349-
350481``` ts
351482{
352483 type : " adEvent" ,
@@ -362,8 +493,6 @@ Exposed as:
362493``` bash
363494window.tv.freewheel.SDK.EVENT_SLOT_ENDED
364495```
365- <a style =" font-weight : bold ; color : red ;" >TODO</a >
366-
367496``` ts
368497{
369498 type : " onSlotEnded" ,
0 commit comments