{"id":51126608,"url":"https://github.com/radical-beard/switch-screenshots-mac","last_synced_at":"2026-06-25T08:30:26.885Z","repository":{"id":363049465,"uuid":"1260994960","full_name":"radical-beard/switch-screenshots-mac","owner":"radical-beard","description":"Copy Nintendo Switch \u0026 Switch 2 screenshots and video clips to your Mac over USB. Pure Python, no app needed.","archived":false,"fork":false,"pushed_at":"2026-06-07T06:30:17.000Z","size":12,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-07T08:13:22.203Z","etag":null,"topics":["gphoto2","macos","mtp","nintendo-switch","nintendo-switch-2","ptp","python","screenshot-transfer","screenshots","switch2","usb","video-clips"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/radical-beard.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-06T05:32:11.000Z","updated_at":"2026-06-07T06:30:21.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/radical-beard/switch-screenshots-mac","commit_stats":null,"previous_names":["radical-beard/switch-screenshots-mac"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/radical-beard/switch-screenshots-mac","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radical-beard%2Fswitch-screenshots-mac","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radical-beard%2Fswitch-screenshots-mac/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radical-beard%2Fswitch-screenshots-mac/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radical-beard%2Fswitch-screenshots-mac/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/radical-beard","download_url":"https://codeload.github.com/radical-beard/switch-screenshots-mac/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radical-beard%2Fswitch-screenshots-mac/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34767542,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-25T02:00:05.521Z","response_time":101,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gphoto2","macos","mtp","nintendo-switch","nintendo-switch-2","ptp","python","screenshot-transfer","screenshots","switch2","usb","video-clips"],"created_at":"2026-06-25T08:30:20.604Z","updated_at":"2026-06-25T08:30:26.864Z","avatar_url":"https://github.com/radical-beard.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# switch-screenshots-mac\n\nCopy your **Nintendo Switch 2** (and original Switch) screenshots and video clips to your Mac over a USB cable — one command, safe to re-run.\n\nmacOS has no native MTP support, so there's no Finder mount and no Image Capture for the Switch. This is a single, dependency-free Python script that pulls everything off the console anyway and drops it into `~/switch-screenshots/`.\n\n## What it does\n\nPulls every screenshot and video clip off your Switch into `~/switch-screenshots/` as a flat folder of files with their original names. It remembers what it has already copied, so you can run it again any time and it only fetches what's new.\n\n- Single Python file, **standard library only** — no `pip install`, no virtualenv.\n- Original filenames, flat layout, capture timestamps preserved.\n- Built-in dedup: re-running is always safe.\n- Resumable: progress is saved after every small batch.\n\n## Requirements\n\n- **macOS** (Apple Silicon or Intel).\n- **`gphoto2`** — if it's missing, the script offers to `brew install` it for you. Or install it yourself:\n  ```bash\n  brew install gphoto2\n  ```\n  (needs [Homebrew](https://brew.sh))\n- **Python 3.7+** — the `python3` that ships with macOS is fine. No packages to install.\n- A **USB-C data cable** (charge-only cables won't work).\n\n## Quick start\n\n```bash\n# 1. Grab the script\ncurl -fLO https://raw.githubusercontent.com/radical-beard/switch-screenshots-mac/main/get-switch-screenshots.py\n\n# 2. On the console, open the \"Copy to PC over USB\" screen (see below),\n#    plug the cable into the BOTTOM USB-C port, then run:\npython3 get-switch-screenshots.py\n```\n\nThat's it. If `gphoto2` isn't installed yet, the script asks to install it for you. Your screenshots and clips land in `~/switch-screenshots/`.\n\n### Or with breach\n\nIf you've cloned the repo, it's wired for [`breach`](https://github.com/radical-beard/breach):\n\n```bash\nbreach setup     # install gphoto2\nbreach run       # transfer new screenshots/clips\nbreach list      # list what's on the console\nbreach preview   # show what would transfer, download nothing\n```\n\n## On the console (do this first)\n\n1. Open **Settings → Data Management → Manage Screenshots and Videos → Copy to PC over USB**.\n2. Leave that screen showing — the console only exposes its album while it's open.\n3. Plug the USB-C cable into the **bottom port of the console** (the one you charge from in handheld mode).\n   - **Not** the top port.\n   - **Not** through the dock.\n\n## Usage\n\n```bash\npython3 get-switch-screenshots.py            # transfer everything new\npython3 get-switch-screenshots.py --list     # just list what's on the console, transfer nothing\npython3 get-switch-screenshots.py --dry-run  # show what would transfer, download nothing\npython3 get-switch-screenshots.py --limit 5  # transfer at most 5 new files (handy for a first test)\n```\n\n| Flag | Effect |\n|------|--------|\n| `--list` | Print every file on the console (grouped by game) and exit. |\n| `--dry-run` | Show exactly what *would* be fetched without downloading anything. |\n| `--limit N` | Stop after `N` new files. Great for a quick sanity check. |\n\n## How dedup works (safe to re-run)\n\nSwitch filenames are timestamp-based and globally unique, so the script skips anything it has seen before. It checks three things, so a re-run never duplicates work:\n\n1. A **manifest** at `~/.local/share/switch-screenshots/manifest.json` recording everything transferred.\n2. An **on-disk name check** against `~/switch-screenshots/`, so re-runs stay correct even if the manifest is ever deleted.\n3. A **SHA-256 content hash** of every file, so identical content is never stored twice — even under a different name.\n\nThe manifest is flushed after each small batch, so an interrupted run (or a yanked cable) just picks up where it left off next time.\n\n## Where files go\n\n| Path | Contents |\n|------|----------|\n| `~/switch-screenshots/` | Your screenshots and video clips (flat, original names). |\n| `~/.local/share/switch-screenshots/manifest.json` | Dedup state. |\n| `~/.local/share/switch-screenshots/staging/` | Temporary download staging (auto-managed). |\n\n## Troubleshooting\n\n**\"Could not find the Switch.\"**\n- Make sure the **Copy to PC over USB** screen is open on the console.\n- Use the **bottom** USB-C port, directly — not the top port, not the dock.\n- Confirm your cable carries **data**, not just power. Swap cables if unsure.\n- Sanity check: `gphoto2 --auto-detect` should list a Nintendo/Switch device while the copy screen is open.\n\n**It worked, then got stuck mid-transfer.**\n- **Unplug and replug the cable** to reset the connection, then re-run. Thanks to dedup it resumes cleanly and won't re-copy finished files.\n\n**\"The Switch is connected but no screenshots/videos are visible.\"**\n- The console is plugged in but not in transfer mode — open the **Copy to PC over USB** screen and re-run.\n\n## How it works under the hood (and why it's not trivial)\n\nThe Switch presents itself as an **MTP device** (PTP with a Nintendo vendor extension). On macOS that's surprisingly hard to deal with:\n\n- **macOS has no native MTP support.** There's no Finder mount and no Image Capture support — Apple's `ImageCaptureCore` framework sees **zero cameras** when the Switch is plugged in.\n- So the script drives **`gphoto2`** (Homebrew's CLI front-end to `libgphoto2`'s PTP/MTP driver), the one tool that reliably talks to the console here.\n- macOS's **`ptpcamerad`** service grabs the USB interface the moment a still-image device appears, blocking `gphoto2` from claiming it. The script stops `ptpcamerad` **once** right before each session (it's user-owned, so no `sudo`). It deliberately does **not** kill it in a loop — that re-enumerates the USB bus and corrupts transfers.\n- It runs **one `gphoto2` session per folder**, using repeated `--get-file N` flags with **per-folder, 1-based indices**. (`gphoto2 --list-files` numbers files globally across the whole tree, but `--folder F --get-file n` expects `n` relative to that folder — a subtle mismatch the script handles for you.)\n\nThe result is a transfer that \"just works\" from a single command, hiding a fair amount of macOS USB plumbing.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fradical-beard%2Fswitch-screenshots-mac","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fradical-beard%2Fswitch-screenshots-mac","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fradical-beard%2Fswitch-screenshots-mac/lists"}