Automatically detect and mute advertisements during live sports broadcasts using AI-powered vision models
S.A.M intelligently distinguishes between live sports action and commercials, seamlessly muting ads while keeping you immersed in the game using local Ollama AI.
New to S.A.M? Check out the Quick Start Guide for a 5-minute setup!
- Smart Ad Detection - AI vision model identifies gameplay vs. commercials in real-time
- Automatic Muting - Instantly mutes during ads, unmutes for live action
- Local AI Processing - Uses Ollama with
qwen3.5:0.8bmodel for high accuracy - Adaptive Sampling - Intelligently adjusts capture frequency based on content stability
- Rate-Limited Queue - Prevents API overload with smart request management
- Easy Controls - Simple start/stop interface in extension popup
- Privacy First - All processing happens locally, nothing sent to external servers
- Multi-Platform - Works on YouTube, Twitch, ESPN, Peacock, and more
- Quick Start Guide - Get running in 5 minutes!
- Prerequisites
- Installation
- Usage
- Architecture
- Configuration
- Troubleshooting
- Development
- Contributing
- License
- Ollama installed and running locally
- qwen3.5:0.8b model downloaded
# Install Ollama from https://ollama.ai
# Then pull the vision model:
ollama pull qwen3.5:0.8b
# Start Ollama (usually runs automatically):
ollama serveExtension will be published to Chrome Web Store
- Clone the repository:
git clone https://github.com/ethanwheatthin/Football-Ad-Muter.git cd Football-Ad-Muter - Load in Chrome:
- Open
chrome://extensions/ - Enable Developer mode (toggle in top-right)
- Click Load unpacked
- Select the
dist/folder - Extension icon appears in toolbar
- Open
-
Ensure Ollama is running with CORS support:
- Windows: Run
start-ollama-with-cors.bat(included in project) - macOS/Linux:
OLLAMA_ORIGINS=* ollama serve
- Windows: Run
-
Navigate to a live sports stream (e.g., YouTube Sports)
-
Click the S.A.M extension icon
-
Click Start Monitoring
-
S.A.M automatically mutes ads and unmutes for gameplay!
Note: The
start-ollama-with-cors.batscript automatically handles port conflicts and sets the required CORS configuration.
-
Open Extension Popup - Click the S.A.M icon in Chrome toolbar
-
Configure Settings (Optional):
- Check Interval: How often to analyze video (default: 10 seconds)
- Adaptive sampling automatically adjusts this during ads/gameplay
-
Start Monitoring - Click "Start Monitoring" button
-
Watch the Game - S.A.M works in the background:
- Green status = Gameplay detected (unmuted)
- Yellow status = Ad detected (muted)
- Activity log shows all detection events
Gameplay Detected:
Ad Detected:
-
Stop Monitoring - Click "Stop Monitoring" when done
Recent Frame Captures - View the last 3 analyzed frames with AI decisions
Activity Log - Real-time log of all mute/unmute events
Queue Metrics - Monitor API request queue status and performance
Reset Video - Manually reset video player state if needed
Adjust how often S.A.M analyzes the video:
- Default: 10 seconds (adaptive)
- Range: 1-60 seconds
- Recommendation: Leave at 10s, adaptive sampler handles optimization
- API URL: Default
http://localhost:11434 - Change if Ollama runs on different port/machine
- Requires CORS configuration for remote access
Automatically adjusts based on detected content:
- Ads: 3-5 second intervals (faster detection)
- Stable Gameplay: 10-15 second intervals (conserve resources)
- Scene Changes: Immediate capture on significant visual changes
┌─────────────────────────────────────────────────────────────┐
│ Chrome Tab │
│ ┌────────────────────────────────────────────────────┐ │
│ │ content.js (Content Script) │ │
│ │ • Finds active video element │ │
│ │ • Captures frames (multi-method fallback) │ │
│ │ • Applies mute/unmute based on AI response │ │
│ │ • Manages adaptive sampling │ │
│ └────────────────┬────────────────────────────────────┘ │
└───────────────────┬──────────────────────────────────────────┘
│ chrome.runtime.sendMessage()
▼
┌─────────────────────────────────────────────────────────────┐
│ background.js (Service Worker) │
│ • Handles AI model inference (Ollama) │
│ • Manages request queue and rate limiting │
│ • Tracks API performance metrics │
│ • Keeps service worker alive │
└─────────────────────────────────────────────────────────────┘
content.js - Page Context
- Video element detection (handles multiple videos, DRM content)
- Frame capture with 4-method fallback (ImageCapture, OffscreenCanvas, ImageBitmap, Canvas)
- Request queueing via
RequestQueue - Adaptive capture timing via
AdaptiveSampler
background.js - Service Worker
- AI model management (Ollama API)
- Image analysis and content classification
- Metrics tracking and monitoring
request-queue.js - Rate Limiting
- Concurrent request control (max 2 simultaneous)
- Priority-based queue processing
- Exponential backoff on failures
- Request timeout handling
adaptive-sampler.js - Intelligent Sampling
- Adjusts capture frequency based on content type
- Fast sampling during ads (3-5s intervals)
- Slow sampling during stable gameplay (10-15s intervals)
- Scene change detection
popup.js - User Interface
- Settings management
- Real-time status display
- Activity log viewer
- Frame capture preview
Video Frame → Canvas → Base64 → [Queue] → AI Model → true/false
↓
true = Gameplay (unmute)
false = Ad (mute)
Check Extension Status:
1. Go to chrome://extensions/
2. Verify S.A.M is enabled
3. Check "Service worker" status (should say "active")
4. Click "Inspect views: service worker" to view logs
Reload Extension:
1. Go to chrome://extensions/
2. Click reload button (🔄) on S.A.M
3. Refresh your video page
Connection Failures:
# Verify Ollama is running:
ollama list
# If not running, start it:
ollama serve
# Test the connection:
curl http://localhost:11434/api/tagsCORS Errors:
# Windows:
set OLLAMA_ORIGINS=* && ollama serve
# macOS/Linux:
OLLAMA_ORIGINS=* ollama serveModel Not Found:
# Install the required model:
ollama pull qwen3-vl:2b
# Verify installation:
ollama listNo Video Found:
- Refresh the page after starting monitoring
- Ensure video is actually playing (not paused)
- Check console for "No video element found" messages
Wrong Video Detected:
- Extension targets largest visible video
- Check for hidden/background videos on page
- Use "Reset Video" button to force re-detection
Some platforms use DRM (Digital Rights Management) which prevents frame capture:
DRM Protected (Extension Cannot Work):
- Netflix
- Disney+
- Amazon Prime Video (most content)
- ESPN - Most live games and premium content
- Peacock - Most NBC Sports and live events
- HBO Max
Usually Works:
- YouTube (all content)
- Twitch (most streams)
- ESPN (some replays and highlights)
- Peacock (some free content)
- Most non-DRM streaming sites
How It Works:
- S.A.M automatically detects DRM protection when you start monitoring
- If DRM is found, the extension shows an alert and stops automatically
- The alert tells you which DRM system was detected (Widevine, PlayReady, etc.)
Why DRM Blocks This: DRM prevents JavaScript from accessing video frames to protect copyrighted content. This is a browser security feature that cannot be bypassed.
High CPU Usage:
- Increase check interval to 15-20 seconds
- Close other resource-intensive tabs
Memory Usage:
- Extension uses ~100-200MB normally
- Ollama handles AI processing externally (minimal browser memory impact)
Browser Console (F12):
- Shows content script logs
- Displays video detection info
- Reports capture errors
Service Worker Console (chrome://extensions → Inspect):
- Shows background script logs
- Displays API request/response info
- Reports model loading status
Popup Console (Right-click popup → Inspect):
- Shows UI-related logs
- Displays storage operations
- Clone and install:
git clone https://github.com/ethanwheatthin/Sports-Ad-Muter.git
- Start Ollama
cd Sports-Ad-Muter ./start-ollama-with-cors.bat - Load unpacked extension from
Sports-Ad-Muter/folder inchrome://extensions/
Football-Ad-Muter/
├── background.js # Service worker with Ollama integration
├── content.js # Content script for video capture
├── popup.js # Popup UI logic
├── request-queue.js # Request queue manager
├── adaptive-sampler.js # Adaptive sampling logic
├── manifest.json # Extension manifest (v3)
├── popup.html # Popup UI structure
├── popup.css # Popup styling
├── images/ # Extension icons
├── package.json # Dependencies and scripts
└── README.md # This file
npm run build # Production build (minified)
npm run build:dev # Development build (with source maps)
npm run watch # Auto-rebuild on changes
npm run clean # Remove dist/ folderBefore submitting a PR, test:
- Multiple video platforms (YouTube, Twitch, etc.)
- Ollama integration and connectivity
- Start/stop monitoring
- Settings changes apply correctly
- Frame capture displays in popup
- Activity log updates in real-time
- Video detection with multiple videos on page
- Error handling (no Ollama, CORS issues, etc.)
See CONTRIBUTING.md for detailed guidelines.
Contributions are welcome! We appreciate:
- Bug reports and fixes
- New features and enhancements
- Documentation improvements
- Test coverage additions
- Architecture suggestions
See CONTRIBUTING.md for guidelines.
High Priority:
- Improve ad detection accuracy (better prompts, models)
- Support more streaming platforms
- Performance optimizations
- Better error messages
Good First Issues:
- UI improvements
- Documentation additions
- Configuration options
- Statistics tracking
This project is licensed under the MIT License - see the LICENSE file for details.
- Ollama - Local AI model runtime
- Chrome Extensions Team - Manifest V3 documentation
- Contributors - Everyone who has contributed to this project
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Made by sports fans, for sports fans



