watermarks

package
v0.0.62 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 4, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package watermarks manages the on-disk library of uploadable watermark images (logos, channel bugs). Each asset is stored as two files in a flat directory:

<dir>/<id>.<ext>      ← image bytes
<dir>/<id>.json       ← domain.WatermarkAsset metadata sidecar

The sidecar layout means we don't need a separate database for asset metadata — `os.ReadDir` rebuilds the registry after every restart and the cache stays consistent without coordination with the storage layer.

Resolution flow at transcode time:

Stream.Watermark.AssetID
     │
     ▼  watermarks.Service.ResolvePath
  /<dir>/<id>.png
     │
     ▼  coordinator copies into TranscoderConfig.Watermark.ImagePath
  ffmpeg -i ... -vf "...,movie=<absolute path>,..."

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNotFound is returned by Get / Delete when the asset is unknown.
	ErrNotFound = errors.New("watermarks: asset not found")
	// ErrInvalidContent is returned when the uploaded bytes don't sniff
	// as an image MIME type the FFmpeg overlay path supports.
	ErrInvalidContent = errors.New("watermarks: not an image")
	// ErrTooLarge is returned by the handler when the upload exceeds
	// MaxWatermarkAssetBytes — defined here so the handler can wrap it.
	ErrTooLarge = errors.New("watermarks: upload too large")
)

Errors returned by the service. Mapped to HTTP status codes by the REST handler — see internal/api/handler/watermark.go.

Functions

This section is empty.

Types

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service is the public facade. Constructed via DI from config.WatermarksConfig. Safe for concurrent use; an internal RWMutex protects the metadata map.

func New

func New(i do.Injector) (*Service, error)

New is the samber/do constructor. Creates the assets directory if missing and seeds the in-memory cache from any sidecars already on disk so a restart picks up where the previous instance left off.

func (*Service) Delete

func (s *Service) Delete(id domain.WatermarkAssetID) error

Delete removes both the image and metadata sidecar. Idempotent on the "already gone" case so repeat calls return ErrNotFound exactly once and no-op afterwards. Caller is responsible for ensuring the asset isn't referenced by an active stream — there is no foreign-key check here.

func (*Service) Dir

func (s *Service) Dir() string

Dir returns the on-disk root of the assets library. Exposed so the configuration UI can show operators where uploads land.

func (*Service) Get

Get returns the metadata for a single asset.

func (*Service) List

func (s *Service) List() []*domain.WatermarkAsset

List returns a snapshot of every known asset, sorted by upload time (newest first) so dashboards default to "what did I just upload".

func (*Service) ResolvePath

func (s *Service) ResolvePath(id domain.WatermarkAssetID) (string, error)

ResolvePath returns the absolute filesystem path to the image bytes for the given asset id. Used by the coordinator to translate Stream.Watermark.AssetID into TranscoderConfig.Watermark.ImagePath before the transcoder consumes the config.

func (*Service) Save

func (s *Service) Save(displayName, originalFilename string, body io.Reader) (*domain.WatermarkAsset, error)

Save uploads new image bytes under the given display name. ContentType is sniffed via http.DetectContentType from the first 512 bytes; the returned asset's FileName preserves the operator's original filename for download responses.

Atomic on success: temp file written then renamed; sidecar metadata written last so a half-uploaded asset is invisible to subsequent calls.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL