Ready-to-use SRT / WebRTC / RTSP / RTMP / LL-HLS media server and media proxy that allows to read, publish, proxy, record and playback video and audio streams.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

100 lines
2.0 KiB

package srt
import (
"fmt"
"strings"
)
type streamIDMode int
const (
streamIDModeRead streamIDMode = iota
streamIDModePublish
)
type streamID struct {
mode streamIDMode
path string
query string
user string
pass string
}
func (s *streamID) unmarshal(raw string) error {
// standard syntax
// https://github.com/Haivision/srt/blob/master/docs/features/access-control.md
if strings.HasPrefix(raw, "#!::") {
for _, kv := range strings.Split(raw[len("#!::"):], ",") {
kv2 := strings.SplitN(kv, "=", 2)
if len(kv2) != 2 {
return fmt.Errorf("invalid value")
}
key, value := kv2[0], kv2[1]
switch key {
case "u":
s.user = value
case "r":
s.path = value
case "h":
case "s":
s.pass = value
case "t":
case "m":
switch value {
case "request":
s.mode = streamIDModeRead
case "publish":
s.mode = streamIDModePublish
default:
return fmt.Errorf("unsupported mode '%s'", value)
}
default:
return fmt.Errorf("unsupported key '%s'", key)
}
}
} else {
parts := strings.Split(raw, ":")
if len(parts) < 2 || len(parts) > 5 {
return fmt.Errorf("stream ID must be 'action:pathname[:query]' or 'action:pathname:user:pass[:query]', " +
"where action is either read or publish, pathname is the path name, user and pass are the credentials, " +
"query is an optional token containing additional information")
}
switch parts[0] {
case "read":
s.mode = streamIDModeRead
case "publish":
s.mode = streamIDModePublish
default:
return fmt.Errorf("stream ID must be 'action:pathname[:query]' or 'action:pathname:user:pass[:query]', " +
"where action is either read or publish, pathname is the path name, user and pass are the credentials, " +
"query is an optional token containing additional information")
}
s.path = parts[1]
if len(parts) == 4 || len(parts) == 5 {
s.user, s.pass = parts[2], parts[3]
}
if len(parts) == 3 {
s.query = parts[2]
} else if len(parts) == 5 {
s.query = parts[4]
}
}
return nil
}