av/rtmp/parseurl.go

104 lines
2.7 KiB
Go

/*
NAME
parseurl.go
DESCRIPTION
See Readme.md
AUTHOR
Dan Kortschak <dan@ausocean.org>
Saxon Nelson-Milton <saxon@ausocean.org>
LICENSE
parseurl.go is Copyright (C) 2017-2018 the Australian Ocean Lab (AusOcean)
It is free software: you can redistribute it and/or modify them
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with revid in gpl.txt. If not, see http://www.gnu.org/licenses.
Derived from librtmp under the GNU Lesser General Public License 2.1
Copyright (C) 2005-2008 Team XBMC http://www.xbmc.org
Copyright (C) 2008-2009 Andrej Stepanchuk
Copyright (C) 2009-2010 Howard Chu
*/
package rtmp
import (
"log"
"net/url"
"path"
"strconv"
"strings"
)
// int RTMP_ParseURL(const char *url, int *protocol, AVal *host, unsigned int *port, AVal *playpath, AVal *app);
// parseurl.c +33
func C_RTMP_ParseURL(addr string) (protocol int32, host string, port uint16, app, playpath string, err error) {
u, err := url.Parse(addr)
if err != nil {
log.Printf("failed to parse addr: %v", err)
return protocol, host, port, app, playpath, err
}
switch u.Scheme {
case "rtmp":
protocol = RTMP_PROTOCOL_RTMP
case "rtmpt":
protocol = RTMP_PROTOCOL_RTMPT
case "rtmps":
protocol = RTMP_PROTOCOL_RTMPS
case "rtmpe":
protocol = RTMP_PROTOCOL_RTMPE
case "rtmfp":
protocol = RTMP_PROTOCOL_RTMFP
case "rtmpte":
protocol = RTMP_PROTOCOL_RTMPTE
case "rtmpts":
protocol = RTMP_PROTOCOL_RTMPTS
default:
log.Printf("unknown scheme: %q", u.Scheme)
return protocol, host, port, app, playpath, errUnknownScheme
}
host = u.Host
if p := u.Port(); p != "" {
pi, err := strconv.Atoi(p)
if err != nil {
return protocol, host, port, app, playpath, err
}
port = uint16(pi)
}
if !path.IsAbs(u.Path) {
return protocol, host, port, app, playpath, nil
}
elems := strings.SplitN(u.Path[1:], "/", 3)
app = elems[0]
playpath = elems[1]
if len(elems) == 3 && len(elems[2]) != 0 {
playpath = path.Join(elems[1:]...)
switch ext := path.Ext(playpath); ext {
case ".f4v", ".mp4":
playpath = "mp4:" + playpath[:len(playpath)-len(ext)]
case ".mp3":
playpath = "mp3:" + playpath[:len(playpath)-len(ext)]
case ".flv":
playpath = playpath[:len(playpath)-len(ext)]
}
if u.RawQuery != "" {
playpath += "?" + u.RawQuery
}
}
return protocol, host, port, app, playpath, nil
}