Go-based FM stereo transmitter with RDS, Windows-first and cross-platform
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

137 строки
3.8KB

  1. package icecast
  2. import (
  3. "bytes"
  4. "context"
  5. "errors"
  6. "io"
  7. "testing"
  8. "github.com/jan/fm-rds-tx/internal/ingest"
  9. "github.com/jan/fm-rds-tx/internal/ingest/decoder"
  10. )
  11. type testDecoder struct {
  12. name string
  13. err error
  14. called int
  15. }
  16. func (d *testDecoder) Name() string { return d.name }
  17. func (d *testDecoder) DecodeStream(_ context.Context, _ io.Reader, _ decoder.StreamMeta, _ func(ingest.PCMChunk) error) error {
  18. d.called++
  19. return d.err
  20. }
  21. func TestDecodeWithPreferenceAutoFallsBackFromNativeUnsupported(t *testing.T) {
  22. native := &testDecoder{name: "native", err: decoder.ErrUnsupported}
  23. fallback := &testDecoder{name: "ffmpeg"}
  24. reg := decoder.NewRegistry()
  25. reg.Register("mp3", func() decoder.Decoder { return native })
  26. reg.Register("ffmpeg", func() decoder.Decoder { return fallback })
  27. src := New("ice-test", "http://example", nil, ReconnectConfig{},
  28. WithDecoderRegistry(reg),
  29. WithDecoderPreference("auto"),
  30. )
  31. err := src.decodeWithPreference(context.Background(), bytes.NewReader(nil), decoder.StreamMeta{
  32. ContentType: "audio/mpeg",
  33. SourceID: "ice-test",
  34. })
  35. if err != nil {
  36. t.Fatalf("decode: %v", err)
  37. }
  38. if native.called != 1 {
  39. t.Fatalf("native called %d times", native.called)
  40. }
  41. if fallback.called != 1 {
  42. t.Fatalf("fallback called %d times", fallback.called)
  43. }
  44. }
  45. func TestDecodeWithPreferenceNativeDoesNotFallback(t *testing.T) {
  46. nativeErr := errors.New("decode failed")
  47. native := &testDecoder{name: "native", err: nativeErr}
  48. fallback := &testDecoder{name: "ffmpeg"}
  49. reg := decoder.NewRegistry()
  50. reg.Register("mp3", func() decoder.Decoder { return native })
  51. reg.Register("ffmpeg", func() decoder.Decoder { return fallback })
  52. src := New("ice-test", "http://example", nil, ReconnectConfig{},
  53. WithDecoderRegistry(reg),
  54. WithDecoderPreference("native"),
  55. )
  56. err := src.decodeWithPreference(context.Background(), bytes.NewReader(nil), decoder.StreamMeta{
  57. ContentType: "audio/mpeg",
  58. SourceID: "ice-test",
  59. })
  60. if !errors.Is(err, nativeErr) {
  61. t.Fatalf("expected native error, got %v", err)
  62. }
  63. if fallback.called != 0 {
  64. t.Fatalf("fallback should not be called, got %d", fallback.called)
  65. }
  66. }
  67. func TestDecodeWithPreferenceFFmpegOnly(t *testing.T) {
  68. native := &testDecoder{name: "native"}
  69. fallback := &testDecoder{name: "ffmpeg"}
  70. reg := decoder.NewRegistry()
  71. reg.Register("mp3", func() decoder.Decoder { return native })
  72. reg.Register("ffmpeg", func() decoder.Decoder { return fallback })
  73. src := New("ice-test", "http://example", nil, ReconnectConfig{},
  74. WithDecoderRegistry(reg),
  75. WithDecoderPreference("ffmpeg"),
  76. )
  77. err := src.decodeWithPreference(context.Background(), bytes.NewReader(nil), decoder.StreamMeta{
  78. ContentType: "audio/mpeg",
  79. SourceID: "ice-test",
  80. })
  81. if err != nil {
  82. t.Fatalf("decode: %v", err)
  83. }
  84. if native.called != 0 {
  85. t.Fatalf("native should not be called in ffmpeg mode, got %d", native.called)
  86. }
  87. if fallback.called != 1 {
  88. t.Fatalf("fallback called %d times", fallback.called)
  89. }
  90. }
  91. func TestDecodeWithPreferenceAutoUnsupportedContentTypeFallsBack(t *testing.T) {
  92. fallback := &testDecoder{name: "ffmpeg"}
  93. reg := decoder.NewRegistry()
  94. reg.Register("ffmpeg", func() decoder.Decoder { return fallback })
  95. src := New("ice-test", "http://example", nil, ReconnectConfig{},
  96. WithDecoderRegistry(reg),
  97. WithDecoderPreference("auto"),
  98. )
  99. err := src.decodeWithPreference(context.Background(), bytes.NewReader(nil), decoder.StreamMeta{
  100. ContentType: "application/octet-stream",
  101. SourceID: "ice-test",
  102. })
  103. if err != nil {
  104. t.Fatalf("decode: %v", err)
  105. }
  106. if fallback.called != 1 {
  107. t.Fatalf("fallback called %d times", fallback.called)
  108. }
  109. }
  110. func TestWithDecoderPreferenceFallbackAliasNormalizesToFFmpeg(t *testing.T) {
  111. src := New("ice-test", "http://example", nil, ReconnectConfig{}, WithDecoderPreference("fallback"))
  112. if got := src.Descriptor().Codec; got != "ffmpeg" {
  113. t.Fatalf("codec=%s want ffmpeg", got)
  114. }
  115. }