From 1589be3f92f65c4d1e8f8cc0d1077b52a40a3f84 Mon Sep 17 00:00:00 2001 From: Bhakti Shukla Date: Thu, 17 Jul 2025 10:39:11 -0700 Subject: [PATCH 1/2] feat: PE-964: [dev-cookbook] Add indexeddb example - Add example for showcasing how to use indexedDB to cache videos and playback in a loop --- examples/indexeddb-caching-example/README.md | 62 ++++++ .../indexeddb-caching-example/autorun.brs | 40 ++++ examples/indexeddb-caching-example/index.html | 189 ++++++++++++++++++ 3 files changed, 291 insertions(+) create mode 100644 examples/indexeddb-caching-example/README.md create mode 100644 examples/indexeddb-caching-example/autorun.brs create mode 100644 examples/indexeddb-caching-example/index.html diff --git a/examples/indexeddb-caching-example/README.md b/examples/indexeddb-caching-example/README.md new file mode 100644 index 0000000..712e410 --- /dev/null +++ b/examples/indexeddb-caching-example/README.md @@ -0,0 +1,62 @@ +# IndexedDB Video Caching Example + +This example demonstrates how to use IndexedDB for caching video content in a BrightSign HTML5 application. The application creates a video playlist that intelligently caches videos in the background for smooth playback. + +## File Structure + +- `index.html`: Main HTML application with video player and caching logic +- `autorun.brs`: BrightSign autorun script which loads the HTML application + +## Usage + +1. Copy the `autorun.brs` and `index.html` files to the root of an SD card +2. Insert the SD card in the BrightSign player and power it on +3. The `autorun.brs` script will automatically launch the HTML application + +## How It Works + +1. **Database Setup**: Creates an IndexedDB database (`videos_db`) with an object store (`videos_os`) to store video blobs +2. **Playlist Loading**: Loads a predefined playlist of sample videos from Google's test video collection +3. **Smart Caching Strategy**: + - First video: Downloads and plays immediately, then starts background caching + - Subsequent videos: Plays from cache if available, otherwise downloads from network + - Background caching: Downloads remaining videos with 1-second delays between requests +4. **Automatic Playback**: Videos play continuously with automatic progression to the next video + +## Configuration Options + +### BrightSign Configuration (autorun.brs) +- `url`: Path to the HTML file. This can be modified to point to a remote server URL that serves the HTML file. +- `mouse_enabled`: Enable/disable mouse interaction (default: false) +- `javascript_enabled`: Enable/disable JavaScript (default: true) +- `nodejs_enabled`: Enable/disable Node.js (default: false) +- `storage_path`: Directory for local storage cache +- `storage_quota`: Maximum cache size + +See the [roHtmlWidget](https://docs.brightsign.biz/developers/rohtmlwidget#23vJS) page for more details on configuration options. + +### Video Configuration (index.html) +- Modify the `fetchPlaylist()` function to add your own video URLs +- Adjust the background caching delay by changing the `TIMEOUT_DELAY` value +- Customize video display properties in the `displayVideo()` function + +## Error Handling + +The application includes comprehensive error handling for: +- Network connectivity issues +- IndexedDB operation failures +- Duplicate cache entries (ConstraintError) +- Video loading and playback errors + +## Performance Considerations + +- **Storage**: Videos are stored as blobs in IndexedDB, which uses available disk space +- **Network**: Background caching uses staggered requests (1-second delays) to avoid overwhelming the network +- **Memory**: Video blobs are created using `URL.createObjectURL()` for efficient memory usage + +## Troubleshooting + +1. **Videos not caching**: Check console for IndexedDB errors +2. **Network errors**: Verify internet connectivity and video URLs +3. **Storage full**: Check available disk space and storage quota settings +4. **Playback issues**: Ensure video formats are supported by the player diff --git a/examples/indexeddb-caching-example/autorun.brs b/examples/indexeddb-caching-example/autorun.brs new file mode 100644 index 0000000..2c3931b --- /dev/null +++ b/examples/indexeddb-caching-example/autorun.brs @@ -0,0 +1,40 @@ +Sub Main() + width = 1920 + height = 1080 + + vidmode = CreateObject("roVideoMode") + if type(vidmode) = "roVideoMode" + width = vidmode.GetResX() + height = vidmode.GetResY() + end if + + msgPort = CreateObject("roMessagePort") + rect = CreateObject("roRectangle", 0, 0, width, height) + + 'inspector disabled currrently + 'inspectorServer = { + ' port: 3010 + '} + + config = { + url: "file:/SD:/index.html", ' you can use a server or website URL here - "https://example.com/index.html" + mouse_enabled: false, ' set to true to enable mouse/keyboard + 'inspector_server: inspectorServer ' uncomment to enable inspector server + security_params: { websecurity: true } + javascript_enabled: true, ' set to false to disable JavaScript + nodejs_enabled: true, ' set to false to disable Node.js + storage_path: "/cache", ' Name of the directory for local storage cache + storage_quota: "2147483648", ' 2GB + port: msgPort, + } + + html = CreateObject("roHtmlWidget", rect, config) + html.Show() + + syslog = CreateObject("roSystemLog") + + while true + event = wait(0, msgPort) + syslog.sendline("@@ type(event)="+ type(event)) + end while +End Sub diff --git a/examples/indexeddb-caching-example/index.html b/examples/indexeddb-caching-example/index.html new file mode 100644 index 0000000..66e6d0f --- /dev/null +++ b/examples/indexeddb-caching-example/index.html @@ -0,0 +1,189 @@ + + + + + + +
+

Loading playlist ...

+
+ + From c37d3b6e9fea327a5166dae88c302cc9f4839b3f Mon Sep 17 00:00:00 2001 From: Bhakti Shukla Date: Thu, 17 Jul 2025 15:23:16 -0700 Subject: [PATCH 2/2] Address review comments --- examples/indexeddb-caching-example/autorun.brs | 6 +++--- examples/indexeddb-caching-example/index.html | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/indexeddb-caching-example/autorun.brs b/examples/indexeddb-caching-example/autorun.brs index 2c3931b..08bfdc1 100644 --- a/examples/indexeddb-caching-example/autorun.brs +++ b/examples/indexeddb-caching-example/autorun.brs @@ -11,7 +11,7 @@ Sub Main() msgPort = CreateObject("roMessagePort") rect = CreateObject("roRectangle", 0, 0, width, height) - 'inspector disabled currrently + 'inspector disabled currently 'inspectorServer = { ' port: 3010 '} @@ -21,8 +21,8 @@ Sub Main() mouse_enabled: false, ' set to true to enable mouse/keyboard 'inspector_server: inspectorServer ' uncomment to enable inspector server security_params: { websecurity: true } - javascript_enabled: true, ' set to false to disable JavaScript - nodejs_enabled: true, ' set to false to disable Node.js + javascript_enabled: true, ' Else set to false to disable JavaScript + nodejs_enabled: true, ' Else set to false to disable Node.js storage_path: "/cache", ' Name of the directory for local storage cache storage_quota: "2147483648", ' 2GB port: msgPort, diff --git a/examples/indexeddb-caching-example/index.html b/examples/indexeddb-caching-example/index.html index 66e6d0f..3dc7f8f 100644 --- a/examples/indexeddb-caching-example/index.html +++ b/examples/indexeddb-caching-example/index.html @@ -160,7 +160,7 @@ }; request.onsuccess = function() { - console.log('Database opened succesfully'); + console.log('Database opened successfully'); db = request.result; fetchPlaylist(); @@ -171,7 +171,7 @@ // Setup the database tables if this has not already been done request.onupgradeneeded = function(e) { const db = e.target.result; - const objectStore = db.createObjectStore('videos_os', { keyPath: 'name', autoIncrement: true }); + const objectStore = db.createObjectStore('videos_os', { keyPath: 'name' }); // Define what data items the objectStore will contain objectStore.createIndex('mp4', 'mp4', { unique: false });