/* 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" ) // parseURL parses an RTMP URL (ok, technically it is lexing). func 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 }