Play one YouTube video in a grid of many looping tiles at once — a video-wall on your screen.
🌐 Try it live: gridplayy.vercel.app
You choose the layout (rows × columns), the size of each tile, which tile has sound, and how the tiles start. Only one tile plays audio at a time, and every tile loops forever.
There are two versions:
| Version | Runs on | Best for |
|---|---|---|
Native app (GridPlay.app) |
macOS 14+ | Mac users who want a real double-clickable app |
Browser version (web/gridplay.html) |
Windows, macOS, Linux — any modern browser | Everyone else, incl. Windows users |
ℹ️ The native app is built with Apple's SwiftUI/AppKit and therefore cannot run on Windows. Windows (and Linux) users should use the browser version below — it has the same features.
| Setup screen | Grid playing |
|---|---|
![]() |
![]() |
- Paste a YouTube link, pick rows × columns and the pixel size of each tile.
- Every tile plays the same video, looping forever.
- One tile has sound; click any tile's 🔈 speaker to move the audio there, or click the sounded tile again to silence everything.
- Mute All and Pause All / Play All buttons.
- Start modes:
- Together – all tiles start at once.
- Cascade – tiles start one after another, N seconds apart.
- Random – the sounded tile starts from the beginning; the others start from a random point.
- Duplicate / New Window – open the same wall again in another window (stack several 3×3 walls).
- Saved Packages – save a link + all its settings as a named package and reopen it with one click.
- Swap the video while playing – paste a new link in the top bar and hit Update; the layout and every setting stay put, only the video changes.
- No subtitles – captions are kept off for a clean picture.
- Auto-open from YouTube – install the browser extension and every YouTube video you open launches the GridPlay macOS app as a wall with your default settings. Switching to another video updates the open grid in place (same layout) instead of opening a new window. Toggle it off anytime to watch YouTube normally.
No installation. Works everywhere.
- Download the file
web/gridplay.html. - Double-click it — it opens in your default browser (Chrome, Edge, Firefox, Safari…).
- Paste a YouTube link, set up your grid, and press Start.
- Duplicate / New Window open new browser windows.
- Saved Packages are stored in that browser (via
localStorage) and stay between sessions.
If a tile shows "Video unavailable" when opened directly: some browsers restrict YouTube embeds loaded from a local file (
file://). Fix it by serving the file over a tiny local web server instead:# from the folder that contains gridplay.html python3 -m http.server 8000 # macOS / Linux py -m http.server 8000 # Windows (Python installed)Then open http://localhost:8000/gridplay.html in your browser.
The web app also accepts query params, so a single link opens directly into a playing grid (no setup screen):
https://gridplayy.vercel.app/?v=VIDEO_ID&rows=3&cols=3&w=470&h=250&mode=random
| Param | Meaning | Default |
|---|---|---|
v (or url) |
YouTube video id or full link | — (required) |
rows, cols |
grid size (1–10) | 3, 3 |
w, h |
tile width/height in px | 480, 270 |
mode |
together, cascade, or random |
together |
snd |
which tile has sound (1-based) | 1 |
delay |
seconds between tiles (cascade only) | 1 |
Want any YouTube video you watch to open in the GridPlay macOS app automatically? Install the GridPlay for YouTube extension (Chrome / Edge / Brave / Firefox).
- Build & install the app once so macOS registers its
gridplay://link:./build-macos-app.sh cp -R GridPlay.app /Applications/ # macOS binds the scheme to the copy in /Applications open /Applications/GridPlay.app # launch once so Launch Services records the handler
- Open
chrome://extensions, enable Developer mode, click Load unpacked, pick theextension/folder. - Open any YouTube video — GridPlay.app launches a wall with your defaults (3×3, 470×250, Random out of the box). The first time, the browser asks “Open GridPlay?” — tick Always allow.
- Switch to another video and the same grid updates in place (all tiles reload the new video) — it doesn't pile up new windows.
- Click the toolbar icon to change the defaults, pause the YouTube tab, or turn auto-open off.
How it hangs together: the extension's content script reads the video on YouTube and asks its background worker to open
gridplay://open?v=…&rows=…&cols=…&w=…&h=…&mode=…. The app parses that inconfigFromDeepLink()and routes it to the open window viaDeepLinkRouter.Rebuilt the app? Re-copy it to
/Applicationsand refresh Launch Services, otherwise the old copy still answers the link:rm -rf /Applications/GridPlay.app && cp -R GridPlay.app /Applications/ /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -f /Applications/GridPlay.appPrefer the browser web app instead of the native app? Use the query-param URL above directly, or repoint the extension's content script — see
extension/README.md.
Download GridPlay.dmg (or a shared GridPlay.zip), open it, and drag GridPlay.app into
your Applications folder.
Because the app isn't notarized with a paid Apple Developer account, macOS Gatekeeper blocks the first launch with "Apple could not verify GridPlay is free of malware." This is expected for any un-notarized app. To open it, either:
- System Settings → Privacy & Security → scroll down → click Open Anyway (on macOS 15 Sequoia and later this is the only GUI route — the old "right-click → Open" no longer works), or
- run once in Terminal:
xattr -dr com.apple.quarantine /Applications/GridPlay.app
To remove the warning entirely for everyone who downloads it, the app would need to be signed and notarized with a paid Apple Developer account ($99/yr).
Requires Xcode / Swift toolchain (Swift 5.9+) on macOS 14+.
git clone <this-repo> # or download & unzip the source
cd gridplay
./build-macos-app.sh # produces ./GridPlay.appThen double-click GridPlay.app, or drag it to /Applications.
To share it with another Mac user, make a drag-to-Applications disk image or a zip:
./make-dmg.sh # produces GridPlay.dmg
# or:
zip -r GridPlay.zip GridPlay.appswift run- Paste a YouTube link (e.g.
https://www.youtube.com/watch?v=…, ayoutu.be/…, or a Shorts link). - Layout – set rows, columns, and each tile's width/height in pixels.
- Audio – choose which tile starts with sound.
- Start – choose Together, Cascade (+ delay), or Random.
- Press Start.
In the grid:
| Action | How |
|---|---|
| Move the sound to a tile | Click that tile's 🔈 speaker |
| Silence everything | Click the sounded tile's speaker, or Mute All (⌘M) |
| Pause / resume all tiles | Pause All / Play All (⌘P) |
| Change the video (keep all settings) | Paste a link in the top bar → Update |
| Open the same wall again | Duplicate (⌘D) |
| Open a fresh setup | New Window (⌘N) |
| Go back to setup | ← Back |
Save a setup as a package: type a name in Saved Packages → Save current. Reopen it later with the ▶ button, load it into the form with ↗, rename it by clicking its name, or remove it with 🗑.
- Each tile is a live YouTube player. Two 3×3 windows = 18 simultaneous streams — that's heavy on CPU/GPU and network. If it gets sluggish, use fewer/smaller tiles.
- Videos whose owners disable embedding cannot be played (a YouTube restriction, not a bug).
- Uses YouTube's official IFrame Player API, in line with YouTube's Terms of Service.
- An internet connection is required.
gridplay/
├── Package.swift # Swift package (macOS app)
├── build-macos-app.sh # builds GridPlay.app (bundles the icon)
├── make-dmg.sh # builds GridPlay.dmg (drag-to-Applications)
├── make-icon.swift # draws the app icon (1024px master)
├── make-icon.sh # generates Resources/AppIcon.icns
├── Resources/
│ ├── AppIcon.icns # macOS app icon
│ └── icon-1024.png # icon master (PNG, also shown in this README)
├── screenshots/ # start.png & grid.png (shown in this README)
├── Sources/GridPlay/ # native macOS app source
│ ├── GridPlayApp.swift
│ ├── ContentView.swift # setup screen + windows + packages
│ ├── GridPlayerView.swift # the tile grid + controls
│ ├── YouTubePlayerView.swift # one YouTube player (WKWebView)
│ ├── GridConfig.swift # settings model + start modes
│ ├── PresetStore.swift # saved packages (on disk)
│ └── YouTubeID.swift # link → video-ID parser
├── web/
│ ├── gridplay.html # cross-platform browser version (Windows/Mac/Linux)
│ └── favicon.svg # browser tab icon (also embedded in the HTML)
├── extension/ # "GridPlay for YouTube" browser extension (MV3)
│ ├── manifest.json
│ ├── background.js # auto-redirects YouTube videos → GridPlay wall
│ ├── popup.html / popup.js # on/off toggle + default grid settings
│ └── icons/
└── site/ # landing page deployed to Vercel (static)
├── index.html # the landing page
├── gridplay.html # the web app (Launch button target)
├── GridPlay.dmg # macOS download
└── icon.png, start.png, grid.png
The icon is drawn in code. Edit make-icon.swift, then regenerate:
./make-icon.sh # rewrites Resources/AppIcon.icns and icon-1024.png
./build-macos-app.sh # rebuild the app so it picks up the new iconIf Finder still shows the old icon after rebuilding, it's just the macOS icon cache. Move the app or log out/in, or run:
touch GridPlay.app.

