Skip to content

Commit 9934767

Browse files
committed
Read Content-Length from HTTP response if information is missing in video
closes #246
1 parent 46ebe0a commit 9934767

File tree

2 files changed

+44
-16
lines changed

2 files changed

+44
-16
lines changed

client.go

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"io"
99
"log"
1010
"net/http"
11+
"strconv"
1112
)
1213

1314
// Client offers methods to download video metadata and video streams.
@@ -235,13 +236,45 @@ func (c *Client) GetStreamContext(ctx context.Context, video *Video, format *For
235236
}
236237

237238
r, w := io.Pipe()
239+
contentLength := format.ContentLength
238240

239-
go c.download(req, w, format)
241+
if contentLength == 0 {
242+
// some videos don't have length information
243+
contentLength = c.downloadOnce(req, w, format)
244+
} else {
245+
// we have length information, let's download by chunks!
246+
go c.downloadChunked(req, w, format)
247+
}
248+
249+
return r, contentLength, nil
250+
}
251+
252+
func (c *Client) downloadOnce(req *http.Request, w *io.PipeWriter, format *Format) int64 {
253+
resp, err := c.httpDo(req)
254+
if err != nil {
255+
//nolint:errcheck
256+
w.CloseWithError(err)
257+
return 0
258+
}
259+
260+
go func() {
261+
defer resp.Body.Close()
262+
_, err := io.Copy(w, resp.Body)
263+
if err == nil {
264+
w.Close()
265+
} else {
266+
//nolint:errcheck
267+
w.CloseWithError(err)
268+
}
269+
}()
240270

241-
return r, format.ContentLength, nil
271+
contentLength := resp.Header.Get("Content-Length")
272+
len, _ := strconv.ParseInt(contentLength, 10, 64)
273+
274+
return len
242275
}
243276

244-
func (c *Client) download(req *http.Request, w *io.PipeWriter, format *Format) {
277+
func (c *Client) downloadChunked(req *http.Request, w *io.PipeWriter, format *Format) {
245278
const chunkSize int64 = 10_000_000
246279
// Loads a chunk a returns the written bytes.
247280
// Downloading in multiple chunks is much faster:
@@ -263,19 +296,6 @@ func (c *Client) download(req *http.Request, w *io.PipeWriter, format *Format) {
263296
}
264297

265298
defer w.Close()
266-
//nolint:revive,errcheck
267-
if format.ContentLength == 0 {
268-
resp, err := c.httpDo(req)
269-
if err != nil {
270-
w.CloseWithError(err)
271-
return
272-
}
273-
274-
defer resp.Body.Close()
275-
276-
io.Copy(w, resp.Body)
277-
return
278-
}
279299

280300
//nolint:revive,errcheck
281301
// load all the chunks

client_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,19 @@ func TestGetVideoWithManifestURL(t *testing.T) {
107107
require.NoError(err)
108108
require.NotNil(video)
109109

110+
assert.NotEmpty(video.Formats)
110111
assert.NotEmpty(video.Thumbnails)
111112
assert.Greater(len(video.Thumbnails), 0)
112113
assert.NotEmpty(video.Thumbnails[0].URL)
113114
assert.NotEmpty(video.HLSManifestURL)
114115
assert.NotEmpty(video.DASHManifestURL)
116+
117+
format := video.Formats[0]
118+
assert.Zero(format.ContentLength)
119+
120+
_, size, err := testClient.GetStream(video, &format)
121+
require.NoError(err)
122+
require.NotZero(size)
115123
}
116124

117125
func TestGetStream(t *testing.T) {

0 commit comments

Comments
 (0)