Go-based FM stereo transmitter with RDS, Windows-first and cross-platform
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

67 Zeilen
1.5KB

  1. package decoder
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "strings"
  7. "github.com/jan/fm-rds-tx/internal/ingest"
  8. )
  9. var ErrUnsupported = fmt.Errorf("decoder unsupported")
  10. type StreamMeta struct {
  11. ContentType string
  12. SampleRateHz int
  13. Channels int
  14. SourceID string
  15. }
  16. type Decoder interface {
  17. Name() string
  18. DecodeStream(ctx context.Context, r io.Reader, meta StreamMeta, emit func(ingest.PCMChunk) error) error
  19. }
  20. type Builder func() Decoder
  21. type Registry struct {
  22. byName map[string]Builder
  23. }
  24. func NewRegistry() *Registry {
  25. return &Registry{byName: map[string]Builder{}}
  26. }
  27. func (r *Registry) Register(name string, builder Builder) {
  28. if r == nil || builder == nil {
  29. return
  30. }
  31. r.byName[strings.ToLower(strings.TrimSpace(name))] = builder
  32. }
  33. func (r *Registry) Create(name string) (Decoder, error) {
  34. if r == nil {
  35. return nil, fmt.Errorf("%w: registry nil", ErrUnsupported)
  36. }
  37. builder, ok := r.byName[strings.ToLower(strings.TrimSpace(name))]
  38. if !ok {
  39. return nil, fmt.Errorf("%w: %s", ErrUnsupported, name)
  40. }
  41. return builder(), nil
  42. }
  43. func (r *Registry) SelectByContentType(contentType string) (Decoder, error) {
  44. ct := strings.ToLower(strings.TrimSpace(contentType))
  45. switch {
  46. case strings.Contains(ct, "mpeg"), strings.Contains(ct, "mp3"):
  47. return r.Create("mp3")
  48. case strings.Contains(ct, "ogg"), strings.Contains(ct, "vorbis"):
  49. return r.Create("oggvorbis")
  50. case strings.Contains(ct, "aac"), strings.Contains(ct, "adts"):
  51. return r.Create("aac")
  52. default:
  53. return nil, fmt.Errorf("%w: content-type=%s", ErrUnsupported, contentType)
  54. }
  55. }