mirror of
https://github.com/xaionaro-go/streamctl.git
synced 2025-10-20 14:16:42 +08:00
103 lines
2.2 KiB
Go
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)
|
|
}
|