Racjin PS2 DSI container multiplexer/demultiplexer
Project description
DSI Muxer
Multiplexer/demultiplexer for the Racjin PS2 DSI container format.
DSI is a proprietary streaming container used by Racjin for PS2 cutscenes in games like:
- Fullmetal Alchemist and the Broken Angel
- Fullmetal Alchemist 2: Curse of the Crimson Elixir
- Busin 0: Wizardry Alternative NEO
No DSI muxer existed before this tool. VGMToolbox could demux DSI files but not create them.
Install
pip install dsi-muxer
Usage
Command Line
# Extract video and audio from a DSI file
dsi-muxer demux M004.DSI --video M004.m2v --audio M004.adpcm
# Create a new DSI from video + audio
dsi-muxer mux --video subtitled.m2v --audio jp_audio.adpcm --blocks 307 -o M004_new.DSI
# Show DSI file info
dsi-muxer info M004.DSI
Python API
from dsi_muxer import DSI
from dsi_muxer.container import ensure_end_of_sequence
# Demux
dsi = DSI.from_file("M004.DSI")
video = dsi.extract_video() # MPEG-2 elementary stream
audio = dsi.extract_audio() # PS2 SPU ADPCM
# Mux with proportional audio (for perfect A/V sync)
video = ensure_end_of_sequence(video)
new_dsi = DSI.mux(video, audio, nblocks=307)
new_dsi.to_file("M004_new.DSI")
# Inspect
for block in new_dsi.block_info():
print(f"Block {block['block']}: {block['frames']}f, "
f"aud={block['audio_size']}, vid={block['video_size']}")
How It Works
The DSI Format
DSI files are divided into fixed 0x40000 byte (256 KB) blocks. Each block contains:
- A 32-byte header identifying two streams (audio + video) with type tags and sizes
- 32 bytes of zero padding
- Interleaved audio and video data
Audio uses PS2 SPU ADPCM (44100 Hz, stereo, 0x100 interleave). Video is MPEG-2 Main Profile (512x448, 29.97 fps).
Proportional Audio Muxing
The key to perfect A/V sync in DSI is proportional audio distribution:
audio_per_block = frames_in_block * (total_audio / total_frames)
Blocks with more video frames get more audio. This ensures each block's audio duration matches its video duration. The PS2's SPU2 buffer smooths per-block variation.
The video is byte-sliced as a continuous stream — GOPs flow freely across block boundaries, just like the original game files. No per-block re-encoding or extra sequence headers.
Why This Matters
Unlike Sony's standard PSS format (which has timestamps for A/V sync), DSI has no timestamps. Sync is entirely determined by the audio/video ratio per block. Getting this ratio wrong causes audible desync during PS2 playback.
Format Reference
Block Header (32 bytes, little-endian)
| Offset | Type | Field |
|---|---|---|
| 0x00 | uint32 | Stream count (always 2) |
| 0x04 | uint32 | Stream 1 offset (always 64) |
| 0x08 | int32 | Stream 1 type (-8192=audio, -16384=video) |
| 0x0C | uint32 | Stream 1 size |
| 0x10 | uint32 | Stream 2 offset |
| 0x14 | int32 | Stream 2 type |
| 0x18 | uint32 | Stream 2 size |
| 0x1C | uint32 | Reserved (always 0) |
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dsi_muxer-1.1.0.tar.gz.
File metadata
- Download URL: dsi_muxer-1.1.0.tar.gz
- Upload date:
- Size: 8.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1f827468bac2aaffa4c013e1af34eb9814b76b4598c8556aae15542bd5e65947
|
|
| MD5 |
7f3d1003d2310bf5245a41c059938d9f
|
|
| BLAKE2b-256 |
37497be87b99e5c7f36977dee6ec1567bfb6ca910ee54fd177c628045946f106
|
File details
Details for the file dsi_muxer-1.1.0-py3-none-any.whl.
File metadata
- Download URL: dsi_muxer-1.1.0-py3-none-any.whl
- Upload date:
- Size: 8.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bae0218e6c85d7e144591468e31fb6c95e795b17a090899aa69f8a1bd0afa02b
|
|
| MD5 |
0e224eb09f8aee5385c80459bbd74bc3
|
|
| BLAKE2b-256 |
5ba3eac3e3a9bde93e70f4a982cc2b897237282df17f29661ef43082d6f90703
|