Skip to content

domabyte/Framecrypt

Repository files navigation

FrameCrypt

Hide any file inside a black-and-white video.

FrameCrypt zips your file into an AES-256 password-protected archive, then draws that archive as a grid of black and white blocks across the frames of a video. Decoding does the reverse. If you want, you can upload the video to YouTube and pull it back later.

The trick is that the blocks are big enough to survive video compression. Each bit is a solid square of pixels, so even after YouTube re-encodes the video, the squares are still readable. From my tests, a block stays intact as long as it's at least 4 pixels wide in the version you download. That's why the dense preset (1080p, 4px blocks) fits about 9× more data per frame than the old 720p/8px one and still comes back byte-for-byte through YouTube.

How it works

file ──AES-256 zip──► bytes ──► bits ──► black/white blocks ──► .mp4
                                                                  │
file ◄──AES-256 unzip── bytes ◄── bits ◄── read block centers ◄───┘

A small header (magic FCR1 + payload length) goes in first, so decoding is exact with no leftover padding.

Install

One line. It installs everything, then asks whether you want the web or terminal version and launches it.

macOS / Linux:

curl -fsSL https://raw.githubusercontent.com/domabyte/Framecrypt/master/install.sh | bash

Windows (PowerShell):

irm https://raw.githubusercontent.com/domabyte/Framecrypt/master/install.ps1 | iex

This grabs Python 3.10+ (or installs it), drops FrameCrypt in ~/framecrypt, sets up its own environment, and starts it. Run it again anytime to update.

Already cloned the repo? Just run sh installation.sh. It installs the dependencies and creates the folders. Everything is bundled (numpy, opencv, pyzipper, reedsolo for the core; rich, questionary, flask for the UIs; google and yt-dlp for YouTube), so nothing else to set up. You need Python 3.10+.

Running it

Run with no arguments to get the full terminal app:

python3 framecrypt.py

You get a sidebar menu, a file picker, live progress bars, the two encoding presets with a Reed-Solomon toggle, and the YouTube views. Press ? anytime for the keyboard shortcuts.

Prefer a browser? Start the web version:

python3 framecrypt.py web            # opens http://127.0.0.1:8462
python3 framecrypt.py web --port 9000 --no-browser

Drag and drop files to encode, see a size estimate, decode straight to a download, browse your library, and use the YouTube tab. It only listens on 127.0.0.1, so nothing leaves your machine.

Command line

Every action is also a plain command if you'd rather script it:

# Encode a file (asks for a password, saves to encoded_videos/)
python3 framecrypt.py encode secret.pdf

# Decode it back (asks for the password, saves to decoded_files/)
python3 framecrypt.py decode encoded_video.mp4

# Look at a video without decoding it (payload size, frames, ECC)
python3 framecrypt.py info encoded_video.mp4

# Upload to YouTube (kept unlisted)
python3 framecrypt.py upload encoded_video.mp4 --title "backup"

# Pull one back down
python3 framecrypt.py download <url-or-id>

# List what you've uploaded
python3 framecrypt.py list

# Connect your YouTube channel (or --logout to disconnect)
python3 framecrypt.py auth

Add --shred to encode if you want the original file deleted afterward. Decode and info figure out the resolution and block size on their own, so you never have to remember how a video was encoded.

Presets and error correction

Pick the layout with --preset:

  • standard — 720p, 8px blocks. Smallest video, safe everywhere.
  • dense (recommended) — 1080p, 4px blocks. About 9× more data per frame, and still survives a YouTube round-trip cleanly.

Error correction is separate from the preset. Add --ecc N to any preset to include Reed-Solomon parity (N bytes per 255-byte block, fixes up to N/2 bad bytes) if you expect rough re-encodes. --ecc 16 costs about 6% extra size. Decode notices ECC on its own, so there's no flag to remember when reading back.

python3 framecrypt.py encode secret.pdf --preset dense            # denser
python3 framecrypt.py encode secret.pdf --preset dense --ecc 16   # denser + protected

YouTube setup (optional)

You don't need any of this to use FrameCrypt. Encoding and decoding work fully offline. YouTube is just an optional place to keep your videos. Skip this section unless you want the upload and download features.

If you do want it, you bring your own Google OAuth client. It's free and keeps your API quota to yourself. The libraries are already installed, so this is all in the browser:

  1. Open the Google Cloud Console and create a project (or use one you already have).
  2. Go to APIs & Services → Library, search YouTube Data API v3, and enable it.
  3. Go to OAuth consent screen, choose External, fill in the app name and your email, and add your own Google account under Test users. This lets you use the app while it's unverified.
  4. Go to Credentials → Create Credentials → OAuth client ID, pick Desktop app, create it, and download the JSON.
  5. Give that file to FrameCrypt:
    • Web: drop it on the setup box on the YouTube page.
    • Terminal: the Account menu lets you browse to it, or run python3 framecrypt.py auth --client /path/to/downloaded.json.

The first time you connect, your browser opens. Approve the one-time "unverified app" screen (Advanced → Go to … (unsafe) — it's your own app), pick your channel, and you're done. The login is cached in ~/.credentials/. Switch channels anytime from the Account menu or with auth --logout.

Uploads are kept unlisted: not in feeds, search, or recommendations, only reachable by the exact link. Because they're unlisted, they download without any browser cookies. Download at the resolution the preset used — a lower-quality copy can corrupt the file.

Downloads use yt-dlp, which comes bundled. Unlisted videos need nothing extra. Older private videos still need cookies from a browser you're signed into (your default browser is detected first, and Arc works too), and macOS may ask once for Keychain access — click Always Allow. Signed-in downloads also need deno or node on your PATH for YouTube's bot check.

Project layout

File Purpose
framecrypt.py command line + interactive app
fc_video.py the core: turns bytes into frames and back
fc_crypto.py AES-256 archive create/extract
fc_ecc.py optional Reed-Solomon error correction
fc_ui.py terminal UI
fc_web.py + web/ optional local web UI
fc_youtube.py optional YouTube upload/download/list

— Dikshit Singh

About

FrameCrypt - A tool to convert your any file to protected video frames

Topics

Resources

Stars

5 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors