Basic Embedding
Embed the Ozen-web viewer in web pages and documents
Overview
Ozen-web can be embedded in web pages, documentation, and presentations using standard HTML iframes. The viewer supports URL parameters for pre-loading audio and configuring overlays, making it ideal for interactive examples and educational materials.
Simple iframe Embedding
Basic Example
Embed the hosted viewer directly:
<iframe src="https://ucpresearch.github.io/ozen-web/viewer"
width="800"
height="600"
style="border: 1px solid #ccc;">
</iframe>This embeds the mobile viewer interface with an empty file drop zone.
With Audio Pre-loaded
Load audio automatically via URL parameter:
<iframe src="https://ucpresearch.github.io/ozen-web/viewer?audio=https://example.com/audio.wav"
width="800"
height="600"
style="border: none;">
</iframe>Requirements: - Audio file must be accessible via HTTPS - Server must enable CORS (see below) - Supported formats: WAV, FLAC, MP3, OGG
With Overlays Configured
Pre-enable acoustic overlays:
<iframe src="https://ucpresearch.github.io/ozen-web/viewer?audio=https://example.com/audio.wav&overlays=pitch,formants,intensity"
width="800"
height="600"
style="border: none;">
</iframe>Overlay options: - pitch - Fundamental frequency track - formants - F1-F4 formants - intensity - Intensity track - hnr - Harmonics-to-noise ratio - cog - Center of gravity - spectral_tilt - Spectral tilt - a1_p0 - A1-P0 measure
Multiple overlays separated by commas.
CORS Requirements
For the viewer to load audio from your server, the server must send CORS headers:
Required Headers
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Apache (.htaccess)
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>Nginx
location ~ \.(wav|mp3|ogg)$ {
add_header Access-Control-Allow-Origin *;
}
Python HTTP Server
# Simple CORS-enabled server
python3 -m http.server 8000 --bind 0.0.0.0Note: Python’s built-in server doesn’t add CORS headers by default. Use a production server for deployment.
GitHub Pages
GitHub Pages automatically enables CORS for all static files — no configuration needed.
Amazon S3
When uploading audio files, set: - Public access: Enabled - CORS configuration:
[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET"],
"AllowedOrigins": ["*"],
"ExposeHeaders": []
}
]Responsive Embedding
Make the iframe responsive to container width:
<div style="position: relative; width: 100%; padding-bottom: 75%; /* 4:3 aspect ratio */">
<iframe src="https://ucpresearch.github.io/ozen-web/viewer?audio=..."
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none;">
</iframe>
</div>Common aspect ratios: - 16:9 (widescreen): padding-bottom: 56.25%; - 4:3 (standard): padding-bottom: 75%; - 3:2: padding-bottom: 66.67%;
Self-Contained Embedding (Data URLs)
For truly portable embeds without external file dependencies, encode audio as a data URL:
Creating Data URL
Using Base64 encoding:
# Linux/Mac
base64 -w 0 audio.wav > audio.base64
# Then construct data URL:
# data:audio/wav;base64,<paste base64 here>In JavaScript:
// Convert file to data URL
async function fileToDataURL(file) {
return new Promise((resolve) => {
const reader = new FileReader();
reader.onload = e => resolve(e.target.result);
reader.readAsDataURL(file);
});
}
const dataURL = await fileToDataURL(audioFile);
// data:audio/wav;base64,UklGRiQAAABXQVZFZm10...In R:
library(base64enc)
audio_data <- readBin("audio.wav", "raw", file.info("audio.wav")$size)
data_url <- paste0("data:audio/wav;base64,", base64encode(audio_data))Embedding with Data URL
<iframe src="https://ucpresearch.github.io/ozen-web/viewer?audio=data:audio/wav;base64,UklGRiQAAABXQVZFZm10..."
width="800"
height="600"
style="border: none;">
</iframe>Advantages: - No external file hosting required - Works offline after initial page load - Self-contained — entire example in one HTML file - No CORS issues
Limitations: - URL length limits (~2MB practical limit for most browsers) - Not suitable for long audio files - Increases page size
Use cases: - Short audio examples in documentation - QR code-embeddable demos - Email-friendly examples (single HTML file)
Helper Scripts
Ozen-web includes helper scripts for generating embed code:
R Script (create-iframe.R)
Located at scripts/create-iframe.R:
Basic usage:
source("scripts/create-iframe.R")
# Generate iframe HTML
html <- create_embedded_viewer(
"data/vowel-example.wav",
overlays = "pitch,formants,intensity",
height = 600
)
# Use in R Markdown/Quarto
htmltools::HTML(html)Command-line usage:
Rscript scripts/create-iframe.R audio.wav "pitch,formants" "./ozen-web/viewer.html"Features: - Automatically calculates relative paths - Handles data URL encoding - Customizable viewer URL (for local builds) - Height can be numeric (pixels) or percentage
See Quarto Integration for detailed R Markdown examples.
Python Script (create-iframe.py)
Located at scripts/create-iframe.py:
Basic usage:
from create_iframe import create_embedded_viewer
# Generate iframe HTML
html = create_embedded_viewer(
audio_path="data/vowel-example.wav",
overlays="pitch,formants,intensity",
height=600
)
print(html)Command-line usage:
python scripts/create-iframe.py audio.wav --overlays pitch,formants --height 600Features: - Same functionality as R version - Base64 encoding for data URLs - Relative path calculation - Jupyter notebook compatible
Local Development
When embedding in local HTML files:
File Protocol Limitation
Modern browsers block file:// iframes for security:
<!-- ❌ Won't work when opened as file:// -->
<iframe src="file:///path/to/viewer.html?audio=file:///audio.wav">
</iframe>Solution: Local HTTP Server
Serve your HTML files over HTTP:
Python 3:
python3 -m http.server 8000
# Open http://localhost:8000/your-page.htmlNode.js (http-server):
npx http-server -p 8000
# Open http://localhost:8000/your-page.htmlPHP:
php -S localhost:8000R (servr package):
servr::httd(port = 8000)Now iframes will work properly.
Embedding Best Practices
1. Choose Appropriate Dimensions
Desktop viewers: - Minimum width: 800px - Minimum height: 600px - Recommended: 1000px × 700px or larger
Mobile-optimized: - Width: 100% (responsive) - Height: 500-700px
2. Set Meaningful Defaults
Pre-configure overlays to highlight the acoustic features relevant to your example:
<!-- For pitch analysis example -->
?overlays=pitch,intensity
<!-- For vowel formants example -->
?overlays=formants
<!-- For voice quality example -->
?overlays=pitch,hnr,spectral_tilt3. Provide Context
Always explain what the viewer shows:
<p>Figure 1: Pitch contour for question intonation.
Notice the final rise at the end of the utterance.</p>
<iframe src="https://ucpresearch.github.io/ozen-web/viewer?audio=...&overlays=pitch,intensity">
</iframe>4. Test on Mobile
If your page is mobile-accessible, test the embedded viewer on phones:
- Touch gestures work correctly
- Viewer is responsive
- Settings drawer accessible
- Play button visible
5. Consider Loading Time
For large audio files (>5 MB): - Warn users about loading time - Consider hosting files on CDN - Use compressed formats (MP3 instead of WAV)
Troubleshooting
Viewer Not Loading
Problem: Blank iframe or error message
Possible causes: - CORS not enabled on audio server - Invalid audio URL - Mixed content (HTTP audio on HTTPS page)
Solution: - Check browser console for CORS errors - Test audio URL directly in browser - Ensure both page and audio use HTTPS
Audio Not Playing
Problem: Viewer loads but audio doesn’t play
Possible causes: - Browser autoplay policy - Invalid audio format - File corrupted
Solution: - User must click play button (autoplay restricted) - Verify audio file plays in browser directly - Re-encode audio file
iframe Too Small
Problem: Viewer UI is cramped or cut off
Solution: - Increase iframe dimensions - Use responsive embedding with aspect ratio - Minimum 800×600 recommended
Security Considerations
Content Security Policy (CSP)
If your site uses CSP headers, allow iframes:
Content-Security-Policy: frame-src https://ucpresearch.github.io
Data URL Size Limits
Different browsers have different URL length limits:
| Browser | Max URL Length |
|---|---|
| Chrome | ~2 MB (practical) |
| Firefox | ~65 KB (strict) |
| Safari | ~2 MB |
| Edge | ~2 MB |
For cross-browser compatibility, keep data URLs under 64 KB or use external file hosting.
See Also
- Quarto Integration - Using in Quarto documents
- URL Parameters - Complete parameter reference
- Examples - Real-world embedding examples
- Mobile Viewer - Touch interface details