Files
streamctl/pkg/streamserver/streams/handlers.go
2024-07-20 20:52:38 +01:00

103 lines
2.2 KiB
Go

package streams
import (
"context"
"errors"
"fmt"
"strings"
"github.com/AlexxIT/go2rtc/pkg/core"
"github.com/xaionaro-go/streamctl/pkg/streamserver/server"
)
type Handler func(source string) (core.Producer, error)
func (s *StreamHandler) HandleFunc(scheme string, handler Handler) {
s.handlers[scheme] = handler
}
func (s *StreamHandler) HasProducer(url string) bool {
if i := strings.IndexByte(url, ':'); i > 0 {
scheme := url[:i]
if _, ok := s.handlers[scheme]; ok {
return true
}
if _, ok := s.redirects[scheme]; ok {
return true
}
}
return false
}
type ErrNoProducer struct{}
func (err ErrNoProducer) Error() string {
return "no producers"
}
func (s *StreamHandler) GetProducer(url string) (core.Producer, error) {
i := strings.IndexByte(url, ':')
if i <= 0 {
return nil, fmt.Errorf("streams: empty scheme in URL: '%s'", url)
}
scheme := url[:i]
if redirect, ok := s.redirects[scheme]; ok {
location, err := redirect(url)
if err != nil {
return nil, err
}
if location != "" {
return s.GetProducer(location)
}
}
if handler, ok := s.handlers[scheme]; ok {
return handler(url)
}
return nil, errors.New("streams: unsupported scheme in URL: " + url)
}
// Redirect can return: location URL or error or empty URL and error
type Redirect func(url string) (string, error)
func (s *StreamHandler) RedirectFunc(scheme string, redirect Redirect) {
s.redirects[scheme] = redirect
}
func (s *StreamHandler) Location(url string) (string, error) {
if i := strings.IndexByte(url, ':'); i > 0 {
scheme := url[:i]
if redirect, ok := s.redirects[scheme]; ok {
return redirect(url)
}
}
return "", nil
}
// TODO: rework
type ConsumerHandler func(url string) (core.Consumer, server.NumBytesReaderWroter, func(context.Context) error, error)
func (s *StreamHandler) HandleConsumerFunc(scheme string, handler ConsumerHandler) {
s.consumerHandlers[scheme] = handler
}
func (s *StreamHandler) GetConsumer(url string) (core.Consumer, server.NumBytesReaderWroter, func(context.Context) error, error) {
if i := strings.IndexByte(url, ':'); i > 0 {
scheme := url[:i]
if handler, ok := s.consumerHandlers[scheme]; ok {
return handler(url)
}
}
return nil, nil, nil, errors.New("streams: unsupported scheme: " + url)
}