From 0b5d1c0c64fac06adc6b8a790f18cb5399848a4a Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Mon, 10 Aug 2026 20:03:58 -0700 Subject: [PATCH] format: restore the hls-ts sniff and assert adapter capabilities Sniff identifies TS assets for the coming policy-driven alignment even though nothing reaches it through repack today. Compile-time assertions now state each adapter's capabilities explicitly. --- weed/format/hlsts/hlsts.go | 15 +++++++++++++++ weed/format/hlsts/hlsts_test.go | 12 ++++++++++++ weed/format/parquet/parquet.go | 5 +++++ 3 files changed, 32 insertions(+) diff --git a/weed/format/hlsts/hlsts.go b/weed/format/hlsts/hlsts.go index b29eb7b5a..5dac4fcab 100644 --- a/weed/format/hlsts/hlsts.go +++ b/weed/format/hlsts/hlsts.go @@ -23,6 +23,8 @@ const ( // interior chunk cuts land on packet boundaries. TSPacketSize = 188 + tsSyncByte = 0x47 + PlaylistContentType = "application/vnd.apple.mpegurl" MediaContentType = "video/MP2T" ) @@ -33,8 +35,21 @@ func init() { type Adapter struct{} +var ( + _ format.Sniffer = Adapter{} + _ format.SidecarIndexer = Adapter{} + _ format.Viewer = Adapter{} +) + func (Adapter) Name() string { return FormatName } +func (Adapter) Sniff(h format.Hint) bool { + if len(h.Head) > TSPacketSize { + return h.Head[0] == tsSyncByte && h.Head[TSPacketSize] == tsSyncByte + } + return len(h.Head) > 0 && h.Head[0] == tsSyncByte +} + // playlistInfo is the adapter payload: what the generated playback playlist // needs beyond the extent sizes. type playlistInfo struct { diff --git a/weed/format/hlsts/hlsts_test.go b/weed/format/hlsts/hlsts_test.go index 4d7260a72..af3c09e58 100644 --- a/weed/format/hlsts/hlsts_test.go +++ b/weed/format/hlsts/hlsts_test.go @@ -168,6 +168,18 @@ func TestViewSegmentHonorsMediaSequence(t *testing.T) { } } +func TestSniff(t *testing.T) { + head := make([]byte, 400) + head[0], head[TSPacketSize] = tsSyncByte, tsSyncByte + if !(Adapter{}).Sniff(format.Hint{Head: head}) { + t.Fatalf("Sniff() rejected TS head") + } + head[TSPacketSize] = 0 + if (Adapter{}).Sniff(format.Hint{Head: head}) { + t.Fatalf("Sniff() accepted non-TS head") + } +} + // The ingest bound admits mediaSequence = MaxInt64-(count-1); the payload // decoder must accept the same boundary or every view of such an asset fails. func TestMediaSequenceBoundaryRoundTrip(t *testing.T) { diff --git a/weed/format/parquet/parquet.go b/weed/format/parquet/parquet.go index 7c76bd88e..d65e110bd 100644 --- a/weed/format/parquet/parquet.go +++ b/weed/format/parquet/parquet.go @@ -25,6 +25,11 @@ func init() { type Adapter struct{} +var ( + _ format.Sniffer = Adapter{} + _ format.Indexer = Adapter{} +) + func (Adapter) Name() string { return FormatName } func (Adapter) Sniff(h format.Hint) bool {