Repository: bluenviron/gortsplib
Pull request #801 (2025-06-23 16:52:05)

client: add Start2; deprecate Start

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/bluenviron/gortsplib/pull/801?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron) Report
Attention: Patch coverage is `30.00000%` with `7 lines` in your changes missing coverage. Please review.
> Project coverage is 82.11%. Comparing base [(`d98036a`)](https://app.codecov.io/gh/bluenviron/gortsplib/commit/d98036a493bcc99fd982eb2798e7862a5cb468c9?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron) to head [(`7adc1ff`)](https://app.codecov.io/gh/bluenviron/gortsplib/commit/7adc1ff7e1b7733ec5a61f948d222336cf51fe6c?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron).
> Report is 4 commits behind head on main.

| [Files with missing lines](https://app.codecov.io/gh/bluenviron/gortsplib/pull/801?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron) | Patch % | Lines |
|---|---|---|
| [client.go](https://app.codecov.io/gh/bluenviron/gortsplib/pull/801?src=pr&el=tree&filepath=client.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron#diff-Y2xpZW50Lmdv) | 30.00% | [7 Missing :warning: ](https://app.codecov.io/gh/bluenviron/gortsplib/pull/801?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #801      +/-   ##
==========================================
- Coverage   82.16%   82.11%   -0.05%     
==========================================
  Files         117      117              
  Lines       12720    12727       +7     
==========================================
  Hits        10451    10451              
- Misses       1847     1854       +7     
  Partials      422      422              
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/bluenviron/gortsplib/pull/801?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
</details>

Patch:
diff --git a/client.go b/client.go
index 543c8501..7e620ba4 100644
--- a/client.go
+++ b/client.go
@@ -355,6 +355,14 @@ type OnPacketRTCPAnyFunc func(*description.Media, rtcp.Packet)
 
 // Client is a RTSP client.
 type Client struct {
+	//
+	// Target
+	//
+	// Scheme. Either "rtsp" or "rtsps".
+	Scheme string
+	// Host and port.
+	Host string
+
 	//
 	// RTSP parameters (all optional)
 	//
@@ -444,8 +452,6 @@ type Client struct {
 	receiverReportPeriod time.Duration
 	checkTimeoutPeriod   time.Duration
 
-	scheme               string
-	host                 string
 	ctx                  context.Context
 	ctxCancel            func()
 	state                clientState
@@ -497,7 +503,16 @@ type Client struct {
 }
 
 // Start initializes the connection to a server.
+//
+// Deprecated: replaced by Start2.
 func (c *Client) Start(scheme string, host string) error {
+	c.Scheme = scheme
+	c.Host = host
+	return c.Start2()
+}
+
+// Start2 initializes the connection to a server.
+func (c *Client) Start2() error {
 	// RTSP parameters
 	if c.ReadTimeout == 0 {
 		c.ReadTimeout = 10 * time.Second
@@ -592,8 +607,6 @@ func (c *Client) Start(scheme string, host string) error {
 
 	ctx, ctxCancel := context.WithCancel(context.Background())
 
-	c.scheme = scheme
-	c.host = host
 	c.ctx = ctx
 	c.ctxCancel = ctxCancel
 	c.checkTimeoutTimer = emptyTimer()
@@ -632,7 +645,10 @@ func (c *Client) StartRecording(address string, desc *description.Session) error
 		return err
 	}
 
-	err = c.Start(u.Scheme, u.Host)
+	c.Scheme = u.Scheme
+	c.Host = u.Host
+
+	err = c.Start2()
 	if err != nil {
 		return err
 	}
@@ -1062,29 +1078,29 @@ func (c *Client) connOpen() error {
 		return nil
 	}
 
-	if c.scheme != "rtsp" && c.scheme != "rtsps" {
-		return liberrors.ErrClientUnsupportedScheme{Scheme: c.scheme}
+	if c.Scheme != "rtsp" && c.Scheme != "rtsps" {
+		return liberrors.ErrClientUnsupportedScheme{Scheme: c.Scheme}
 	}
 
 	dialCtx, dialCtxCancel := context.WithTimeout(c.ctx, c.ReadTimeout)
 	defer dialCtxCancel()
 
 	nconn, err := c.DialContext(dialCtx, "tcp", canonicalAddr(&base.URL{
-		Scheme: c.scheme,
-		Host:   c.host,
+		Scheme: c.Scheme,
+		Host:   c.Host,
 	}))
 	if err != nil {
 		return err
 	}
 
-	if c.scheme == "rtsps" {
+	if c.Scheme == "rtsps" {
 		tlsConfig := c.TLSConfig
 		if tlsConfig == nil {
 			tlsConfig = &tls.Config{}
 		}
 		tlsConfig.ServerName = (&base.URL{
-			Scheme: c.scheme,
-			Host:   c.host,
+			Scheme: c.Scheme,
+			Host:   c.Host,
 		}).Hostname()
 
 		nconn = tls.Client(nconn, tlsConfig)
@@ -1352,7 +1368,7 @@ func (c *Client) doDescribe(u *base.URL) (*description.Session, *base.Response,
 				return nil, nil, err
 			}
 
-			if c.scheme == "rtsps" && ru.Scheme != "rtsps" {
+			if c.Scheme == "rtsps" && ru.Scheme != "rtsps" {
 				return nil, nil, fmt.Errorf("connection cannot be downgraded from RTSPS to RTSP")
 			}
 
@@ -1360,8 +1376,8 @@ func (c *Client) doDescribe(u *base.URL) (*description.Session, *base.Response,
 				ru.User = u.User
 			}
 
-			c.scheme = ru.Scheme
-			c.host = ru.Host
+			c.Scheme = ru.Scheme
+			c.Host = ru.Host
 
 			return c.doDescribe(ru)
 		}
@@ -1435,12 +1451,12 @@ func (c *Client) doAnnounce(u *base.URL, desc *description.Session) (*base.Respo
 		return nil, err
 	}
 
-	announceData, err := generateAnnounceData(desc, c.scheme == "rtsps")
+	announceData, err := generateAnnounceData(desc, c.Scheme == "rtsps")
 	if err != nil {
 		return nil, err
 	}
 
-	err = prepareForAnnounce(desc, announceData, c.scheme == "rtsps")
+	err = prepareForAnnounce(desc, announceData, c.Scheme == "rtsps")
 	if err != nil {
 		return nil, err
 	}
@@ -1535,13 +1551,13 @@ func (c *Client) doSetup(
 	// use transport from config, secure flag from server
 	case c.Transport != nil:
 		transport = *c.Transport
-		th.Secure = medi.Secure && c.scheme == "rtsps"
+		th.Secure = medi.Secure && c.Scheme == "rtsps"
 
 	// try UDP if unencrypted or secure is supported by server, otherwise try TCP
 	default:
-		th.Secure = medi.Secure && c.scheme == "rtsps"
+		th.Secure = medi.Secure && c.Scheme == "rtsps"
 
-		if th.Secure || c.scheme == "rtsp" {
+		if th.Secure || c.Scheme == "rtsp" {
 			transport = TransportUDP
 		} else {
 			transport = TransportTCP
@@ -1560,7 +1576,7 @@ func (c *Client) doSetup(
 
 	switch transport {
 	case TransportUDP, TransportUDPMulticast:
-		if c.scheme == "rtsps" && !medi.Secure {
+		if c.Scheme == "rtsps" && !medi.Secure {
 			cm.close()
 			return nil, fmt.Errorf("server does not support secure UDP")
 		}
diff --git a/examples/client-play-backchannel/main.go b/examples/client-play-backchannel/main.go
index f541b0d7..89356885 100644
--- a/examples/client-play-backchannel/main.go
+++ b/examples/client-play-backchannel/main.go
@@ -47,18 +47,20 @@ func findG711BackChannel(desc *description.Session) (*description.Media, *format
 }
 
 func main() {
-	c := gortsplib.Client{
-		RequestBackChannels: true,
-	}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme:              u.Scheme,
+		Host:                u.Host,
+		RequestBackChannels: true,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-av1-to-jpeg/main.go b/examples/client-play-format-av1-to-jpeg/main.go
index 2cf65e0d..b40f93c3 100644
--- a/examples/client-play-format-av1-to-jpeg/main.go
+++ b/examples/client-play-format-av1-to-jpeg/main.go
@@ -46,16 +46,19 @@ func saveToFile(img image.Image) error {
 }
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-av1/main.go b/examples/client-play-format-av1/main.go
index 7c27d66e..9305b980 100644
--- a/examples/client-play-format-av1/main.go
+++ b/examples/client-play-format-av1/main.go
@@ -23,16 +23,19 @@ import (
 // apt install -y libavcodec-dev libswscale-dev gcc pkg-config
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-g711/main.go b/examples/client-play-format-g711/main.go
index 10f51658..d2dbe62b 100644
--- a/examples/client-play-format-g711/main.go
+++ b/examples/client-play-format-g711/main.go
@@ -17,16 +17,19 @@ import (
 // 3. decode the G711 stream into audio samples.
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-h264-mpeg4audio-to-disk/main.go b/examples/client-play-format-h264-mpeg4audio-to-disk/main.go
index 86edf3c2..8c82c628 100644
--- a/examples/client-play-format-h264-mpeg4audio-to-disk/main.go
+++ b/examples/client-play-format-h264-mpeg4audio-to-disk/main.go
@@ -18,16 +18,19 @@ import (
 // 3. save the content of these streams in a file in MPEG-TS format.
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/stream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-h264-to-disk/main.go b/examples/client-play-format-h264-to-disk/main.go
index dcfa769c..d19ce8bf 100644
--- a/examples/client-play-format-h264-to-disk/main.go
+++ b/examples/client-play-format-h264-to-disk/main.go
@@ -18,16 +18,19 @@ import (
 // 3. save the content of the format in a file in MPEG-TS format.
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-h264-to-jpeg/main.go b/examples/client-play-format-h264-to-jpeg/main.go
index df24c5ef..855e4967 100644
--- a/examples/client-play-format-h264-to-jpeg/main.go
+++ b/examples/client-play-format-h264-to-jpeg/main.go
@@ -46,16 +46,19 @@ func saveToFile(img image.Image) error {
 }
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-h264/main.go b/examples/client-play-format-h264/main.go
index 2d84dc7a..142ba85a 100644
--- a/examples/client-play-format-h264/main.go
+++ b/examples/client-play-format-h264/main.go
@@ -23,16 +23,19 @@ import (
 // apt install -y libavcodec-dev libswscale-dev gcc pkg-config
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-h265-to-disk/main.go b/examples/client-play-format-h265-to-disk/main.go
index 01cbc97e..dae8f3b0 100644
--- a/examples/client-play-format-h265-to-disk/main.go
+++ b/examples/client-play-format-h265-to-disk/main.go
@@ -18,16 +18,19 @@ import (
 // 3. save the content of the format in a file in MPEG-TS format.
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-h265-to-jpeg/main.go b/examples/client-play-format-h265-to-jpeg/main.go
index 6d283fe2..2cafc673 100644
--- a/examples/client-play-format-h265-to-jpeg/main.go
+++ b/examples/client-play-format-h265-to-jpeg/main.go
@@ -46,16 +46,19 @@ func saveToFile(img image.Image) error {
 }
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-h265/main.go b/examples/client-play-format-h265/main.go
index bcfb9eef..02674fbe 100644
--- a/examples/client-play-format-h265/main.go
+++ b/examples/client-play-format-h265/main.go
@@ -23,16 +23,19 @@ import (
 // apt install -y libavcodec-dev libswscale-dev gcc pkg-config
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-lpcm/main.go b/examples/client-play-format-lpcm/main.go
index 17a09a15..8f326072 100644
--- a/examples/client-play-format-lpcm/main.go
+++ b/examples/client-play-format-lpcm/main.go
@@ -16,16 +16,19 @@ import (
 // 3. get LPCM samples of that format.
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-mjpeg/main.go b/examples/client-play-format-mjpeg/main.go
index 8f636e7b..c60e48e9 100644
--- a/examples/client-play-format-mjpeg/main.go
+++ b/examples/client-play-format-mjpeg/main.go
@@ -21,16 +21,19 @@ import (
 // 4. decode JPEG images into RGBA frames.
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-mpeg4audio-to-disk/main.go b/examples/client-play-format-mpeg4audio-to-disk/main.go
index 2aa6aa48..a4b309b1 100644
--- a/examples/client-play-format-mpeg4audio-to-disk/main.go
+++ b/examples/client-play-format-mpeg4audio-to-disk/main.go
@@ -17,16 +17,19 @@ import (
 // 3. save the content of the format in a file in MPEG-TS format.
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-mpeg4audio/main.go b/examples/client-play-format-mpeg4audio/main.go
index 5b0cd5d0..00d500e4 100644
--- a/examples/client-play-format-mpeg4audio/main.go
+++ b/examples/client-play-format-mpeg4audio/main.go
@@ -16,16 +16,19 @@ import (
 // 3. get access units of that format.
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-opus-to-disk/main.go b/examples/client-play-format-opus-to-disk/main.go
index 447c85ac..71d513f9 100644
--- a/examples/client-play-format-opus-to-disk/main.go
+++ b/examples/client-play-format-opus-to-disk/main.go
@@ -17,16 +17,19 @@ import (
 // 3. save the content of the format in a file in MPEG-TS format.
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-opus/main.go b/examples/client-play-format-opus/main.go
index aa85d2ba..0e36a327 100644
--- a/examples/client-play-format-opus/main.go
+++ b/examples/client-play-format-opus/main.go
@@ -16,16 +16,19 @@ import (
 // 3. get Opus packets of that format.
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-vp8/main.go b/examples/client-play-format-vp8/main.go
index c0d08de7..a02bc1d6 100644
--- a/examples/client-play-format-vp8/main.go
+++ b/examples/client-play-format-vp8/main.go
@@ -22,16 +22,19 @@ import (
 // apt install -y libavcodec-dev libswscale-dev gcc pkg-config
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-format-vp9/main.go b/examples/client-play-format-vp9/main.go
index 7677178d..c382f1f1 100644
--- a/examples/client-play-format-vp9/main.go
+++ b/examples/client-play-format-vp9/main.go
@@ -22,16 +22,19 @@ import (
 // apt install -y libavcodec-dev libswscale-dev gcc pkg-config
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-options/main.go b/examples/client-play-options/main.go
index 75810dcf..0aa728f3 100644
--- a/examples/client-play-options/main.go
+++ b/examples/client-play-options/main.go
@@ -18,8 +18,16 @@ import (
 // 2. connect to a RTSP server and read all medias on a path.
 
 func main() {
+	// parse URL
+	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
+	if err != nil {
+		panic(err)
+	}
+
 	// Client allows to set additional client options
-	c := &gortsplib.Client{
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
 		// transport protocol (UDP, Multicast or TCP). If nil, it is chosen automatically
 		Transport: nil,
 		// timeout of read operations
@@ -28,14 +36,8 @@ func main() {
 		WriteTimeout: 10 * time.Second,
 	}
 
-	// parse URL
-	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
-	if err != nil {
-		panic(err)
-	}
-
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-pause/main.go b/examples/client-play-pause/main.go
index ce467d23..a505d0be 100644
--- a/examples/client-play-pause/main.go
+++ b/examples/client-play-pause/main.go
@@ -20,16 +20,19 @@ import (
 // 4. repeat.
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-timestamp/main.go b/examples/client-play-timestamp/main.go
index fd28abfc..445bf87d 100644
--- a/examples/client-play-timestamp/main.go
+++ b/examples/client-play-timestamp/main.go
@@ -17,16 +17,19 @@ import (
 // 3. Get PTS and NTP of incoming RTP packets.
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play-to-record/main.go b/examples/client-play-to-record/main.go
index f5ce8294..795a0ebb 100644
--- a/examples/client-play-to-record/main.go
+++ b/examples/client-play-to-record/main.go
@@ -17,16 +17,19 @@ import (
 // 3. re-publish all medias on another path.
 
 func main() {
-	reader := gortsplib.Client{}
-
 	// parse source URL
 	sourceURL, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	reader := gortsplib.Client{
+		Scheme: sourceURL.Scheme,
+		Host:   sourceURL.Host,
+	}
+
 	// connect to the server
-	err = reader.Start(sourceURL.Scheme, sourceURL.Host)
+	err = reader.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-play/main.go b/examples/client-play/main.go
index f809327c..482be3ba 100644
--- a/examples/client-play/main.go
+++ b/examples/client-play/main.go
@@ -17,16 +17,19 @@ import (
 // 2. read all media streams on a path.
 
 func main() {
-	c := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
 	if err != nil {
 		panic(err)
 	}
 
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/client-query/main.go b/examples/client-query/main.go
index 08a5b840..a3f287d2 100644
--- a/examples/client-query/main.go
+++ b/examples/client-query/main.go
@@ -13,14 +13,17 @@ import (
 // 2. get and print informations about medias published on a path.
 
 func main() {
-	c := gortsplib.Client{}
-
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mypath")
 	if err != nil {
 		panic(err)
 	}
 
-	err = c.Start(u.Scheme, u.Host)
+	c := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
+	err = c.Start2()
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/proxy-backchannel/client.go b/examples/proxy-backchannel/client.go
index c100408a..ac944232 100644
--- a/examples/proxy-backchannel/client.go
+++ b/examples/proxy-backchannel/client.go
@@ -48,18 +48,20 @@ func (c *client) run() {
 }
 
 func (c *client) read() error {
-	rc := gortsplib.Client{
-		RequestBackChannels: true,
-	}
-
 	// parse URL
 	u, err := base.ParseURL(existingStream)
 	if err != nil {
 		return err
 	}
 
+	rc := gortsplib.Client{
+		Scheme:              u.Scheme,
+		Host:                u.Host,
+		RequestBackChannels: true,
+	}
+
 	// connect to the server
-	err = rc.Start(u.Scheme, u.Host)
+	err = rc.Start2()
 	if err != nil {
 		return err
 	}
diff --git a/examples/proxy/client.go b/examples/proxy/client.go
index 0b4d521d..eaf56110 100644
--- a/examples/proxy/client.go
+++ b/examples/proxy/client.go
@@ -35,16 +35,19 @@ func (c *client) run() {
 }
 
 func (c *client) read() error {
-	rc := gortsplib.Client{}
-
 	// parse URL
 	u, err := base.ParseURL(existingStream)
 	if err != nil {
 		return err
 	}
 
+	rc := gortsplib.Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
+
 	// connect to the server
-	err = rc.Start(u.Scheme, u.Host)
+	err = rc.Start2()
 	if err != nil {
 		return err
 	}


Test patch:
diff --git a/client_play_test.go b/client_play_test.go
index 399a0d19..fe0580a0 100644
--- a/client_play_test.go
+++ b/client_play_test.go
@@ -82,7 +82,10 @@ func readAll(c *Client, ur string, cb func(*description.Media, format.Format, *r
 		return err
 	}
 
-	err = c.Start(u.Scheme, u.Host)
+	c.Scheme = u.Scheme
+	c.Host = u.Host
+
+	err = c.Start2()
 	if err != nil {
 		return err
 	}
@@ -604,7 +607,12 @@ func TestClientPlay(t *testing.T) {
 				require.NoError(t, err2)
 			}()
 
+			u, err := base.ParseURL(ca.scheme + "://" + listenIP + ":8554/test/stream?param=value")
+			require.NoError(t, err)
+
 			c := Client{
+				Scheme:    u.Scheme,
+				Host:      u.Host,
 				TLSConfig: &tls.Config{InsecureSkipVerify: true},
 				Transport: func() *Transport {
 					switch ca.transport {
@@ -623,10 +631,7 @@ func TestClientPlay(t *testing.T) {
 				}(),
 			}
 
-			u, err := base.ParseURL(ca.scheme + "://" + listenIP + ":8554/test/stream?param=value")
-			require.NoError(t, err)
-
-			err = c.Start(u.Scheme, u.Host)
+			err = c.Start2()
 			require.NoError(t, err)
 			defer c.Close()
 
@@ -1029,14 +1034,16 @@ func TestClientPlayPartial(t *testing.T) {
 
 	packetRecv := make(chan struct{})
 
+	u, err := base.ParseURL("rtsp://" + listenIP + ":8554/teststream")
+	require.NoError(t, err)
+
 	c := Client{
+		Scheme:    u.Scheme,
+		Host:      u.Host,
 		Transport: transportPtr(TransportTCP),
 	}
 
-	u, err := base.ParseURL("rtsp://" + listenIP + ":8554/teststream")
-	require.NoError(t, err)
-
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	require.NoError(t, err)
 	defer c.Close()
 
@@ -3904,7 +3911,12 @@ func TestClientPlayBackChannel(t *testing.T) {
 				require.NoError(t, err2)
 			}()
 
+			u, err := base.ParseURL("rtsp://localhost:8554/teststream")
+			require.NoError(t, err)
+
 			c := Client{
+				Scheme:              u.Scheme,
+				Host:                u.Host,
 				RequestBackChannels: true,
 				Transport: func() *Transport {
 					if transport == "tcp" {
@@ -3916,10 +3928,7 @@ func TestClientPlayBackChannel(t *testing.T) {
 				receiverReportPeriod: 750 * time.Millisecond,
 			}
 
-			u, err := base.ParseURL("rtsp://localhost:8554/teststream")
-			require.NoError(t, err)
-
-			err = c.Start(u.Scheme, u.Host)
+			err = c.Start2()
 			require.NoError(t, err)
 			defer c.Close()
 
diff --git a/client_record_test.go b/client_record_test.go
index f01c28af..028c0538 100644
--- a/client_record_test.go
+++ b/client_record_test.go
@@ -80,7 +80,10 @@ func record(c *Client, ur string, medias []*description.Media, cb func(*descript
 		return err
 	}
 
-	err = c.Start(u.Scheme, u.Host)
+	c.Scheme = u.Scheme
+	c.Host = u.Host
+
+	err = c.Start2()
 	if err != nil {
 		return err
 	}
diff --git a/client_test.go b/client_test.go
index eb679eb1..5d5e5a2c 100644
--- a/client_test.go
+++ b/client_test.go
@@ -86,10 +86,12 @@ func TestClientTLSSetServerName(t *testing.T) {
 	require.NoError(t, err)
 
 	c := Client{
+		Scheme:    u.Scheme,
+		Host:      u.Host,
 		TLSConfig: &tls.Config{},
 	}
 
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	require.NoError(t, err)
 	defer c.Close()
 
@@ -103,9 +105,12 @@ func TestClientClose(t *testing.T) {
 	u, err := base.ParseURL("rtsp://localhost:8554/teststream")
 	require.NoError(t, err)
 
-	c := Client{}
+	c := Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
 
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	require.NoError(t, err)
 
 	c.Close()
@@ -162,9 +167,12 @@ func TestClientCloseDuringRequest(t *testing.T) {
 	u, err := base.ParseURL("rtsp://localhost:8554/teststream")
 	require.NoError(t, err)
 
-	c := Client{}
+	c := Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
 
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	require.NoError(t, err)
 
 	optionsDone := make(chan struct{})
@@ -232,9 +240,12 @@ func TestClientSession(t *testing.T) {
 	u, err := base.ParseURL("rtsp://localhost:8554/stream")
 	require.NoError(t, err)
 
-	c := Client{}
+	c := Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
 
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	require.NoError(t, err)
 	defer c.Close()
 
@@ -309,9 +320,12 @@ func TestClientAuth(t *testing.T) {
 	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/stream")
 	require.NoError(t, err)
 
-	c := Client{}
+	c := Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
 
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	require.NoError(t, err)
 	defer c.Close()
 
@@ -385,9 +399,12 @@ func TestClientCSeq(t *testing.T) {
 			u, err := base.ParseURL("rtsp://localhost:8554/teststream")
 			require.NoError(t, err)
 
-			c := Client{}
+			c := Client{
+				Scheme: u.Scheme,
+				Host:   u.Host,
+			}
 
-			err = c.Start(u.Scheme, u.Host)
+			err = c.Start2()
 			require.NoError(t, err)
 			defer c.Close()
 
@@ -448,9 +465,12 @@ func TestClientDescribeCharset(t *testing.T) {
 	u, err := base.ParseURL("rtsp://localhost:8554/teststream")
 	require.NoError(t, err)
 
-	c := Client{}
+	c := Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
 
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	require.NoError(t, err)
 	defer c.Close()
 
@@ -534,9 +554,12 @@ func TestClientReplyToServerRequest(t *testing.T) {
 			u, err := base.ParseURL("rtsp://localhost:8554/stream")
 			require.NoError(t, err)
 
-			c := Client{}
+			c := Client{
+				Scheme: u.Scheme,
+				Host:   u.Host,
+			}
 
-			err = c.Start(u.Scheme, u.Host)
+			err = c.Start2()
 			require.NoError(t, err)
 			defer c.Close()
 
@@ -599,9 +622,12 @@ func TestClientRelativeContentBase(t *testing.T) {
 	u, err := base.ParseURL("rtsp://localhost:8554/teststream")
 	require.NoError(t, err)
 
-	c := Client{}
+	c := Client{
+		Scheme: u.Scheme,
+		Host:   u.Host,
+	}
 
-	err = c.Start(u.Scheme, u.Host)
+	err = c.Start2()
 	require.NoError(t, err)
 	defer c.Close()
 
diff --git a/internal/teste2e/client_vs_server_test.go b/internal/teste2e/client_vs_server_test.go
index 0308ee83..bb816db0 100644
--- a/internal/teste2e/client_vs_server_test.go
+++ b/internal/teste2e/client_vs_server_test.go
@@ -156,10 +156,12 @@ func TestClientVsServer(t *testing.T) {
 			require.NoError(t, err)
 
 			reader := &gortsplib.Client{
+				Scheme:    u.Scheme,
+				Host:      u.Host,
 				TLSConfig: &tls.Config{InsecureSkipVerify: true},
 				Transport: &readerProto,
 			}
-			err = reader.Start(u.Scheme, u.Host)
+			err = reader.Start2()
 			require.NoError(t, err)
 			defer reader.Close()