Repository files navigation

MacVidCatch

MacVidCatch is a native macOS 13+ Internet Download Manager with browser integration. The user-facing app name, .app bundle, DMG volume, Swift package, and executable target all use MacVidCatch.

Screenshots

MacVidCatch App

MacVidCatch app screenshot

Browser Floating Button

MacVidCatch browser floating button screenshot

Current Status

  • SwiftUI macOS app with a downloads list, status filters, manual download dialog, Settings, menu bar controls, and a button to open the logs folder.
  • Native HTTP/HTTPS downloader with metadata probing via HEAD, HTTP status validation, retry, buffered partial-file pause/resume, partial cleanup, final file-size validation, and segmented downloads that require 206 Partial Content responses.
  • Download queue with global parallel download limits and per-file connection limits.
  • Basic global speed limiting for the native single-download path.
  • Local persistence for jobs and settings under Application Support.
  • Custom URL scheme integration via macvidcatch://download?... for URLs sent by browser extensions.
  • Browser-extension downloads, HLS .m3u8, and YouTube URLs are routed through yt-dlp; normal manual direct HTTP downloads continue to use the native downloader unless the URL or MIME type indicates HLS.
  • Chrome Manifest V3, Firefox WebExtensions, and Safari WebExtension source connectors for detecting direct media, HLS playlists, YouTube pages, quality selection, extension Options, and opening the app via the URL scheme.
  • Diagnostic logging for app/download lifecycle, external tool commands, exit status, and per-job yt-dlp/ffmpeg output.
  • Local scripts for building the .app bundle and creating a DMG.

Requirements

  • macOS 13 or later.
  • Xcode Command Line Tools / Swift Package Manager with Swift 6 support.
  • Optional runtime dependencies for browser video and HLS downloads:
brew install yt-dlp aria2 ffmpeg

MacVidCatch searches for yt-dlp, aria2c, and ffmpeg in common paths such as /opt/homebrew/bin, /usr/local/bin, /usr/bin, /bin, /opt/homebrew/opt/node/bin, and /usr/local/opt/node/bin. aria2c is used by yt-dlp as the external downloader on the main path. ffmpeg is used to remux HLS MPEG-TS output to MP4 when needed.

Build And Run

Run commands from the app/ directory:

swift build -c release
./scripts/build_app.sh
open ".build/release/MacVidCatch.app"

./scripts/build_app.sh runs a release build, retries after clearing Swift ModuleCache if the first build fails, creates .build/release/MacVidCatch.app, copies the MacVidCatch executable, and writes Info.plist including the macvidcatch URL scheme.

Create A DMG

Run commands from the app/ directory:

./scripts/build_app.sh
./scripts/create_dmg.sh

Default output:

.build/release/MacVidCatch.dmg

The DMG volume name is MacVidCatch. The script also creates an Applications symlink in the staging folder.

Signing and notarization require an Apple Developer ID:

codesign --deep --force --options runtime --sign "Developer ID Application: YOUR NAME"".build/release/MacVidCatch.app"
xcrun notarytool submit ".build/release/MacVidCatch.dmg" --keychain-profile YOUR_PROFILE --wait
xcrun stapler staple ".build/release/MacVidCatch.dmg"

How Downloads Work

Native HTTP/HTTPS

The native path is used for normal manual downloads.

  • The app sends a HEAD request to resolve the file name, file size, final URL, and resume support.
  • If the file supports range requests, is larger than 1 MiB, and maxConnectionsPerFile > 1, the app uses segmented download.
  • Otherwise, the app uses a single stream download with a partial file.
  • Resume appends to an existing partial file only when the server confirms a range response with 206 Partial Content; otherwise the partial is restarted safely.
  • Segmented downloads also require 206 Partial Content for every segment to avoid merging full-file responses from servers that ignore Range.
  • Partial files are stored under the temporary directory MacVidCatch/<job-id>/ and cleaned up on cancel/delete/retry.
  • The final file is validated against Content-Length when the size is known.

Browser Video / HLS / YouTube

The yt-dlp path is used for downloads from browser extensions, .m3u8 URLs, HLS MIME types, and YouTube URLs.

  • The app shows a native save dialog when it receives a browser deep link.
  • The app runs yt-dlp with the originating page referer when available.
  • The app applies a browser-specific user agent based on the source browser (chrome, firefox, or safari).
  • The app attempts to use cookies from the configured browser profile for Chrome/Firefox-style profiles, or Safari's browser cookie store for Safari-originated downloads.
  • The app uses aria2c as the external downloader on the main path.
  • For HLS, the app uses MPEG-TS handling and then remuxes to MP4 with ffmpeg if the output is detected as MPEG-TS.
  • yt-dlp[download] output is parsed to update progress, total size, and speed in the UI.
  • For known YouTube failure modes, the app retries with alternate extractor/client settings or without the external downloader and with more conservative formats.

Quality selected in the extension is passed to yt-dlp as a format selector. For example, 720 means the best format with height <=720; best leaves format selection to yt-dlp.

Browser Integration

The app registers this URL scheme in the bundle Info.plist:

macvidcatch://download?url=...

Query parameters used by the app:

  • url — required media or page URL to download.
  • pageUrl — optional originating page URL for the yt-dlp referer.
  • title — optional suggested display/output name.
  • mimeType — optional media type used to choose the native or yt-dlp path.
  • browser — optional source browser hint such as chrome, firefox, or safari.
  • quality — optional preferred quality, either best or a height such as 1080, 720, 480, or 360.

Chrome Extension

  1. Open chrome://extensions.
  2. Enable Developer Mode.
  3. Choose Load unpacked.
  4. Select BrowserExtension/chrome.
  5. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  6. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension Options page from chrome://extensions.

Firefox Extension

  1. Open about:debugging#/runtime/this-firefox.
  2. Choose Load Temporary Add-on….
  3. Select BrowserExtension/firefox/manifest.json.
  4. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  5. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension Options page from about:addons or the temporary add-on details page.

Safari Extension

Safari WebExtensions must be packaged in a small native app wrapper before Safari can load them. MacVidCatch keeps the portable source files in BrowserExtension/safari; generate the local wrapper with Xcode when you need to install or test it.

  1. Install the full Xcode app, not only Command Line Tools.
  2. From the app/ directory, run:
xcrun safari-web-extension-converter --macos-only --bundle-identifier com.macvidcatch.connector.safari BrowserExtension/safari
  1. Open the generated Xcode project.
  2. Choose the macOS app target, set local signing if Xcode asks for it, then run the app.
  3. In Safari, open Safari > Settings > Extensions and enable MacVidCatch Connector.
  4. If Safari requires unsigned local extensions for development, enable the Develop menu in Safari > Settings > Advanced, then choose Develop > Allow Unsigned Extensions.
  5. Grant website permissions when Safari prompts for them.
  6. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  7. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension settings page from Safari's extension settings.

Settings

Settings are automatically saved to JSON under Application Support.

Available app settings:

  • Default download folder.
  • Max simultaneous downloads.
  • Max connections per file.
  • Retry count and retry interval.
  • Global speed limit in bytes/second; 0 means unlimited.
  • Notifications toggle.
  • Browser cookies/profile path.
  • App-side domain blocklist.

Available browser extension settings, configured from the extension Options page:

  • Show or hide the floating download button.
  • Blocklist domains.
  • Allowlist domains.
  • Allowlist mode, which only permits domains in the allowlist.

Browser cookies/profile path accepts a Profiles folder, a specific profile folder, a cookies.sqlite file, or a Chromium-style profile folder containing Cookies. Default detection checks common Firefox, Firefox Developer Edition, LibreWolf, Waterfox, Chrome, Chromium, Edge, and Brave locations. Safari-originated downloads use yt-dlp's Safari cookie extractor directly; if macOS privacy permissions block Safari cookie access, MacVidCatch retries without browser cookies.

Note: extension settings live in browser extension storage and app settings live in macOS Application Support. The app cannot directly modify browser extension storage, so browser-facing controls are intentionally kept in the extension Options page.

Logging And Data

MacVidCatch stores app data under its Application Support folder:

~/Library/Application Support/MacVidCatch/

Data files:

  • downloads.json — download job list.
  • settings.json — app settings.

Logs are written to:

~/Library/Application Support/MacVidCatch/Logs/

Log files:

  • app.log — global app and download lifecycle events.
  • download-<UUID>.log — per-job output from yt-dlp/ffmpeg and related command details.

Use the Logs button in the UI to open the logs folder.

Command logs redact common sensitive URL query parameters such as token, signature, sig, policy, key, and jwt. Upstream output from yt-dlp/ffmpeg is still stored for diagnostics, so review logs before sharing them.

Validation

Run the lightweight utility checks and release build from app/:

./scripts/run_unit_checks.sh
swift build -c release

The check script covers small pure utility behavior that can run in this Command Line Tools environment. A full XCTest/Swift Testing target is not currently configured.

For build-only validation, run:

swift build -c release

If changes affect the app bundle, URL scheme, or packaging, also run:

./scripts/build_app.sh

Compliance And Safety

MacVidCatch is intended only for downloads the user is authorized to access and save. The app and extensions do not implement DRM, paywall, encryption, or access-control bypasses.

Current safety behavior:

  • Extensions detect common direct media such as .mp4, .mov, .webm, .m4v, HLS .m3u8, and supported YouTube pages for yt-dlp handling.
  • Extensions perform best-effort DRM detection from response headers and markers such as keyformat, widevine, playready, and fairplay.
  • If media appears protected, the floating button is not shown and the user receives an explanatory notice.
  • Extensions honor local blocklist and allowlist-mode settings before sending candidates to the app.
  • The app honors the persisted domain blocklist when enqueuing jobs.
  • Cookies/referer are used only for content the user is authorized to access through their local browser profile.

DRM and policy safeguards are conservative and best-effort; they are not a guarantee that every protected stream can be identified. Users are responsible for following source-site terms and downloading only content they are allowed to save.

About

Native macOS Internet Download Manager with browser video capture.

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

MacVidCatch

MacVidCatch is a native macOS 13+ Internet Download Manager with browser integration. The user-facing app name, .app bundle, DMG volume, Swift package, and executable target all use MacVidCatch.

Screenshots

MacVidCatch App

MacVidCatch app screenshot

Browser Floating Button

MacVidCatch browser floating button screenshot

Current Status

  • SwiftUI macOS app with a downloads list, status filters, manual download dialog, Settings, menu bar controls, and a button to open the logs folder.
  • Native HTTP/HTTPS downloader with metadata probing via HEAD, HTTP status validation, retry, buffered partial-file pause/resume, partial cleanup, final file-size validation, and segmented downloads that require 206 Partial Content responses.
  • Download queue with global parallel download limits and per-file connection limits.
  • Basic global speed limiting for the native single-download path.
  • Local persistence for jobs and settings under Application Support.
  • Custom URL scheme integration via macvidcatch://download?... for URLs sent by browser extensions.
  • Browser-extension downloads, HLS .m3u8, and YouTube URLs are routed through yt-dlp; normal manual direct HTTP downloads continue to use the native downloader unless the URL or MIME type indicates HLS.
  • Chrome Manifest V3, Firefox WebExtensions, and Safari WebExtension source connectors for detecting direct media, HLS playlists, YouTube pages, quality selection, extension Options, and opening the app via the URL scheme.
  • Diagnostic logging for app/download lifecycle, external tool commands, exit status, and per-job yt-dlp/ffmpeg output.
  • Local scripts for building the .app bundle and creating a DMG.

Requirements

  • macOS 13 or later.
  • Xcode Command Line Tools / Swift Package Manager with Swift 6 support.
  • Optional runtime dependencies for browser video and HLS downloads:
brew install yt-dlp aria2 ffmpeg

MacVidCatch searches for yt-dlp, aria2c, and ffmpeg in common paths such as /opt/homebrew/bin, /usr/local/bin, /usr/bin, /bin, /opt/homebrew/opt/node/bin, and /usr/local/opt/node/bin. aria2c is used by yt-dlp as the external downloader on the main path. ffmpeg is used to remux HLS MPEG-TS output to MP4 when needed.

Build And Run

Run commands from the app/ directory:

swift build -c release
./scripts/build_app.sh
open ".build/release/MacVidCatch.app"

./scripts/build_app.sh runs a release build, retries after clearing Swift ModuleCache if the first build fails, creates .build/release/MacVidCatch.app, copies the MacVidCatch executable, and writes Info.plist including the macvidcatch URL scheme.

Create A DMG

Run commands from the app/ directory:

./scripts/build_app.sh
./scripts/create_dmg.sh

Default output:

.build/release/MacVidCatch.dmg

The DMG volume name is MacVidCatch. The script also creates an Applications symlink in the staging folder.

Signing and notarization require an Apple Developer ID:

codesign --deep --force --options runtime --sign "Developer ID Application: YOUR NAME"".build/release/MacVidCatch.app"
xcrun notarytool submit ".build/release/MacVidCatch.dmg" --keychain-profile YOUR_PROFILE --wait
xcrun stapler staple ".build/release/MacVidCatch.dmg"

How Downloads Work

Native HTTP/HTTPS

The native path is used for normal manual downloads.

  • The app sends a HEAD request to resolve the file name, file size, final URL, and resume support.
  • If the file supports range requests, is larger than 1 MiB, and maxConnectionsPerFile > 1, the app uses segmented download.
  • Otherwise, the app uses a single stream download with a partial file.
  • Resume appends to an existing partial file only when the server confirms a range response with 206 Partial Content; otherwise the partial is restarted safely.
  • Segmented downloads also require 206 Partial Content for every segment to avoid merging full-file responses from servers that ignore Range.
  • Partial files are stored under the temporary directory MacVidCatch/<job-id>/ and cleaned up on cancel/delete/retry.
  • The final file is validated against Content-Length when the size is known.

Browser Video / HLS / YouTube

The yt-dlp path is used for downloads from browser extensions, .m3u8 URLs, HLS MIME types, and YouTube URLs.

  • The app shows a native save dialog when it receives a browser deep link.
  • The app runs yt-dlp with the originating page referer when available.
  • The app applies a browser-specific user agent based on the source browser (chrome, firefox, or safari).
  • The app attempts to use cookies from the configured browser profile for Chrome/Firefox-style profiles, or Safari's browser cookie store for Safari-originated downloads.
  • The app uses aria2c as the external downloader on the main path.
  • For HLS, the app uses MPEG-TS handling and then remuxes to MP4 with ffmpeg if the output is detected as MPEG-TS.
  • yt-dlp[download] output is parsed to update progress, total size, and speed in the UI.
  • For known YouTube failure modes, the app retries with alternate extractor/client settings or without the external downloader and with more conservative formats.

Quality selected in the extension is passed to yt-dlp as a format selector. For example, 720 means the best format with height <=720; best leaves format selection to yt-dlp.

Browser Integration

The app registers this URL scheme in the bundle Info.plist:

macvidcatch://download?url=...

Query parameters used by the app:

  • url — required media or page URL to download.
  • pageUrl — optional originating page URL for the yt-dlp referer.
  • title — optional suggested display/output name.
  • mimeType — optional media type used to choose the native or yt-dlp path.
  • browser — optional source browser hint such as chrome, firefox, or safari.
  • quality — optional preferred quality, either best or a height such as 1080, 720, 480, or 360.

Chrome Extension

  1. Open chrome://extensions.
  2. Enable Developer Mode.
  3. Choose Load unpacked.
  4. Select BrowserExtension/chrome.
  5. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  6. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension Options page from chrome://extensions.

Firefox Extension

  1. Open about:debugging#/runtime/this-firefox.
  2. Choose Load Temporary Add-on….
  3. Select BrowserExtension/firefox/manifest.json.
  4. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  5. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension Options page from about:addons or the temporary add-on details page.

Safari Extension

Safari WebExtensions must be packaged in a small native app wrapper before Safari can load them. MacVidCatch keeps the portable source files in BrowserExtension/safari; generate the local wrapper with Xcode when you need to install or test it.

  1. Install the full Xcode app, not only Command Line Tools.
  2. From the app/ directory, run:
xcrun safari-web-extension-converter --macos-only --bundle-identifier com.macvidcatch.connector.safari BrowserExtension/safari
  1. Open the generated Xcode project.
  2. Choose the macOS app target, set local signing if Xcode asks for it, then run the app.
  3. In Safari, open Safari > Settings > Extensions and enable MacVidCatch Connector.
  4. If Safari requires unsigned local extensions for development, enable the Develop menu in Safari > Settings > Advanced, then choose Develop > Allow Unsigned Extensions.
  5. Grant website permissions when Safari prompts for them.
  6. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  7. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension settings page from Safari's extension settings.

Settings

Settings are automatically saved to JSON under Application Support.

Available app settings:

  • Default download folder.
  • Max simultaneous downloads.
  • Max connections per file.
  • Retry count and retry interval.
  • Global speed limit in bytes/second; 0 means unlimited.
  • Notifications toggle.
  • Browser cookies/profile path.
  • App-side domain blocklist.

Available browser extension settings, configured from the extension Options page:

  • Show or hide the floating download button.
  • Blocklist domains.
  • Allowlist domains.
  • Allowlist mode, which only permits domains in the allowlist.

Browser cookies/profile path accepts a Profiles folder, a specific profile folder, a cookies.sqlite file, or a Chromium-style profile folder containing Cookies. Default detection checks common Firefox, Firefox Developer Edition, LibreWolf, Waterfox, Chrome, Chromium, Edge, and Brave locations. Safari-originated downloads use yt-dlp's Safari cookie extractor directly; if macOS privacy permissions block Safari cookie access, MacVidCatch retries without browser cookies.

Note: extension settings live in browser extension storage and app settings live in macOS Application Support. The app cannot directly modify browser extension storage, so browser-facing controls are intentionally kept in the extension Options page.

Logging And Data

MacVidCatch stores app data under its Application Support folder:

~/Library/Application Support/MacVidCatch/

Data files:

  • downloads.json — download job list.
  • settings.json — app settings.

Logs are written to:

~/Library/Application Support/MacVidCatch/Logs/

Log files:

  • app.log — global app and download lifecycle events.
  • download-<UUID>.log — per-job output from yt-dlp/ffmpeg and related command details.

Use the Logs button in the UI to open the logs folder.

Command logs redact common sensitive URL query parameters such as token, signature, sig, policy, key, and jwt. Upstream output from yt-dlp/ffmpeg is still stored for diagnostics, so review logs before sharing them.

Validation

Run the lightweight utility checks and release build from app/:

./scripts/run_unit_checks.sh
swift build -c release

The check script covers small pure utility behavior that can run in this Command Line Tools environment. A full XCTest/Swift Testing target is not currently configured.

For build-only validation, run:

swift build -c release

If changes affect the app bundle, URL scheme, or packaging, also run:

./scripts/build_app.sh

Compliance And Safety

MacVidCatch is intended only for downloads the user is authorized to access and save. The app and extensions do not implement DRM, paywall, encryption, or access-control bypasses.

Current safety behavior:

  • Extensions detect common direct media such as .mp4, .mov, .webm, .m4v, HLS .m3u8, and supported YouTube pages for yt-dlp handling.
  • Extensions perform best-effort DRM detection from response headers and markers such as keyformat, widevine, playready, and fairplay.
  • If media appears protected, the floating button is not shown and the user receives an explanatory notice.
  • Extensions honor local blocklist and allowlist-mode settings before sending candidates to the app.
  • The app honors the persisted domain blocklist when enqueuing jobs.
  • Cookies/referer are used only for content the user is authorized to access through their local browser profile.

DRM and policy safeguards are conservative and best-effort; they are not a guarantee that every protected stream can be identified. Users are responsible for following source-site terms and downloading only content they are allowed to save.

About

Native macOS Internet Download Manager with browser video capture.

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

MacVidCatch

MacVidCatch is a native macOS 13+ Internet Download Manager with browser integration. The user-facing app name, .app bundle, DMG volume, Swift package, and executable target all use MacVidCatch.

Screenshots

MacVidCatch App

MacVidCatch app screenshot

Browser Floating Button

MacVidCatch browser floating button screenshot

Current Status

  • SwiftUI macOS app with a downloads list, status filters, manual download dialog, Settings, menu bar controls, and a button to open the logs folder.
  • Native HTTP/HTTPS downloader with metadata probing via HEAD, HTTP status validation, retry, buffered partial-file pause/resume, partial cleanup, final file-size validation, and segmented downloads that require 206 Partial Content responses.
  • Download queue with global parallel download limits and per-file connection limits.
  • Basic global speed limiting for the native single-download path.
  • Local persistence for jobs and settings under Application Support.
  • Custom URL scheme integration via macvidcatch://download?... for URLs sent by browser extensions.
  • Browser-extension downloads, HLS .m3u8, and YouTube URLs are routed through yt-dlp; normal manual direct HTTP downloads continue to use the native downloader unless the URL or MIME type indicates HLS.
  • Chrome Manifest V3, Firefox WebExtensions, and Safari WebExtension source connectors for detecting direct media, HLS playlists, YouTube pages, quality selection, extension Options, and opening the app via the URL scheme.
  • Diagnostic logging for app/download lifecycle, external tool commands, exit status, and per-job yt-dlp/ffmpeg output.
  • Local scripts for building the .app bundle and creating a DMG.

Requirements

  • macOS 13 or later.
  • Xcode Command Line Tools / Swift Package Manager with Swift 6 support.
  • Optional runtime dependencies for browser video and HLS downloads:
brew install yt-dlp aria2 ffmpeg

MacVidCatch searches for yt-dlp, aria2c, and ffmpeg in common paths such as /opt/homebrew/bin, /usr/local/bin, /usr/bin, /bin, /opt/homebrew/opt/node/bin, and /usr/local/opt/node/bin. aria2c is used by yt-dlp as the external downloader on the main path. ffmpeg is used to remux HLS MPEG-TS output to MP4 when needed.

Build And Run

Run commands from the app/ directory:

swift build -c release
./scripts/build_app.sh
open ".build/release/MacVidCatch.app"

./scripts/build_app.sh runs a release build, retries after clearing Swift ModuleCache if the first build fails, creates .build/release/MacVidCatch.app, copies the MacVidCatch executable, and writes Info.plist including the macvidcatch URL scheme.

Create A DMG

Run commands from the app/ directory:

./scripts/build_app.sh
./scripts/create_dmg.sh

Default output:

.build/release/MacVidCatch.dmg

The DMG volume name is MacVidCatch. The script also creates an Applications symlink in the staging folder.

Signing and notarization require an Apple Developer ID:

codesign --deep --force --options runtime --sign "Developer ID Application: YOUR NAME"".build/release/MacVidCatch.app"
xcrun notarytool submit ".build/release/MacVidCatch.dmg" --keychain-profile YOUR_PROFILE --wait
xcrun stapler staple ".build/release/MacVidCatch.dmg"

How Downloads Work

Native HTTP/HTTPS

The native path is used for normal manual downloads.

  • The app sends a HEAD request to resolve the file name, file size, final URL, and resume support.
  • If the file supports range requests, is larger than 1 MiB, and maxConnectionsPerFile > 1, the app uses segmented download.
  • Otherwise, the app uses a single stream download with a partial file.
  • Resume appends to an existing partial file only when the server confirms a range response with 206 Partial Content; otherwise the partial is restarted safely.
  • Segmented downloads also require 206 Partial Content for every segment to avoid merging full-file responses from servers that ignore Range.
  • Partial files are stored under the temporary directory MacVidCatch/<job-id>/ and cleaned up on cancel/delete/retry.
  • The final file is validated against Content-Length when the size is known.

Browser Video / HLS / YouTube

The yt-dlp path is used for downloads from browser extensions, .m3u8 URLs, HLS MIME types, and YouTube URLs.

  • The app shows a native save dialog when it receives a browser deep link.
  • The app runs yt-dlp with the originating page referer when available.
  • The app applies a browser-specific user agent based on the source browser (chrome, firefox, or safari).
  • The app attempts to use cookies from the configured browser profile for Chrome/Firefox-style profiles, or Safari's browser cookie store for Safari-originated downloads.
  • The app uses aria2c as the external downloader on the main path.
  • For HLS, the app uses MPEG-TS handling and then remuxes to MP4 with ffmpeg if the output is detected as MPEG-TS.
  • yt-dlp[download] output is parsed to update progress, total size, and speed in the UI.
  • For known YouTube failure modes, the app retries with alternate extractor/client settings or without the external downloader and with more conservative formats.

Quality selected in the extension is passed to yt-dlp as a format selector. For example, 720 means the best format with height <=720; best leaves format selection to yt-dlp.

Browser Integration

The app registers this URL scheme in the bundle Info.plist:

macvidcatch://download?url=...

Query parameters used by the app:

  • url — required media or page URL to download.
  • pageUrl — optional originating page URL for the yt-dlp referer.
  • title — optional suggested display/output name.
  • mimeType — optional media type used to choose the native or yt-dlp path.
  • browser — optional source browser hint such as chrome, firefox, or safari.
  • quality — optional preferred quality, either best or a height such as 1080, 720, 480, or 360.

Chrome Extension

  1. Open chrome://extensions.
  2. Enable Developer Mode.
  3. Choose Load unpacked.
  4. Select BrowserExtension/chrome.
  5. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  6. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension Options page from chrome://extensions.

Firefox Extension

  1. Open about:debugging#/runtime/this-firefox.
  2. Choose Load Temporary Add-on….
  3. Select BrowserExtension/firefox/manifest.json.
  4. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  5. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension Options page from about:addons or the temporary add-on details page.

Safari Extension

Safari WebExtensions must be packaged in a small native app wrapper before Safari can load them. MacVidCatch keeps the portable source files in BrowserExtension/safari; generate the local wrapper with Xcode when you need to install or test it.

  1. Install the full Xcode app, not only Command Line Tools.
  2. From the app/ directory, run:
xcrun safari-web-extension-converter --macos-only --bundle-identifier com.macvidcatch.connector.safari BrowserExtension/safari
  1. Open the generated Xcode project.
  2. Choose the macOS app target, set local signing if Xcode asks for it, then run the app.
  3. In Safari, open Safari > Settings > Extensions and enable MacVidCatch Connector.
  4. If Safari requires unsigned local extensions for development, enable the Develop menu in Safari > Settings > Advanced, then choose Develop > Allow Unsigned Extensions.
  5. Grant website permissions when Safari prompts for them.
  6. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  7. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension settings page from Safari's extension settings.

Settings

Settings are automatically saved to JSON under Application Support.

Available app settings:

  • Default download folder.
  • Max simultaneous downloads.
  • Max connections per file.
  • Retry count and retry interval.
  • Global speed limit in bytes/second; 0 means unlimited.
  • Notifications toggle.
  • Browser cookies/profile path.
  • App-side domain blocklist.

Available browser extension settings, configured from the extension Options page:

  • Show or hide the floating download button.
  • Blocklist domains.
  • Allowlist domains.
  • Allowlist mode, which only permits domains in the allowlist.

Browser cookies/profile path accepts a Profiles folder, a specific profile folder, a cookies.sqlite file, or a Chromium-style profile folder containing Cookies. Default detection checks common Firefox, Firefox Developer Edition, LibreWolf, Waterfox, Chrome, Chromium, Edge, and Brave locations. Safari-originated downloads use yt-dlp's Safari cookie extractor directly; if macOS privacy permissions block Safari cookie access, MacVidCatch retries without browser cookies.

Note: extension settings live in browser extension storage and app settings live in macOS Application Support. The app cannot directly modify browser extension storage, so browser-facing controls are intentionally kept in the extension Options page.

Logging And Data

MacVidCatch stores app data under its Application Support folder:

~/Library/Application Support/MacVidCatch/

Data files:

  • downloads.json — download job list.
  • settings.json — app settings.

Logs are written to:

~/Library/Application Support/MacVidCatch/Logs/

Log files:

  • app.log — global app and download lifecycle events.
  • download-<UUID>.log — per-job output from yt-dlp/ffmpeg and related command details.

Use the Logs button in the UI to open the logs folder.

Command logs redact common sensitive URL query parameters such as token, signature, sig, policy, key, and jwt. Upstream output from yt-dlp/ffmpeg is still stored for diagnostics, so review logs before sharing them.

Validation

Run the lightweight utility checks and release build from app/:

./scripts/run_unit_checks.sh
swift build -c release

The check script covers small pure utility behavior that can run in this Command Line Tools environment. A full XCTest/Swift Testing target is not currently configured.

For build-only validation, run:

swift build -c release

If changes affect the app bundle, URL scheme, or packaging, also run:

./scripts/build_app.sh

Compliance And Safety

MacVidCatch is intended only for downloads the user is authorized to access and save. The app and extensions do not implement DRM, paywall, encryption, or access-control bypasses.

Current safety behavior:

  • Extensions detect common direct media such as .mp4, .mov, .webm, .m4v, HLS .m3u8, and supported YouTube pages for yt-dlp handling.
  • Extensions perform best-effort DRM detection from response headers and markers such as keyformat, widevine, playready, and fairplay.
  • If media appears protected, the floating button is not shown and the user receives an explanatory notice.
  • Extensions honor local blocklist and allowlist-mode settings before sending candidates to the app.
  • The app honors the persisted domain blocklist when enqueuing jobs.
  • Cookies/referer are used only for content the user is authorized to access through their local browser profile.

DRM and policy safeguards are conservative and best-effort; they are not a guarantee that every protected stream can be identified. Users are responsible for following source-site terms and downloading only content they are allowed to save.

About

Native macOS Internet Download Manager with browser video capture.

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

MacVidCatch

MacVidCatch is a native macOS 13+ Internet Download Manager with browser integration. The user-facing app name, .app bundle, DMG volume, Swift package, and executable target all use MacVidCatch.

Screenshots

MacVidCatch App

MacVidCatch app screenshot

Browser Floating Button

MacVidCatch browser floating button screenshot

Current Status

  • SwiftUI macOS app with a downloads list, status filters, manual download dialog, Settings, menu bar controls, and a button to open the logs folder.
  • Native HTTP/HTTPS downloader with metadata probing via HEAD, HTTP status validation, retry, buffered partial-file pause/resume, partial cleanup, final file-size validation, and segmented downloads that require 206 Partial Content responses.
  • Download queue with global parallel download limits and per-file connection limits.
  • Basic global speed limiting for the native single-download path.
  • Local persistence for jobs and settings under Application Support.
  • Custom URL scheme integration via macvidcatch://download?... for URLs sent by browser extensions.
  • Browser-extension downloads, HLS .m3u8, and YouTube URLs are routed through yt-dlp; normal manual direct HTTP downloads continue to use the native downloader unless the URL or MIME type indicates HLS.
  • Chrome Manifest V3, Firefox WebExtensions, and Safari WebExtension source connectors for detecting direct media, HLS playlists, YouTube pages, quality selection, extension Options, and opening the app via the URL scheme.
  • Diagnostic logging for app/download lifecycle, external tool commands, exit status, and per-job yt-dlp/ffmpeg output.
  • Local scripts for building the .app bundle and creating a DMG.

Requirements

  • macOS 13 or later.
  • Xcode Command Line Tools / Swift Package Manager with Swift 6 support.
  • Optional runtime dependencies for browser video and HLS downloads:
brew install yt-dlp aria2 ffmpeg

MacVidCatch searches for yt-dlp, aria2c, and ffmpeg in common paths such as /opt/homebrew/bin, /usr/local/bin, /usr/bin, /bin, /opt/homebrew/opt/node/bin, and /usr/local/opt/node/bin. aria2c is used by yt-dlp as the external downloader on the main path. ffmpeg is used to remux HLS MPEG-TS output to MP4 when needed.

Build And Run

Run commands from the app/ directory:

swift build -c release
./scripts/build_app.sh
open ".build/release/MacVidCatch.app"

./scripts/build_app.sh runs a release build, retries after clearing Swift ModuleCache if the first build fails, creates .build/release/MacVidCatch.app, copies the MacVidCatch executable, and writes Info.plist including the macvidcatch URL scheme.

Create A DMG

Run commands from the app/ directory:

./scripts/build_app.sh
./scripts/create_dmg.sh

Default output:

.build/release/MacVidCatch.dmg

The DMG volume name is MacVidCatch. The script also creates an Applications symlink in the staging folder.

Signing and notarization require an Apple Developer ID:

codesign --deep --force --options runtime --sign "Developer ID Application: YOUR NAME"".build/release/MacVidCatch.app"
xcrun notarytool submit ".build/release/MacVidCatch.dmg" --keychain-profile YOUR_PROFILE --wait
xcrun stapler staple ".build/release/MacVidCatch.dmg"

How Downloads Work

Native HTTP/HTTPS

The native path is used for normal manual downloads.

  • The app sends a HEAD request to resolve the file name, file size, final URL, and resume support.
  • If the file supports range requests, is larger than 1 MiB, and maxConnectionsPerFile > 1, the app uses segmented download.
  • Otherwise, the app uses a single stream download with a partial file.
  • Resume appends to an existing partial file only when the server confirms a range response with 206 Partial Content; otherwise the partial is restarted safely.
  • Segmented downloads also require 206 Partial Content for every segment to avoid merging full-file responses from servers that ignore Range.
  • Partial files are stored under the temporary directory MacVidCatch/<job-id>/ and cleaned up on cancel/delete/retry.
  • The final file is validated against Content-Length when the size is known.

Browser Video / HLS / YouTube

The yt-dlp path is used for downloads from browser extensions, .m3u8 URLs, HLS MIME types, and YouTube URLs.

  • The app shows a native save dialog when it receives a browser deep link.
  • The app runs yt-dlp with the originating page referer when available.
  • The app applies a browser-specific user agent based on the source browser (chrome, firefox, or safari).
  • The app attempts to use cookies from the configured browser profile for Chrome/Firefox-style profiles, or Safari's browser cookie store for Safari-originated downloads.
  • The app uses aria2c as the external downloader on the main path.
  • For HLS, the app uses MPEG-TS handling and then remuxes to MP4 with ffmpeg if the output is detected as MPEG-TS.
  • yt-dlp[download] output is parsed to update progress, total size, and speed in the UI.
  • For known YouTube failure modes, the app retries with alternate extractor/client settings or without the external downloader and with more conservative formats.

Quality selected in the extension is passed to yt-dlp as a format selector. For example, 720 means the best format with height <=720; best leaves format selection to yt-dlp.

Browser Integration

The app registers this URL scheme in the bundle Info.plist:

macvidcatch://download?url=...

Query parameters used by the app:

  • url — required media or page URL to download.
  • pageUrl — optional originating page URL for the yt-dlp referer.
  • title — optional suggested display/output name.
  • mimeType — optional media type used to choose the native or yt-dlp path.
  • browser — optional source browser hint such as chrome, firefox, or safari.
  • quality — optional preferred quality, either best or a height such as 1080, 720, 480, or 360.

Chrome Extension

  1. Open chrome://extensions.
  2. Enable Developer Mode.
  3. Choose Load unpacked.
  4. Select BrowserExtension/chrome.
  5. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  6. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension Options page from chrome://extensions.

Firefox Extension

  1. Open about:debugging#/runtime/this-firefox.
  2. Choose Load Temporary Add-on….
  3. Select BrowserExtension/firefox/manifest.json.
  4. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  5. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension Options page from about:addons or the temporary add-on details page.

Safari Extension

Safari WebExtensions must be packaged in a small native app wrapper before Safari can load them. MacVidCatch keeps the portable source files in BrowserExtension/safari; generate the local wrapper with Xcode when you need to install or test it.

  1. Install the full Xcode app, not only Command Line Tools.
  2. From the app/ directory, run:
xcrun safari-web-extension-converter --macos-only --bundle-identifier com.macvidcatch.connector.safari BrowserExtension/safari
  1. Open the generated Xcode project.
  2. Choose the macOS app target, set local signing if Xcode asks for it, then run the app.
  3. In Safari, open Safari > Settings > Extensions and enable MacVidCatch Connector.
  4. If Safari requires unsigned local extensions for development, enable the Develop menu in Safari > Settings > Advanced, then choose Develop > Allow Unsigned Extensions.
  5. Grant website permissions when Safari prompts for them.
  6. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  7. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension settings page from Safari's extension settings.

Settings

Settings are automatically saved to JSON under Application Support.

Available app settings:

  • Default download folder.
  • Max simultaneous downloads.
  • Max connections per file.
  • Retry count and retry interval.
  • Global speed limit in bytes/second; 0 means unlimited.
  • Notifications toggle.
  • Browser cookies/profile path.
  • App-side domain blocklist.

Available browser extension settings, configured from the extension Options page:

  • Show or hide the floating download button.
  • Blocklist domains.
  • Allowlist domains.
  • Allowlist mode, which only permits domains in the allowlist.

Browser cookies/profile path accepts a Profiles folder, a specific profile folder, a cookies.sqlite file, or a Chromium-style profile folder containing Cookies. Default detection checks common Firefox, Firefox Developer Edition, LibreWolf, Waterfox, Chrome, Chromium, Edge, and Brave locations. Safari-originated downloads use yt-dlp's Safari cookie extractor directly; if macOS privacy permissions block Safari cookie access, MacVidCatch retries without browser cookies.

Note: extension settings live in browser extension storage and app settings live in macOS Application Support. The app cannot directly modify browser extension storage, so browser-facing controls are intentionally kept in the extension Options page.

Logging And Data

MacVidCatch stores app data under its Application Support folder:

~/Library/Application Support/MacVidCatch/

Data files:

  • downloads.json — download job list.
  • settings.json — app settings.

Logs are written to:

~/Library/Application Support/MacVidCatch/Logs/

Log files:

  • app.log — global app and download lifecycle events.
  • download-<UUID>.log — per-job output from yt-dlp/ffmpeg and related command details.

Use the Logs button in the UI to open the logs folder.

Command logs redact common sensitive URL query parameters such as token, signature, sig, policy, key, and jwt. Upstream output from yt-dlp/ffmpeg is still stored for diagnostics, so review logs before sharing them.

Validation

Run the lightweight utility checks and release build from app/:

./scripts/run_unit_checks.sh
swift build -c release

The check script covers small pure utility behavior that can run in this Command Line Tools environment. A full XCTest/Swift Testing target is not currently configured.

For build-only validation, run:

swift build -c release

If changes affect the app bundle, URL scheme, or packaging, also run:

./scripts/build_app.sh

Compliance And Safety

MacVidCatch is intended only for downloads the user is authorized to access and save. The app and extensions do not implement DRM, paywall, encryption, or access-control bypasses.

Current safety behavior:

  • Extensions detect common direct media such as .mp4, .mov, .webm, .m4v, HLS .m3u8, and supported YouTube pages for yt-dlp handling.
  • Extensions perform best-effort DRM detection from response headers and markers such as keyformat, widevine, playready, and fairplay.
  • If media appears protected, the floating button is not shown and the user receives an explanatory notice.
  • Extensions honor local blocklist and allowlist-mode settings before sending candidates to the app.
  • The app honors the persisted domain blocklist when enqueuing jobs.
  • Cookies/referer are used only for content the user is authorized to access through their local browser profile.

DRM and policy safeguards are conservative and best-effort; they are not a guarantee that every protected stream can be identified. Users are responsible for following source-site terms and downloading only content they are allowed to save.

About

Native macOS Internet Download Manager with browser video capture.

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

MacVidCatch

MacVidCatch is a native macOS 13+ Internet Download Manager with browser integration. The user-facing app name, .app bundle, DMG volume, Swift package, and executable target all use MacVidCatch.

Screenshots

MacVidCatch App

MacVidCatch app screenshot

Browser Floating Button

MacVidCatch browser floating button screenshot

Current Status

  • SwiftUI macOS app with a downloads list, status filters, manual download dialog, Settings, menu bar controls, and a button to open the logs folder.
  • Native HTTP/HTTPS downloader with metadata probing via HEAD, HTTP status validation, retry, buffered partial-file pause/resume, partial cleanup, final file-size validation, and segmented downloads that require 206 Partial Content responses.
  • Download queue with global parallel download limits and per-file connection limits.
  • Basic global speed limiting for the native single-download path.
  • Local persistence for jobs and settings under Application Support.
  • Custom URL scheme integration via macvidcatch://download?... for URLs sent by browser extensions.
  • Browser-extension downloads, HLS .m3u8, and YouTube URLs are routed through yt-dlp; normal manual direct HTTP downloads continue to use the native downloader unless the URL or MIME type indicates HLS.
  • Chrome Manifest V3, Firefox WebExtensions, and Safari WebExtension source connectors for detecting direct media, HLS playlists, YouTube pages, quality selection, extension Options, and opening the app via the URL scheme.
  • Diagnostic logging for app/download lifecycle, external tool commands, exit status, and per-job yt-dlp/ffmpeg output.
  • Local scripts for building the .app bundle and creating a DMG.

Requirements

  • macOS 13 or later.
  • Xcode Command Line Tools / Swift Package Manager with Swift 6 support.
  • Optional runtime dependencies for browser video and HLS downloads:
brew install yt-dlp aria2 ffmpeg

MacVidCatch searches for yt-dlp, aria2c, and ffmpeg in common paths such as /opt/homebrew/bin, /usr/local/bin, /usr/bin, /bin, /opt/homebrew/opt/node/bin, and /usr/local/opt/node/bin. aria2c is used by yt-dlp as the external downloader on the main path. ffmpeg is used to remux HLS MPEG-TS output to MP4 when needed.

Build And Run

Run commands from the app/ directory:

swift build -c release
./scripts/build_app.sh
open ".build/release/MacVidCatch.app"

./scripts/build_app.sh runs a release build, retries after clearing Swift ModuleCache if the first build fails, creates .build/release/MacVidCatch.app, copies the MacVidCatch executable, and writes Info.plist including the macvidcatch URL scheme.

Create A DMG

Run commands from the app/ directory:

./scripts/build_app.sh
./scripts/create_dmg.sh

Default output:

.build/release/MacVidCatch.dmg

The DMG volume name is MacVidCatch. The script also creates an Applications symlink in the staging folder.

Signing and notarization require an Apple Developer ID:

codesign --deep --force --options runtime --sign "Developer ID Application: YOUR NAME"".build/release/MacVidCatch.app"
xcrun notarytool submit ".build/release/MacVidCatch.dmg" --keychain-profile YOUR_PROFILE --wait
xcrun stapler staple ".build/release/MacVidCatch.dmg"

How Downloads Work

Native HTTP/HTTPS

The native path is used for normal manual downloads.

  • The app sends a HEAD request to resolve the file name, file size, final URL, and resume support.
  • If the file supports range requests, is larger than 1 MiB, and maxConnectionsPerFile > 1, the app uses segmented download.
  • Otherwise, the app uses a single stream download with a partial file.
  • Resume appends to an existing partial file only when the server confirms a range response with 206 Partial Content; otherwise the partial is restarted safely.
  • Segmented downloads also require 206 Partial Content for every segment to avoid merging full-file responses from servers that ignore Range.
  • Partial files are stored under the temporary directory MacVidCatch/<job-id>/ and cleaned up on cancel/delete/retry.
  • The final file is validated against Content-Length when the size is known.

Browser Video / HLS / YouTube

The yt-dlp path is used for downloads from browser extensions, .m3u8 URLs, HLS MIME types, and YouTube URLs.

  • The app shows a native save dialog when it receives a browser deep link.
  • The app runs yt-dlp with the originating page referer when available.
  • The app applies a browser-specific user agent based on the source browser (chrome, firefox, or safari).
  • The app attempts to use cookies from the configured browser profile for Chrome/Firefox-style profiles, or Safari's browser cookie store for Safari-originated downloads.
  • The app uses aria2c as the external downloader on the main path.
  • For HLS, the app uses MPEG-TS handling and then remuxes to MP4 with ffmpeg if the output is detected as MPEG-TS.
  • yt-dlp[download] output is parsed to update progress, total size, and speed in the UI.
  • For known YouTube failure modes, the app retries with alternate extractor/client settings or without the external downloader and with more conservative formats.

Quality selected in the extension is passed to yt-dlp as a format selector. For example, 720 means the best format with height <=720; best leaves format selection to yt-dlp.

Browser Integration

The app registers this URL scheme in the bundle Info.plist:

macvidcatch://download?url=...

Query parameters used by the app:

  • url — required media or page URL to download.
  • pageUrl — optional originating page URL for the yt-dlp referer.
  • title — optional suggested display/output name.
  • mimeType — optional media type used to choose the native or yt-dlp path.
  • browser — optional source browser hint such as chrome, firefox, or safari.
  • quality — optional preferred quality, either best or a height such as 1080, 720, 480, or 360.

Chrome Extension

  1. Open chrome://extensions.
  2. Enable Developer Mode.
  3. Choose Load unpacked.
  4. Select BrowserExtension/chrome.
  5. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  6. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension Options page from chrome://extensions.

Firefox Extension

  1. Open about:debugging#/runtime/this-firefox.
  2. Choose Load Temporary Add-on….
  3. Select BrowserExtension/firefox/manifest.json.
  4. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  5. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension Options page from about:addons or the temporary add-on details page.

Safari Extension

Safari WebExtensions must be packaged in a small native app wrapper before Safari can load them. MacVidCatch keeps the portable source files in BrowserExtension/safari; generate the local wrapper with Xcode when you need to install or test it.

  1. Install the full Xcode app, not only Command Line Tools.
  2. From the app/ directory, run:
xcrun safari-web-extension-converter --macos-only --bundle-identifier com.macvidcatch.connector.safari BrowserExtension/safari
  1. Open the generated Xcode project.
  2. Choose the macOS app target, set local signing if Xcode asks for it, then run the app.
  3. In Safari, open Safari > Settings > Extensions and enable MacVidCatch Connector.
  4. If Safari requires unsigned local extensions for development, enable the Develop menu in Safari > Settings > Advanced, then choose Develop > Allow Unsigned Extensions.
  5. Grant website permissions when Safari prompts for them.
  6. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  7. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension settings page from Safari's extension settings.

Settings

Settings are automatically saved to JSON under Application Support.

Available app settings:

  • Default download folder.
  • Max simultaneous downloads.
  • Max connections per file.
  • Retry count and retry interval.
  • Global speed limit in bytes/second; 0 means unlimited.
  • Notifications toggle.
  • Browser cookies/profile path.
  • App-side domain blocklist.

Available browser extension settings, configured from the extension Options page:

  • Show or hide the floating download button.
  • Blocklist domains.
  • Allowlist domains.
  • Allowlist mode, which only permits domains in the allowlist.

Browser cookies/profile path accepts a Profiles folder, a specific profile folder, a cookies.sqlite file, or a Chromium-style profile folder containing Cookies. Default detection checks common Firefox, Firefox Developer Edition, LibreWolf, Waterfox, Chrome, Chromium, Edge, and Brave locations. Safari-originated downloads use yt-dlp's Safari cookie extractor directly; if macOS privacy permissions block Safari cookie access, MacVidCatch retries without browser cookies.

Note: extension settings live in browser extension storage and app settings live in macOS Application Support. The app cannot directly modify browser extension storage, so browser-facing controls are intentionally kept in the extension Options page.

Logging And Data

MacVidCatch stores app data under its Application Support folder:

~/Library/Application Support/MacVidCatch/

Data files:

  • downloads.json — download job list.
  • settings.json — app settings.

Logs are written to:

~/Library/Application Support/MacVidCatch/Logs/

Log files:

  • app.log — global app and download lifecycle events.
  • download-<UUID>.log — per-job output from yt-dlp/ffmpeg and related command details.

Use the Logs button in the UI to open the logs folder.

Command logs redact common sensitive URL query parameters such as token, signature, sig, policy, key, and jwt. Upstream output from yt-dlp/ffmpeg is still stored for diagnostics, so review logs before sharing them.

Validation

Run the lightweight utility checks and release build from app/:

./scripts/run_unit_checks.sh
swift build -c release

The check script covers small pure utility behavior that can run in this Command Line Tools environment. A full XCTest/Swift Testing target is not currently configured.

For build-only validation, run:

swift build -c release

If changes affect the app bundle, URL scheme, or packaging, also run:

./scripts/build_app.sh

Compliance And Safety

MacVidCatch is intended only for downloads the user is authorized to access and save. The app and extensions do not implement DRM, paywall, encryption, or access-control bypasses.

Current safety behavior:

  • Extensions detect common direct media such as .mp4, .mov, .webm, .m4v, HLS .m3u8, and supported YouTube pages for yt-dlp handling.
  • Extensions perform best-effort DRM detection from response headers and markers such as keyformat, widevine, playready, and fairplay.
  • If media appears protected, the floating button is not shown and the user receives an explanatory notice.
  • Extensions honor local blocklist and allowlist-mode settings before sending candidates to the app.
  • The app honors the persisted domain blocklist when enqueuing jobs.
  • Cookies/referer are used only for content the user is authorized to access through their local browser profile.

DRM and policy safeguards are conservative and best-effort; they are not a guarantee that every protected stream can be identified. Users are responsible for following source-site terms and downloading only content they are allowed to save.

About

Native macOS Internet Download Manager with browser video capture.

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

MacVidCatch

MacVidCatch is a native macOS 13+ Internet Download Manager with browser integration. The user-facing app name, .app bundle, DMG volume, Swift package, and executable target all use MacVidCatch.

Screenshots

MacVidCatch App

MacVidCatch app screenshot

Browser Floating Button

MacVidCatch browser floating button screenshot

Current Status

  • SwiftUI macOS app with a downloads list, status filters, manual download dialog, Settings, menu bar controls, and a button to open the logs folder.
  • Native HTTP/HTTPS downloader with metadata probing via HEAD, HTTP status validation, retry, buffered partial-file pause/resume, partial cleanup, final file-size validation, and segmented downloads that require 206 Partial Content responses.
  • Download queue with global parallel download limits and per-file connection limits.
  • Basic global speed limiting for the native single-download path.
  • Local persistence for jobs and settings under Application Support.
  • Custom URL scheme integration via macvidcatch://download?... for URLs sent by browser extensions.
  • Browser-extension downloads, HLS .m3u8, and YouTube URLs are routed through yt-dlp; normal manual direct HTTP downloads continue to use the native downloader unless the URL or MIME type indicates HLS.
  • Chrome Manifest V3, Firefox WebExtensions, and Safari WebExtension source connectors for detecting direct media, HLS playlists, YouTube pages, quality selection, extension Options, and opening the app via the URL scheme.
  • Diagnostic logging for app/download lifecycle, external tool commands, exit status, and per-job yt-dlp/ffmpeg output.
  • Local scripts for building the .app bundle and creating a DMG.

Requirements

  • macOS 13 or later.
  • Xcode Command Line Tools / Swift Package Manager with Swift 6 support.
  • Optional runtime dependencies for browser video and HLS downloads:
brew install yt-dlp aria2 ffmpeg

MacVidCatch searches for yt-dlp, aria2c, and ffmpeg in common paths such as /opt/homebrew/bin, /usr/local/bin, /usr/bin, /bin, /opt/homebrew/opt/node/bin, and /usr/local/opt/node/bin. aria2c is used by yt-dlp as the external downloader on the main path. ffmpeg is used to remux HLS MPEG-TS output to MP4 when needed.

Build And Run

Run commands from the app/ directory:

swift build -c release
./scripts/build_app.sh
open ".build/release/MacVidCatch.app"

./scripts/build_app.sh runs a release build, retries after clearing Swift ModuleCache if the first build fails, creates .build/release/MacVidCatch.app, copies the MacVidCatch executable, and writes Info.plist including the macvidcatch URL scheme.

Create A DMG

Run commands from the app/ directory:

./scripts/build_app.sh
./scripts/create_dmg.sh

Default output:

.build/release/MacVidCatch.dmg

The DMG volume name is MacVidCatch. The script also creates an Applications symlink in the staging folder.

Signing and notarization require an Apple Developer ID:

codesign --deep --force --options runtime --sign "Developer ID Application: YOUR NAME"".build/release/MacVidCatch.app"
xcrun notarytool submit ".build/release/MacVidCatch.dmg" --keychain-profile YOUR_PROFILE --wait
xcrun stapler staple ".build/release/MacVidCatch.dmg"

How Downloads Work

Native HTTP/HTTPS

The native path is used for normal manual downloads.

  • The app sends a HEAD request to resolve the file name, file size, final URL, and resume support.
  • If the file supports range requests, is larger than 1 MiB, and maxConnectionsPerFile > 1, the app uses segmented download.
  • Otherwise, the app uses a single stream download with a partial file.
  • Resume appends to an existing partial file only when the server confirms a range response with 206 Partial Content; otherwise the partial is restarted safely.
  • Segmented downloads also require 206 Partial Content for every segment to avoid merging full-file responses from servers that ignore Range.
  • Partial files are stored under the temporary directory MacVidCatch/<job-id>/ and cleaned up on cancel/delete/retry.
  • The final file is validated against Content-Length when the size is known.

Browser Video / HLS / YouTube

The yt-dlp path is used for downloads from browser extensions, .m3u8 URLs, HLS MIME types, and YouTube URLs.

  • The app shows a native save dialog when it receives a browser deep link.
  • The app runs yt-dlp with the originating page referer when available.
  • The app applies a browser-specific user agent based on the source browser (chrome, firefox, or safari).
  • The app attempts to use cookies from the configured browser profile for Chrome/Firefox-style profiles, or Safari's browser cookie store for Safari-originated downloads.
  • The app uses aria2c as the external downloader on the main path.
  • For HLS, the app uses MPEG-TS handling and then remuxes to MP4 with ffmpeg if the output is detected as MPEG-TS.
  • yt-dlp[download] output is parsed to update progress, total size, and speed in the UI.
  • For known YouTube failure modes, the app retries with alternate extractor/client settings or without the external downloader and with more conservative formats.

Quality selected in the extension is passed to yt-dlp as a format selector. For example, 720 means the best format with height <=720; best leaves format selection to yt-dlp.

Browser Integration

The app registers this URL scheme in the bundle Info.plist:

macvidcatch://download?url=...

Query parameters used by the app:

  • url — required media or page URL to download.
  • pageUrl — optional originating page URL for the yt-dlp referer.
  • title — optional suggested display/output name.
  • mimeType — optional media type used to choose the native or yt-dlp path.
  • browser — optional source browser hint such as chrome, firefox, or safari.
  • quality — optional preferred quality, either best or a height such as 1080, 720, 480, or 360.

Chrome Extension

  1. Open chrome://extensions.
  2. Enable Developer Mode.
  3. Choose Load unpacked.
  4. Select BrowserExtension/chrome.
  5. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  6. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension Options page from chrome://extensions.

Firefox Extension

  1. Open about:debugging#/runtime/this-firefox.
  2. Choose Load Temporary Add-on….
  3. Select BrowserExtension/firefox/manifest.json.
  4. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  5. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension Options page from about:addons or the temporary add-on details page.

Safari Extension

Safari WebExtensions must be packaged in a small native app wrapper before Safari can load them. MacVidCatch keeps the portable source files in BrowserExtension/safari; generate the local wrapper with Xcode when you need to install or test it.

  1. Install the full Xcode app, not only Command Line Tools.
  2. From the app/ directory, run:
xcrun safari-web-extension-converter --macos-only --bundle-identifier com.macvidcatch.connector.safari BrowserExtension/safari
  1. Open the generated Xcode project.
  2. Choose the macOS app target, set local signing if Xcode asks for it, then run the app.
  3. In Safari, open Safari > Settings > Extensions and enable MacVidCatch Connector.
  4. If Safari requires unsigned local extensions for development, enable the Develop menu in Safari > Settings > Advanced, then choose Develop > Allow Unsigned Extensions.
  5. Grant website permissions when Safari prompts for them.
  6. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  7. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension settings page from Safari's extension settings.

Settings

Settings are automatically saved to JSON under Application Support.

Available app settings:

  • Default download folder.
  • Max simultaneous downloads.
  • Max connections per file.
  • Retry count and retry interval.
  • Global speed limit in bytes/second; 0 means unlimited.
  • Notifications toggle.
  • Browser cookies/profile path.
  • App-side domain blocklist.

Available browser extension settings, configured from the extension Options page:

  • Show or hide the floating download button.
  • Blocklist domains.
  • Allowlist domains.
  • Allowlist mode, which only permits domains in the allowlist.

Browser cookies/profile path accepts a Profiles folder, a specific profile folder, a cookies.sqlite file, or a Chromium-style profile folder containing Cookies. Default detection checks common Firefox, Firefox Developer Edition, LibreWolf, Waterfox, Chrome, Chromium, Edge, and Brave locations. Safari-originated downloads use yt-dlp's Safari cookie extractor directly; if macOS privacy permissions block Safari cookie access, MacVidCatch retries without browser cookies.

Note: extension settings live in browser extension storage and app settings live in macOS Application Support. The app cannot directly modify browser extension storage, so browser-facing controls are intentionally kept in the extension Options page.

Logging And Data

MacVidCatch stores app data under its Application Support folder:

~/Library/Application Support/MacVidCatch/

Data files:

  • downloads.json — download job list.
  • settings.json — app settings.

Logs are written to:

~/Library/Application Support/MacVidCatch/Logs/

Log files:

  • app.log — global app and download lifecycle events.
  • download-<UUID>.log — per-job output from yt-dlp/ffmpeg and related command details.

Use the Logs button in the UI to open the logs folder.

Command logs redact common sensitive URL query parameters such as token, signature, sig, policy, key, and jwt. Upstream output from yt-dlp/ffmpeg is still stored for diagnostics, so review logs before sharing them.

Validation

Run the lightweight utility checks and release build from app/:

./scripts/run_unit_checks.sh
swift build -c release

The check script covers small pure utility behavior that can run in this Command Line Tools environment. A full XCTest/Swift Testing target is not currently configured.

For build-only validation, run:

swift build -c release

If changes affect the app bundle, URL scheme, or packaging, also run:

./scripts/build_app.sh

Compliance And Safety

MacVidCatch is intended only for downloads the user is authorized to access and save. The app and extensions do not implement DRM, paywall, encryption, or access-control bypasses.

Current safety behavior:

  • Extensions detect common direct media such as .mp4, .mov, .webm, .m4v, HLS .m3u8, and supported YouTube pages for yt-dlp handling.
  • Extensions perform best-effort DRM detection from response headers and markers such as keyformat, widevine, playready, and fairplay.
  • If media appears protected, the floating button is not shown and the user receives an explanatory notice.
  • Extensions honor local blocklist and allowlist-mode settings before sending candidates to the app.
  • The app honors the persisted domain blocklist when enqueuing jobs.
  • Cookies/referer are used only for content the user is authorized to access through their local browser profile.

DRM and policy safeguards are conservative and best-effort; they are not a guarantee that every protected stream can be identified. Users are responsible for following source-site terms and downloading only content they are allowed to save.

About

Native macOS Internet Download Manager with browser video capture.

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

MacVidCatch

MacVidCatch is a native macOS 13+ Internet Download Manager with browser integration. The user-facing app name, .app bundle, DMG volume, Swift package, and executable target all use MacVidCatch.

Screenshots

MacVidCatch App

MacVidCatch app screenshot

Browser Floating Button

MacVidCatch browser floating button screenshot

Current Status

  • SwiftUI macOS app with a downloads list, status filters, manual download dialog, Settings, menu bar controls, and a button to open the logs folder.
  • Native HTTP/HTTPS downloader with metadata probing via HEAD, HTTP status validation, retry, buffered partial-file pause/resume, partial cleanup, final file-size validation, and segmented downloads that require 206 Partial Content responses.
  • Download queue with global parallel download limits and per-file connection limits.
  • Basic global speed limiting for the native single-download path.
  • Local persistence for jobs and settings under Application Support.
  • Custom URL scheme integration via macvidcatch://download?... for URLs sent by browser extensions.
  • Browser-extension downloads, HLS .m3u8, and YouTube URLs are routed through yt-dlp; normal manual direct HTTP downloads continue to use the native downloader unless the URL or MIME type indicates HLS.
  • Chrome Manifest V3, Firefox WebExtensions, and Safari WebExtension source connectors for detecting direct media, HLS playlists, YouTube pages, quality selection, extension Options, and opening the app via the URL scheme.
  • Diagnostic logging for app/download lifecycle, external tool commands, exit status, and per-job yt-dlp/ffmpeg output.
  • Local scripts for building the .app bundle and creating a DMG.

Requirements

  • macOS 13 or later.
  • Xcode Command Line Tools / Swift Package Manager with Swift 6 support.
  • Optional runtime dependencies for browser video and HLS downloads:
brew install yt-dlp aria2 ffmpeg

MacVidCatch searches for yt-dlp, aria2c, and ffmpeg in common paths such as /opt/homebrew/bin, /usr/local/bin, /usr/bin, /bin, /opt/homebrew/opt/node/bin, and /usr/local/opt/node/bin. aria2c is used by yt-dlp as the external downloader on the main path. ffmpeg is used to remux HLS MPEG-TS output to MP4 when needed.

Build And Run

Run commands from the app/ directory:

swift build -c release
./scripts/build_app.sh
open ".build/release/MacVidCatch.app"

./scripts/build_app.sh runs a release build, retries after clearing Swift ModuleCache if the first build fails, creates .build/release/MacVidCatch.app, copies the MacVidCatch executable, and writes Info.plist including the macvidcatch URL scheme.

Create A DMG

Run commands from the app/ directory:

./scripts/build_app.sh
./scripts/create_dmg.sh

Default output:

.build/release/MacVidCatch.dmg

The DMG volume name is MacVidCatch. The script also creates an Applications symlink in the staging folder.

Signing and notarization require an Apple Developer ID:

codesign --deep --force --options runtime --sign "Developer ID Application: YOUR NAME"".build/release/MacVidCatch.app"
xcrun notarytool submit ".build/release/MacVidCatch.dmg" --keychain-profile YOUR_PROFILE --wait
xcrun stapler staple ".build/release/MacVidCatch.dmg"

How Downloads Work

Native HTTP/HTTPS

The native path is used for normal manual downloads.

  • The app sends a HEAD request to resolve the file name, file size, final URL, and resume support.
  • If the file supports range requests, is larger than 1 MiB, and maxConnectionsPerFile > 1, the app uses segmented download.
  • Otherwise, the app uses a single stream download with a partial file.
  • Resume appends to an existing partial file only when the server confirms a range response with 206 Partial Content; otherwise the partial is restarted safely.
  • Segmented downloads also require 206 Partial Content for every segment to avoid merging full-file responses from servers that ignore Range.
  • Partial files are stored under the temporary directory MacVidCatch/<job-id>/ and cleaned up on cancel/delete/retry.
  • The final file is validated against Content-Length when the size is known.

Browser Video / HLS / YouTube

The yt-dlp path is used for downloads from browser extensions, .m3u8 URLs, HLS MIME types, and YouTube URLs.

  • The app shows a native save dialog when it receives a browser deep link.
  • The app runs yt-dlp with the originating page referer when available.
  • The app applies a browser-specific user agent based on the source browser (chrome, firefox, or safari).
  • The app attempts to use cookies from the configured browser profile for Chrome/Firefox-style profiles, or Safari's browser cookie store for Safari-originated downloads.
  • The app uses aria2c as the external downloader on the main path.
  • For HLS, the app uses MPEG-TS handling and then remuxes to MP4 with ffmpeg if the output is detected as MPEG-TS.
  • yt-dlp[download] output is parsed to update progress, total size, and speed in the UI.
  • For known YouTube failure modes, the app retries with alternate extractor/client settings or without the external downloader and with more conservative formats.

Quality selected in the extension is passed to yt-dlp as a format selector. For example, 720 means the best format with height <=720; best leaves format selection to yt-dlp.

Browser Integration

The app registers this URL scheme in the bundle Info.plist:

macvidcatch://download?url=...

Query parameters used by the app:

  • url — required media or page URL to download.
  • pageUrl — optional originating page URL for the yt-dlp referer.
  • title — optional suggested display/output name.
  • mimeType — optional media type used to choose the native or yt-dlp path.
  • browser — optional source browser hint such as chrome, firefox, or safari.
  • quality — optional preferred quality, either best or a height such as 1080, 720, 480, or 360.

Chrome Extension

  1. Open chrome://extensions.
  2. Enable Developer Mode.
  3. Choose Load unpacked.
  4. Select BrowserExtension/chrome.
  5. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  6. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension Options page from chrome://extensions.

Firefox Extension

  1. Open about:debugging#/runtime/this-firefox.
  2. Choose Load Temporary Add-on….
  3. Select BrowserExtension/firefox/manifest.json.
  4. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  5. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension Options page from about:addons or the temporary add-on details page.

Safari Extension

Safari WebExtensions must be packaged in a small native app wrapper before Safari can load them. MacVidCatch keeps the portable source files in BrowserExtension/safari; generate the local wrapper with Xcode when you need to install or test it.

  1. Install the full Xcode app, not only Command Line Tools.
  2. From the app/ directory, run:
xcrun safari-web-extension-converter --macos-only --bundle-identifier com.macvidcatch.connector.safari BrowserExtension/safari
  1. Open the generated Xcode project.
  2. Choose the macOS app target, set local signing if Xcode asks for it, then run the app.
  3. In Safari, open Safari > Settings > Extensions and enable MacVidCatch Connector.
  4. If Safari requires unsigned local extensions for development, enable the Develop menu in Safari > Settings > Advanced, then choose Develop > Allow Unsigned Extensions.
  5. Grant website permissions when Safari prompts for them.
  6. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  7. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension settings page from Safari's extension settings.

Settings

Settings are automatically saved to JSON under Application Support.

Available app settings:

  • Default download folder.
  • Max simultaneous downloads.
  • Max connections per file.
  • Retry count and retry interval.
  • Global speed limit in bytes/second; 0 means unlimited.
  • Notifications toggle.
  • Browser cookies/profile path.
  • App-side domain blocklist.

Available browser extension settings, configured from the extension Options page:

  • Show or hide the floating download button.
  • Blocklist domains.
  • Allowlist domains.
  • Allowlist mode, which only permits domains in the allowlist.

Browser cookies/profile path accepts a Profiles folder, a specific profile folder, a cookies.sqlite file, or a Chromium-style profile folder containing Cookies. Default detection checks common Firefox, Firefox Developer Edition, LibreWolf, Waterfox, Chrome, Chromium, Edge, and Brave locations. Safari-originated downloads use yt-dlp's Safari cookie extractor directly; if macOS privacy permissions block Safari cookie access, MacVidCatch retries without browser cookies.

Note: extension settings live in browser extension storage and app settings live in macOS Application Support. The app cannot directly modify browser extension storage, so browser-facing controls are intentionally kept in the extension Options page.

Logging And Data

MacVidCatch stores app data under its Application Support folder:

~/Library/Application Support/MacVidCatch/

Data files:

  • downloads.json — download job list.
  • settings.json — app settings.

Logs are written to:

~/Library/Application Support/MacVidCatch/Logs/

Log files:

  • app.log — global app and download lifecycle events.
  • download-<UUID>.log — per-job output from yt-dlp/ffmpeg and related command details.

Use the Logs button in the UI to open the logs folder.

Command logs redact common sensitive URL query parameters such as token, signature, sig, policy, key, and jwt. Upstream output from yt-dlp/ffmpeg is still stored for diagnostics, so review logs before sharing them.

Validation

Run the lightweight utility checks and release build from app/:

./scripts/run_unit_checks.sh
swift build -c release

The check script covers small pure utility behavior that can run in this Command Line Tools environment. A full XCTest/Swift Testing target is not currently configured.

For build-only validation, run:

swift build -c release

If changes affect the app bundle, URL scheme, or packaging, also run:

./scripts/build_app.sh

Compliance And Safety

MacVidCatch is intended only for downloads the user is authorized to access and save. The app and extensions do not implement DRM, paywall, encryption, or access-control bypasses.

Current safety behavior:

  • Extensions detect common direct media such as .mp4, .mov, .webm, .m4v, HLS .m3u8, and supported YouTube pages for yt-dlp handling.
  • Extensions perform best-effort DRM detection from response headers and markers such as keyformat, widevine, playready, and fairplay.
  • If media appears protected, the floating button is not shown and the user receives an explanatory notice.
  • Extensions honor local blocklist and allowlist-mode settings before sending candidates to the app.
  • The app honors the persisted domain blocklist when enqueuing jobs.
  • Cookies/referer are used only for content the user is authorized to access through their local browser profile.

DRM and policy safeguards are conservative and best-effort; they are not a guarantee that every protected stream can be identified. Users are responsible for following source-site terms and downloading only content they are allowed to save.

About

Native macOS Internet Download Manager with browser video capture.

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

MacVidCatch

MacVidCatch is a native macOS 13+ Internet Download Manager with browser integration. The user-facing app name, .app bundle, DMG volume, Swift package, and executable target all use MacVidCatch.

Screenshots

MacVidCatch App

MacVidCatch app screenshot

Browser Floating Button

MacVidCatch browser floating button screenshot

Current Status

  • SwiftUI macOS app with a downloads list, status filters, manual download dialog, Settings, menu bar controls, and a button to open the logs folder.
  • Native HTTP/HTTPS downloader with metadata probing via HEAD, HTTP status validation, retry, buffered partial-file pause/resume, partial cleanup, final file-size validation, and segmented downloads that require 206 Partial Content responses.
  • Download queue with global parallel download limits and per-file connection limits.
  • Basic global speed limiting for the native single-download path.
  • Local persistence for jobs and settings under Application Support.
  • Custom URL scheme integration via macvidcatch://download?... for URLs sent by browser extensions.
  • Browser-extension downloads, HLS .m3u8, and YouTube URLs are routed through yt-dlp; normal manual direct HTTP downloads continue to use the native downloader unless the URL or MIME type indicates HLS.
  • Chrome Manifest V3, Firefox WebExtensions, and Safari WebExtension source connectors for detecting direct media, HLS playlists, YouTube pages, quality selection, extension Options, and opening the app via the URL scheme.
  • Diagnostic logging for app/download lifecycle, external tool commands, exit status, and per-job yt-dlp/ffmpeg output.
  • Local scripts for building the .app bundle and creating a DMG.

Requirements

  • macOS 13 or later.
  • Xcode Command Line Tools / Swift Package Manager with Swift 6 support.
  • Optional runtime dependencies for browser video and HLS downloads:
brew install yt-dlp aria2 ffmpeg

MacVidCatch searches for yt-dlp, aria2c, and ffmpeg in common paths such as /opt/homebrew/bin, /usr/local/bin, /usr/bin, /bin, /opt/homebrew/opt/node/bin, and /usr/local/opt/node/bin. aria2c is used by yt-dlp as the external downloader on the main path. ffmpeg is used to remux HLS MPEG-TS output to MP4 when needed.

Build And Run

Run commands from the app/ directory:

swift build -c release
./scripts/build_app.sh
open ".build/release/MacVidCatch.app"

./scripts/build_app.sh runs a release build, retries after clearing Swift ModuleCache if the first build fails, creates .build/release/MacVidCatch.app, copies the MacVidCatch executable, and writes Info.plist including the macvidcatch URL scheme.

Create A DMG

Run commands from the app/ directory:

./scripts/build_app.sh
./scripts/create_dmg.sh

Default output:

.build/release/MacVidCatch.dmg

The DMG volume name is MacVidCatch. The script also creates an Applications symlink in the staging folder.

Signing and notarization require an Apple Developer ID:

codesign --deep --force --options runtime --sign "Developer ID Application: YOUR NAME"".build/release/MacVidCatch.app"
xcrun notarytool submit ".build/release/MacVidCatch.dmg" --keychain-profile YOUR_PROFILE --wait
xcrun stapler staple ".build/release/MacVidCatch.dmg"

How Downloads Work

Native HTTP/HTTPS

The native path is used for normal manual downloads.

  • The app sends a HEAD request to resolve the file name, file size, final URL, and resume support.
  • If the file supports range requests, is larger than 1 MiB, and maxConnectionsPerFile > 1, the app uses segmented download.
  • Otherwise, the app uses a single stream download with a partial file.
  • Resume appends to an existing partial file only when the server confirms a range response with 206 Partial Content; otherwise the partial is restarted safely.
  • Segmented downloads also require 206 Partial Content for every segment to avoid merging full-file responses from servers that ignore Range.
  • Partial files are stored under the temporary directory MacVidCatch/<job-id>/ and cleaned up on cancel/delete/retry.
  • The final file is validated against Content-Length when the size is known.

Browser Video / HLS / YouTube

The yt-dlp path is used for downloads from browser extensions, .m3u8 URLs, HLS MIME types, and YouTube URLs.

  • The app shows a native save dialog when it receives a browser deep link.
  • The app runs yt-dlp with the originating page referer when available.
  • The app applies a browser-specific user agent based on the source browser (chrome, firefox, or safari).
  • The app attempts to use cookies from the configured browser profile for Chrome/Firefox-style profiles, or Safari's browser cookie store for Safari-originated downloads.
  • The app uses aria2c as the external downloader on the main path.
  • For HLS, the app uses MPEG-TS handling and then remuxes to MP4 with ffmpeg if the output is detected as MPEG-TS.
  • yt-dlp[download] output is parsed to update progress, total size, and speed in the UI.
  • For known YouTube failure modes, the app retries with alternate extractor/client settings or without the external downloader and with more conservative formats.

Quality selected in the extension is passed to yt-dlp as a format selector. For example, 720 means the best format with height <=720; best leaves format selection to yt-dlp.

Browser Integration

The app registers this URL scheme in the bundle Info.plist:

macvidcatch://download?url=...

Query parameters used by the app:

  • url — required media or page URL to download.
  • pageUrl — optional originating page URL for the yt-dlp referer.
  • title — optional suggested display/output name.
  • mimeType — optional media type used to choose the native or yt-dlp path.
  • browser — optional source browser hint such as chrome, firefox, or safari.
  • quality — optional preferred quality, either best or a height such as 1080, 720, 480, or 360.

Chrome Extension

  1. Open chrome://extensions.
  2. Enable Developer Mode.
  3. Choose Load unpacked.
  4. Select BrowserExtension/chrome.
  5. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  6. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension Options page from chrome://extensions.

Firefox Extension

  1. Open about:debugging#/runtime/this-firefox.
  2. Choose Load Temporary Add-on….
  3. Select BrowserExtension/firefox/manifest.json.
  4. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  5. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension Options page from about:addons or the temporary add-on details page.

Safari Extension

Safari WebExtensions must be packaged in a small native app wrapper before Safari can load them. MacVidCatch keeps the portable source files in BrowserExtension/safari; generate the local wrapper with Xcode when you need to install or test it.

  1. Install the full Xcode app, not only Command Line Tools.
  2. From the app/ directory, run:
xcrun safari-web-extension-converter --macos-only --bundle-identifier com.macvidcatch.connector.safari BrowserExtension/safari
  1. Open the generated Xcode project.
  2. Choose the macOS app target, set local signing if Xcode asks for it, then run the app.
  3. In Safari, open Safari > Settings > Extensions and enable MacVidCatch Connector.
  4. If Safari requires unsigned local extensions for development, enable the Develop menu in Safari > Settings > Advanced, then choose Develop > Allow Unsigned Extensions.
  5. Grant website permissions when Safari prompts for them.
  6. When direct media, HLS, or a YouTube page is detected, use the MacVidCatch floating button.
  7. To configure the floating button, blocklist, allowlist, or allowlist mode, open the extension settings page from Safari's extension settings.

Settings

Settings are automatically saved to JSON under Application Support.

Available app settings:

  • Default download folder.
  • Max simultaneous downloads.
  • Max connections per file.
  • Retry count and retry interval.
  • Global speed limit in bytes/second; 0 means unlimited.
  • Notifications toggle.
  • Browser cookies/profile path.
  • App-side domain blocklist.

Available browser extension settings, configured from the extension Options page:

  • Show or hide the floating download button.
  • Blocklist domains.
  • Allowlist domains.
  • Allowlist mode, which only permits domains in the allowlist.

Browser cookies/profile path accepts a Profiles folder, a specific profile folder, a cookies.sqlite file, or a Chromium-style profile folder containing Cookies. Default detection checks common Firefox, Firefox Developer Edition, LibreWolf, Waterfox, Chrome, Chromium, Edge, and Brave locations. Safari-originated downloads use yt-dlp's Safari cookie extractor directly; if macOS privacy permissions block Safari cookie access, MacVidCatch retries without browser cookies.

Note: extension settings live in browser extension storage and app settings live in macOS Application Support. The app cannot directly modify browser extension storage, so browser-facing controls are intentionally kept in the extension Options page.

Logging And Data

MacVidCatch stores app data under its Application Support folder:

~/Library/Application Support/MacVidCatch/

Data files:

  • downloads.json — download job list.
  • settings.json — app settings.

Logs are written to:

~/Library/Application Support/MacVidCatch/Logs/

Log files:

  • app.log — global app and download lifecycle events.
  • download-<UUID>.log — per-job output from yt-dlp/ffmpeg and related command details.

Use the Logs button in the UI to open the logs folder.

Command logs redact common sensitive URL query parameters such as token, signature, sig, policy, key, and jwt. Upstream output from yt-dlp/ffmpeg is still stored for diagnostics, so review logs before sharing them.

Validation

Run the lightweight utility checks and release build from app/:

./scripts/run_unit_checks.sh
swift build -c release

The check script covers small pure utility behavior that can run in this Command Line Tools environment. A full XCTest/Swift Testing target is not currently configured.

For build-only validation, run:

swift build -c release

If changes affect the app bundle, URL scheme, or packaging, also run:

./scripts/build_app.sh

Compliance And Safety

MacVidCatch is intended only for downloads the user is authorized to access and save. The app and extensions do not implement DRM, paywall, encryption, or access-control bypasses.

Current safety behavior:

  • Extensions detect common direct media such as .mp4, .mov, .webm, .m4v, HLS .m3u8, and supported YouTube pages for yt-dlp handling.
  • Extensions perform best-effort DRM detection from response headers and markers such as keyformat, widevine, playready, and fairplay.
  • If media appears protected, the floating button is not shown and the user receives an explanatory notice.
  • Extensions honor local blocklist and allowlist-mode settings before sending candidates to the app.
  • The app honors the persisted domain blocklist when enqueuing jobs.
  • Cookies/referer are used only for content the user is authorized to access through their local browser profile.

DRM and policy safeguards are conservative and best-effort; they are not a guarantee that every protected stream can be identified. Users are responsible for following source-site terms and downloading only content they are allowed to save.

About

Native macOS Internet Download Manager with browser video capture.

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages