This release is a pre-release and may not be stable for production use.
hyperdeckwire
Python library for Blackmagic HyperDeck Studio recorders: transport control, clip listing and timeline editing over the HyperDeck Ethernet Protocol (TCP 9993), plus clip upload over the deck's built-in FTP server.
hyperdeckwire is small and dependency-free. It targets the 9993 + FTP
combination on purpose: the HTTP REST API that arrived in firmware 8.x is only
available on the Plus/Pro/HDR/Shuttle models, while every networked HyperDeck,
including the Studio HD Mini, offers these two.
Status
- Pre-release (
0.1.0.dev1), extracted from a broadcast control application where it drives decks in production: clip push, cue-and-loop as a switcher background source, and a transport modal for operators. - Verified on a HyperDeck Studio HD Mini (firmware 8.1.1) through the full probe / clear / upload / cue-and-loop cycle. Other Studio HD models speak the same protocol but were not on the bench.
Install
From PyPI:
pip install hyperdeckwire
Only pre-release versions exist so far (0.1.0.dev1). pip installs a pre-release when it is the only release there is, so no --pre is needed; pin the version in a requirements file (hyperdeckwire==0.1.0.dev1) so a later release cannot change your install under you. To install straight from a GitHub tag instead (git needed on the machine):
pip install "hyperdeckwire @ git+https://github.com/lucas-romanenko/bmdwire.git@hyperdeckwire-v0.1.0.dev1#subdirectory=hyperdeckwire"
Python 3.10 or newer. No other dependencies.
Features
- Blocking, single-socket
Hyperdeckclient with an explicit connect/close lifecycle and context-manager support. - Read commands:
device_info,remote_info,slot_info,transport_info,configuration,disk_list,clips_get,clips_count. - Write commands:
play(loop, single clip, speed, clip id),pause,stop,goto_clip,clips_add,clips_remove,clips_clear,slot_select,remote_enable,set_configuration,ping. - Typed
ClipandResponsedataclasses; protocol errors raiseHyperdeckErrorwith the deck's code and text. - Asynchronous 5xx notifications are filtered out of blocking requests and can be read explicitly.
upload_clipFTP helper with storage-volume auto-detection, anonymous-login fallback, progress callback and throughput reporting.- Pure standard library; a
socket_factoryhook andftplibmonkeypatching make the whole suite runnable without hardware.
Usage
from hyperdeckwire import Hyperdeck, HyperdeckError, upload_clip
# Push a clip onto the deck's active storage volume.
result = upload_clip('192.0.2.11', '/local/path/intro.mp4')
print(f'{result.name}: {result.throughput_mb_s:.1f} MB/s into slot {result.slot_dir}')
# Cue it and loop it.
with Hyperdeck('192.0.2.11') as hd:
print(hd.model, hd.protocol_version)
for clip in hd.disk_list():
print(clip.clip_id, clip.name, clip.duration)
hd.stop()
hd.clips_clear()
try:
hd.clips_add('intro.mp4')
except HyperdeckError as e:
raise SystemExit(f'deck refused the clip: {e}')
hd.play(loop=True, single_clip=True)
The full command reference, dataclass fields and error-code table are in docs/API.md.
Protocol notes
The Ethernet Protocol itself is documented by Blackmagic in
HyperDeckEthernetProtocol.pdf (December 2024 revision). The points below
are behaviour the library relies on that the document does not spell out, or
that was established on hardware.
- No REST API on the Studio HD Mini. Port 80 is closed on firmware 8.1.1, so the library never depends on HTTP.
- The greeting is a 5xx. On connect the deck sends
500 connection info:as a multi-line block. It shares the code range of asynchronous notifications but is synchronous and arrives once; the client reads it eagerly and cachesmodelandprotocol versionfrom it. - Multi-line framing. A response is multi-line if and only if its head line ends with a colon; the body is then read until a blank line. Async notifications can interleave with a pending response and are skipped inside
request()by default. - There is no pause verb.
pause()sendsplay: speed: 0, which freezes on the current frame.stopalso holds the last frame under the factorystop mode: lastframesetting; the transport reportsstoppedin both cases. 213 deck rebootingis a success. Afile formatchange may answer with 213 instead of200 okand drop the connection. The client treats both as success and leaves reconnecting to the caller.- FTP volume layout. Storage volumes are top-level directories. The Studio HD Mini names them by slot number (
/1/,/2/); other models name them by medium (sd1,ssd1,usb,nas).STORat the root is refused with550, soupload_cliplists the root, picks a volume (numeric first, then SD, SSD, USB, NAS) and changes into it.System Volume Informationand.Trashesare never selected. - FTP login. Stock firmware accepts an empty anonymous login; some servers reject the bare
USERform, so the helper retries asanonymousbefore failing. - The disk index updates live. A clip is visible to
disk listimmediately after itsSTORcompletes; no rescan or slot reselect is needed. - Clip names contain spaces.
disk listandclips getrows are tokenised from the right (duration, format fields) and everything left over is the name, which is why a name such asIntro Loop animation.mp4round-trips. - Client limit. Beyond a small number of simultaneous 9993 clients the deck answers
120 connection failedand closes the socket. - Verified hardware. HyperDeck Studio HD Mini, firmware 8.1.1, full probe / clear / upload / cue-and-loop cycle. Other Studio HD models speak the same protocol but were not on the bench.
Development
git clone https://github.com/lucas-romanenko/bmdwire.git
cd bmdwire/hyperdeckwire
pip install -e ".[test]"
python -m pytest
The suite needs no hardware. CI runs it on Python 3.10, 3.12 and 3.14 for every push and pull request.
Related libraries
One library per Blackmagic device family, same shape, same author, all pure standard library except atemwire's small C extension:
- atemwire: ATEM switchers (UDP protocol, macros, profiles)
- ultimattewire: Ultimatte keyers (archive and restore)
- videohubwire: Videohub routers (routing, labels)
License
MIT. See LICENSE.
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 hyperdeckwire-0.1.0.dev1.tar.gz.
File metadata
- Download URL: hyperdeckwire-0.1.0.dev1.tar.gz
- Upload date:
- Size: 17.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e9ae2501d1f767f35650a225330a177c30fed7b143a76c8cb0f534f05c93131
|
|
| MD5 |
9dac4c279bd20fe0fce86ddfdbc97ae4
|
|
| BLAKE2b-256 |
cb1e5d7ed173c5c069b40313a904800f4df35565e0b584697465dfaef5cb91b2
|
Provenance
The following attestation bundles were made for hyperdeckwire-0.1.0.dev1.tar.gz:
Publisher:
publish.yml on lucas-romanenko/bmdwire
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hyperdeckwire-0.1.0.dev1.tar.gz -
Subject digest:
4e9ae2501d1f767f35650a225330a177c30fed7b143a76c8cb0f534f05c93131 - Sigstore transparency entry: 2800691744
- Sigstore integration time:
-
Permalink:
lucas-romanenko/bmdwire@122c9880b645676978bcfaef95bb430f609071c3 -
Branch / Tag:
refs/tags/hyperdeckwire-v0.1.0.dev1 - Owner: https://github.com/lucas-romanenko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@122c9880b645676978bcfaef95bb430f609071c3 -
Trigger Event:
release
-
Statement type:
File details
Details for the file hyperdeckwire-0.1.0.dev1-py3-none-any.whl.
File metadata
- Download URL: hyperdeckwire-0.1.0.dev1-py3-none-any.whl
- Upload date:
- Size: 15.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b6a9947ed3800b87221d361a12e48b94cf93ce9498a4c1a729b1cc6449adc52
|
|
| MD5 |
bb7101dd75478d9f1ccf881995ca482b
|
|
| BLAKE2b-256 |
7599b0e485b6ebe3d7aa16b82ff4077ff7c85d6a1b793dae06dc64c4c5f4b27d
|
Provenance
The following attestation bundles were made for hyperdeckwire-0.1.0.dev1-py3-none-any.whl:
Publisher:
publish.yml on lucas-romanenko/bmdwire
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hyperdeckwire-0.1.0.dev1-py3-none-any.whl -
Subject digest:
1b6a9947ed3800b87221d361a12e48b94cf93ce9498a4c1a729b1cc6449adc52 - Sigstore transparency entry: 2800691790
- Sigstore integration time:
-
Permalink:
lucas-romanenko/bmdwire@122c9880b645676978bcfaef95bb430f609071c3 -
Branch / Tag:
refs/tags/hyperdeckwire-v0.1.0.dev1 - Owner: https://github.com/lucas-romanenko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@122c9880b645676978bcfaef95bb430f609071c3 -
Trigger Event:
release
-
Statement type: