Testers wanted: ZapperBox tuners as an HDHomeRun source for Channels DVR

Thanks, that confirms it: registration now goes out, but the bridge then starts with different IDs than the ones it registered, so the M1 still refuses it. That's the bug I'm fixing now, and a new image is coming shortly. No need to change anything else in the meantime.

1 Like

thanks.

Found it. Your registration run and your running bridge are reading two different /data volumes, so each uses a different saved seed and makes different tuner IDs. Easiest fix, no upgrade needed:

  1. Copy the three "dev 02bb00…" IDs from the running bridge's startup log into the [[m1]] block: devs = ["02bb00a0735a", "02bb003c6c0a", "02bb00c7fbb9"]
  2. Run docker compose run --rm zapperbridge discover --listen 60 --apply again. It should now announce those same three IDs.
  3. Restart the bridge and check /health.

I also pushed v0.1.1, which you can pull to get these fixes. Its /health now shows the M1's exact answer (err_name and hint) if it still refuses, so please post that "api8" section if it isn't working.

no dice see logs below:

WARN  ui.mode = "readonly" without ZUI_TOKEN: the UI is open to every private-LAN address that can reach :80 (set env ZUI_TOKEN to require a token; never expose it to the internet)
WARN  network.advertise_ip unset: the facade will pick the route-selected primary LAN IP
device id seed: persisted seed file /data/seed (fingerprint fba082ea)
network mode: host | advertised TunerCount total: 4
M1 living-room  addr=192.168.1.54  hdhr=02BB0012  tuners=4  http=80 ts=5004
   dev 02bb00a0735a -> push 192.168.1.81:31061
   dev 02bb003c6c0a -> push 192.168.1.82:31061
   dev 02bb00c7fbb9 -> push 192.168.1.83:31061
   + 1 fixed HLS tuner (not retunable)
host mode: add each push IP as an alias on the host NIC (not done for you):
   sudo ip addr add 192.168.1.81/32 dev eth0   # arping -D -I eth0 -c 2 192.168.1.81 first
   sudo ip addr add 192.168.1.82/32 dev eth0   # arping -D -I eth0 -c 2 192.168.1.82 first
   sudo ip addr add 192.168.1.83/32 dev eth0   # arping -D -I eth0 -c 2 192.168.1.83 first
info: push ip 192.168.1.81: already assigned to this host
info: push ip 192.168.1.82: already assigned to this host
info: push ip 192.168.1.83: already assigned to this host
starting facade for living-room
push-ip: seed 02bb003c6c0a -> 192.168.1.82 (ZPUSH_IPS)
push-ip: seed 02bb00a0735a -> 192.168.1.81 (ZPUSH_IPS)
push-ip: seed 02bb00c7fbb9 -> 192.168.1.83 (ZPUSH_IPS)
full-stream diagnostics: ts_analysis=on gap_ms=100 capture_seconds=0
ssdp on :1900 group 239.255.255.250 if 192.168.1.29 location http://192.168.1.29/device.xml udn uuid:d5842096-00cb-5f2c-a3ae-35e8b7375c81
HDHR emulator: JSON on :80  TS-redirect on :5004
lineup: M1 192.168.1.54 dev 02bb00a0735a refused or failed: api8 FAIL on a0 2/3/4/5: a0=2 NOT_FOUND, a0=3 NOT_FOUND, a0=4 NOT_FOUND, a0=5 NOT_FOUND; api6 handshake: NOT_FOUND -> the M1 does not know device id 02bb00a0735a yet: register the bridge's ids with `discover --apply` (docs/DOCKER.md)
epg refresh fail: RuntimeError('lineup unavailable: api8 failed and no cache') (serving last-good=False)
lineup: M1 unreachable or lineup fetch failed; no cache, serving []
epg watch err: RuntimeError('lineup unavailable: api8 failed and no cache')
signal 15: shutting down
ssdp byebye sent
WARN  ui.mode = "readonly" without ZUI_TOKEN: the UI is open to every private-LAN address that can reach :80 (set env ZUI_TOKEN to require a token; never expose it to the internet)
WARN  network.advertise_ip unset: the facade will pick the route-selected primary LAN IP
device id seed: persisted seed file /data/seed (fingerprint fba082ea)
network mode: host | advertised TunerCount total: 4
M1 living-room  addr=192.168.1.54  hdhr=02BB0012  tuners=4  http=80 ts=5004
   dev 02bb00a0735a -> push 192.168.1.81:31061
   dev 02bb003c6c0a -> push 192.168.1.82:31061
   dev 02bb00c7fbb9 -> push 192.168.1.83:31061
   + 1 fixed HLS tuner (not retunable)
host mode: add each push IP as an alias on the host NIC (not done for you):
   sudo ip addr add 192.168.1.81/32 dev eth0   # arping -D -I eth0 -c 2 192.168.1.81 first
   sudo ip addr add 192.168.1.82/32 dev eth0   # arping -D -I eth0 -c 2 192.168.1.82 first
   sudo ip addr add 192.168.1.83/32 dev eth0   # arping -D -I eth0 -c 2 192.168.1.83 first
info: push ip 192.168.1.81: already assigned to this host
info: push ip 192.168.1.82: already assigned to this host
info: push ip 192.168.1.83: already assigned to this host
starting facade for living-room
push-ip: seed 02bb003c6c0a -> 192.168.1.82 (ZPUSH_IPS)
push-ip: seed 02bb00a0735a -> 192.168.1.81 (ZPUSH_IPS)
push-ip: seed 02bb00c7fbb9 -> 192.168.1.83 (ZPUSH_IPS)
full-stream diagnostics: ts_analysis=on gap_ms=100 capture_seconds=0
ssdp on :1900 group 239.255.255.250 if 192.168.1.29 location http://192.168.1.29/device.xml udn uuid:d5842096-00cb-5f2c-a3ae-35e8b7375c81
HDHR emulator: JSON on :80  TS-redirect on :5004
lineup: M1 192.168.1.54 dev 02bb00a0735a refused or failed: api8 FAIL on a0 2/3/4/5: a0=2 NOT_FOUND, a0=3 NOT_FOUND, a0=4 NOT_FOUND, a0=5 NOT_FOUND; api6 handshake: NOT_FOUND -> the M1 does not know device id 02bb00a0735a yet: register the bridge's ids with `discover --apply` (docs/DOCKER.md)
lineup: M1 unreachable or lineup fetch failed; no cache, serving []

edit: tried discover no dice.

Thanks, this is progress. The new log shows the M1's actual answer: NOT_FOUND, meaning it hasn't registered 02bb00a0735a yet. Can you run the registration once more and post its full output?

  1. With the bridge running on v0.1.1: docker exec zapperbridge python3 /app/docker/entrypoint.py discover --listen 30 --apply (this uses the bridge's own /data, so the IDs are guaranteed to match).
  2. Check that it prints "announced 02bb00a0735a from 192.168.1.81" (and the other two).
  3. Wait about 10 seconds, restart the bridge, and post the new "lineup:" line from the log.

much better but still bugs. ATSC 1.0 plays fine atsc 3.0 wont play. logs below:

M1 never answers when the bridge tunes 2.1 or 4.1. Those are real ATSC 3.0 channel IDs, so the M1 likely serves 3.0 a different way than 1.0, through its built-in web stream. I don't get 3.0 here, so could you help me test?

  1. On the M1 itself, tune 2.1 (3.0), then from the bridge host run curl -s http://192.168.1.54:8076/atsc3/1/master.m3u8 and paste the output.
  2. With the M1 still on 2.1, try 4.1 in Channels once more and post the new log.

That'll show me the 3.0 stream format so I can add a proper 3.0 path.

are you sure you got the command right, i get no output.

I added -o output.txt to the command this is what I got:

That's exactly what I needed, thanks! Your M1 is serving real ATSC 3.0 (HEVC video, AC-4 audio, captions). Sorry the empty output was confusing; it only shows when saved to a file like you did. Three more quick ones:

  1. With the M1 still on 2.1, run curl -s http://192.168.1.54:8076/atsc3/1/video.m3u8 -o video.txt and curl -s http://192.168.1.54:8076/atsc3/1/audio1.m3u8 -o audio.txt and post both.
  2. Put the M1 on a 1.0 channel, start 4.1 in Channels, and while it's trying run curl -s http://192.168.1.54:8076/atsc3/N/master.m3u8 -o slotN.txt for N = 2, 3, 4 and 5. Post whatever comes back, even if empty.
  3. Post the bridge log from that attempt.

That tells me whether the bridge can pick 3.0 channels itself or only follow what the M1 is on.

see below:

keep in mind a family member was watching fox 5 this morning and I don't know if he was on the zbox or hdhr but I told him to stop before starting this experment.

Test build is up: sunnyside1/zapperbridge:atsc3-test. In your compose file change the image to that tag, then docker compose pull && docker compose up -d. Please test with nothing else playing on the M1 tuners.

Test A (bridge tunes 3.0 itself): start 4.1 or 2.1 in Channels and wait about 30 seconds (3.0 tunes now get 25s instead of 8s). Post the log. Lines starting with atsc3 tune show exactly what the M1 answered.

Test B (3.0 on the M1-TUNER4 channel): add HDHR_HLS_PROTO=3 to the environment, put the M1 itself on 2.1 (3.0), restart the container, then play 999.1 "M1-TUNER4" in Channels. Tell me if you get video, sound, both, or neither, and post the log (look for lines starting with hls3). If you get video but no sound, add ZB_AC4_SYNC=0, restart and try once more.

Captions aren't carried yet. Audio is AC-4, so whether it plays may depend on your Channels client.

1 Like

I am not home now, testing on a firetv connected to lan by vpn in pfsense. no dice for ether but I noticed the following in channels logs:

Closing connection 02BB0012 ch4.1 after no data was received for 6s

docker logs below:

WARN ui.mode = "readonly" without ZUI_TOKEN: the UI is open to every private-LAN address that can reach :80 (set env ZUI_TOKEN to require a token; never expose it to the internet)
WARN network.advertise_ip unset: the facade will pick the route-selected primary LAN IP
device id seed: persisted seed file /data/seed (fingerprint fba082ea)
network mode: host | advertised TunerCount total: 4
M1 living-room addr=192.168.1.54 hdhr=02BB0012 tuners=4 http=80 ts=5004
dev 02bb00a0735a -> push 192.168.1.81:31061
dev 02bb003c6c0a -> push 192.168.1.82:31061
dev 02bb00c7fbb9 -> push 192.168.1.83:31061

  • 1 fixed HLS tuner (not retunable)
    host mode: add each push IP as an alias on the host NIC (not done for you):
    sudo ip addr add 192.168.1.81/32 dev eth0 # arping -D -I eth0 -c 2 192.168.1.81 first
    sudo ip addr add 192.168.1.82/32 dev eth0 # arping -D -I eth0 -c 2 192.168.1.82 first
    sudo ip addr add 192.168.1.83/32 dev eth0 # arping -D -I eth0 -c 2 192.168.1.83 first
    info: push ip 192.168.1.81: already assigned to this host
    info: push ip 192.168.1.82: already assigned to this host
    info: push ip 192.168.1.83: already assigned to this host
    starting facade for living-room
    push-ip: seed 02bb003c6c0a -> 192.168.1.82 (ZPUSH_IPS)
    push-ip: seed 02bb00a0735a -> 192.168.1.81 (ZPUSH_IPS)
    push-ip: seed 02bb00c7fbb9 -> 192.168.1.83 (ZPUSH_IPS)
    full-stream diagnostics: ts_analysis=on gap_ms=100 capture_seconds=0
    ssdp on :1900 group 239.255.255.250 if 192.168.1.29 location http://192.168.1.29/device.xml udn uuid:d5842096-00cb-5f2c-a3ae-35e8b7375c81
    HDHR emulator: JSON on :80 TS-redirect on :5004
    signal 15: shutting down
    ssdp byebye sent
    WARN ui.mode = "readonly" without ZUI_TOKEN: the UI is open to every private-LAN address that can reach :80 (set env ZUI_TOKEN to require a token; never expose it to the internet)
    WARN network.advertise_ip unset: the facade will pick the route-selected primary LAN IP
    device id seed: persisted seed file /data/seed (fingerprint fba082ea)
    network mode: host | advertised TunerCount total: 4
    M1 living-room addr=192.168.1.54 hdhr=02BB0012 tuners=4 http=80 ts=5004
    dev 02bb00a0735a -> push 192.168.1.81:31061
    dev 02bb003c6c0a -> push 192.168.1.82:31061
    dev 02bb00c7fbb9 -> push 192.168.1.83:31061
  • 1 fixed HLS tuner (not retunable)
    host mode: add each push IP as an alias on the host NIC (not done for you):
    sudo ip addr add 192.168.1.81/32 dev eth0 # arping -D -I eth0 -c 2 192.168.1.81 first
    sudo ip addr add 192.168.1.82/32 dev eth0 # arping -D -I eth0 -c 2 192.168.1.82 first
    sudo ip addr add 192.168.1.83/32 dev eth0 # arping -D -I eth0 -c 2 192.168.1.83 first
    info: push ip 192.168.1.81: already assigned to this host
    info: push ip 192.168.1.82: already assigned to this host
    info: push ip 192.168.1.83: already assigned to this host
    starting facade for living-room
    push-ip: seed 02bb003c6c0a -> 192.168.1.82 (ZPUSH_IPS)
    push-ip: seed 02bb00a0735a -> 192.168.1.81 (ZPUSH_IPS)
    push-ip: seed 02bb00c7fbb9 -> 192.168.1.83 (ZPUSH_IPS)
    full-stream diagnostics: ts_analysis=on gap_ms=100 capture_seconds=0
    ssdp on :1900 group 239.255.255.250 if 192.168.1.29 location http://192.168.1.29/device.xml udn uuid:d5842096-00cb-5f2c-a3ae-35e8b7375c81
    HDHR emulator: JSON on :80 TS-redirect on :5004
    hls3: http://192.168.1.54:8076/atsc3/1/ serves fMP4 (ATSC 3.0) codecs=hvc1.2.4.L123.B0,ac-4.02.01.01,ac-4.02.01.00,stpp.ttml.im1t audio=audio1.m3u8(eng); remuxing HEVC/AC-4 into MPEG-TS unchanged
    hls3 video init xix_1737660161018item-01item_init.m4i tracks=[Track(1 video encv ts=240000)]
    hls3: video track codec 'encv' not carried
    hls3 audio init xix_1737660161018item-02item_init.m4i tracks=[Track(1 audio enca ts=240000)]
    hls3: audio track codec 'enca' not carried
    epg: lineup version unknown -> 3927703922 (restart reconcile), rebuilding
    epg refresh ok channels=125 programmes=50239 bytes=22395559

fyi atsc 1.0 plays on my remote firetv