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 {