uplink/app/streams/metadata_injector.go

68 lines
1.3 KiB
Go

package streams
import (
"io"
)
type MetadataInjector struct {
io.Writer
offset int
MetadataInterval int
metadata Metadata
}
func NewMetadataInjector(w io.Writer, metadataInterval int) *MetadataInjector {
return &MetadataInjector{
Writer: w,
MetadataInterval: metadataInterval,
}
}
func (mi *MetadataInjector) SetMetadata(metadata Metadata) {
mi.metadata = metadata
}
func (mi *MetadataInjector) writeMetadata() (n int, err error) {
// the metadata generated here will be read on the next Read call
metadataBytes := mi.metadata.Bytes()
lenByte := (len(metadataBytes) + 15) / 16
metadataBuf := make([]byte, int(lenByte)*16+1)
metadataBuf[0] = byte(lenByte)
copy(metadataBuf[1:], metadataBytes)
if len(mi.metadata) > 0 {
mi.metadata = Metadata{}
}
return mi.Writer.Write(metadataBuf)
}
func (mi *MetadataInjector) Write(data []byte) (n int, err error) {
for n < len(data) {
toWrite := mi.MetadataInterval - mi.offset
if toWrite <= 0 {
_, cerr := mi.writeMetadata()
//n += cn
if cerr != nil {
err = cerr
return
}
mi.offset = 0
// toWrite = mi.MetadataInterval
continue
}
outBytes := make([]byte, toWrite)
copy(outBytes, data[mi.offset:mi.offset+toWrite])
cn, cerr := mi.Writer.Write(outBytes)
n += cn
mi.offset += cn
if cerr != nil {
err = cerr
return
}
}
return
}