Skip to main content

PyPI version Python versions License

mp32png

Pack MP3 files inside PNG images and extract them back
Bit-identical extraction. Real PNG. No data loss.
Website · GitHub · PyPI


What is this?

mp32png hides an MP3 file inside a standard PNG image. The output is a real, valid PNG that opens in any image viewer — with the MP3 data stored in custom PNG chunks. Extract the MP3 later and get back exactly the original file, byte for byte.

┌─────────────────────┐
│                     │
│       MP3PNG        │
│                     │
│      ♫  song.mp3    │
│                     │
└─────────────────────┘
   ↑ visible PNG cover
   + MP3 data hidden in dMP3 chunks

Install

pip install mp32png

Or from source:

git clone https://github.com/DenisVargaeu/MP32PNG.git
cd mp32png
pip install .

Requires Python 3.8+ and Pillow.

Quick Start

# Pack an MP3 into a PNG
mp32png pack song.mp3 song.png

# Extract it back
mp32png extract song.png restored.mp3

# Verify they match
mp32png hash song.mp3
mp32png hash song.png

Both hashes are identical — bit-for-bit the same file.

GUI — mp32png Studio

Prefer a desktop app? Launch the built-in graphical interface:

mp32png --gui

This opens mp32png Studio — a modern dark-themed desktop app with drag & drop support:

  • Pack — MP3 → PNG with cover selection (default / from ID3 metadata / custom image) and live preview
  • Extract — PNG → MP3 with automatic output naming
  • Verify — full container integrity report
  • Hash — SHA-256 with one-click copy

The GUI is an optional dependency and does not affect the CLI:

pip install "mp32png[gui]"

All operations run in the background, so the interface stays responsive.

Commands

pack — MP3 to PNG

# Basic pack
mp32png pack song.mp3 song.png

# Auto-extract cover art from MP3 ID3 tags
mp32png pack song.mp3 song.png --cover

# Use a specific cover image
mp32png pack song.mp3 song.png --cover album-art.jpg

Cover behavior:

Flag What happens
(none) Generates a minimalist dark default cover
--cover Extracts embedded artwork from MP3 ID3 APIC frame
--cover image.jpg Uses your image (PNG/JPEG/WebP, converted to PNG if needed)

extract — PNG to MP3

# Extract with custom output name
mp32png extract song.png restored.mp3

# Extract using original filename stored in container
mp32png extract song.png

verify — Check integrity

mp32png verify song.png

Output:

mp32png verify song.png
------------------------------
  ✓ Valid PNG
  ✓ dMP3 chunk found
  ✓ MP3 metadata valid
  ✓ MP3 size valid
  ✓ SHA-256 valid

Audio:
  Filename: song.mp3
  Size: 8.42 MB
  SHA-256: 91a8f7...

Status: VALID

hash — SHA-256 checksum

# Hash a raw MP3
mp32png hash song.mp3
SHA-256:
91a8f7...

# Hash a PNG (extracts embedded MP3 hash)
mp32png hash song.png
Embedded MP3 SHA-256:
91a8f7...

Both produce the same hash — useful for verifying roundtrip integrity.

How It Works

The MP3 binary data is stored in custom PNG ancillary chunks called dMP3, following the PNG specification. The visible image is a cover (auto-generated or from ID3 tags).

Container structure:

PNG signature
IHDR (image header)
IDAT (image data — the cover)
dMP3 #1 (1 MiB of MP3 data + header)
dMP3 #2 (1 MiB)
dMP3 #3 (remaining data)
...
IEND

Each dMP3 chunk follows the PNG spec:

4 bytes  length
4 bytes  type ("dMP3")
N bytes  data
4 bytes  CRC32

First dMP3 chunk contains the header:

Field Size Description
Magic 6 bytes MP3PNG
Version 1 byte Format version (1)
Filename length 2 bytes UTF-8 filename length
Filename N bytes Original MP3 filename
MIME length 2 bytes MIME type length
MIME type N bytes audio/mpeg
File size 8 bytes MP3 size in bytes (big-endian)
SHA-256 32 bytes Checksum of original MP3
MP3 data remaining First 1 MiB of audio

Bit-Identical Guarantee

mp32png pack original.mp3 packed.png
mp32png extract packed.png restored.mp3

# These MUST match
sha256sum original.mp3
# 91a8f7c3e2b1...

sha256sum restored.mp3
# 91a8f7c3e2b1...

Not "plays the same." Exactly the same bytes.

Error Handling

Error: File not found: song.mp3
Error: Invalid PNG file.
Error: No embedded MP3 found.
Error: Embedded MP3 checksum mismatch.
Error: Invalid CRC for chunk dMP3.

Project Structure

mp32png/
├── mp32png/
│   ├── __init__.py      # Package version
│   ├── __main__.py      # python -m mp32png
│   ├── cli.py           # CLI with argparse
│   ├── png.py           # PNG reader/writer
│   ├── container.py     # dMP3 container format
│   ├── encoder.py       # Pack: MP3 → PNG
│   ├── decoder.py       # Extract: PNG → MP3
│   ├── id3.py           # ID3v2 / APIC parser
│   ├── cover.py         # Cover art handling
│   ├── hashing.py       # SHA-256 utilities
│   └── gui/             # mp32png Studio (optional, PySide6)
├── tests/
│   └── test_all.py      # 24 tests
├── pyproject.toml
├── LICENSE
└── README.md

Requirements

  • Python 3.8+
  • Pillow (for cover image generation and format conversion)
  • PySide6 (only for mp32png --gui, install via pip install "mp32png[gui]")

License

MIT

Release files for mp32png 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mp32png 1.1.0
File Size Uploaded
mp32png-1.1.0.tar.gz 30.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mp32png 1.1.0
File Interpreter ABI Platform
mp32png-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 58.5 kB

Release files / mp32png-1.1.0.tar.gz

Download URL mp32png-1.1.0.tar.gz
Size 30.6 kB
Tags Source
SHA-256 checksum
How to use checksums
9a549c43bf8159bcc2e7ec91b694cf7bb7f7974fee9b4048600148b2f08f6ce2
BLAKE2b-256 checksum
How to use checksums
af1be6329bba653ba1466a2e8dc028ce5a21cb086b15c8d5885ed9bd443e5fde
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / mp32png-1.1.0-py3-none-any.whl

Download URL mp32png-1.1.0-py3-none-any.whl
Size 27.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
09528c31ebbb20f570a05c00bd933d5f733168c68c36328362d933834d822253
BLAKE2b-256 checksum
How to use checksums
8cf0742afdf9f06c4af474214f337713111ed826057d55426cd5a957e83e3090
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page