Skip to content

Commit

Permalink
Add support for HLS manifests [WIP]
Browse files Browse the repository at this point in the history
test video: YcNc4IBLI1A
  • Loading branch information
corny committed Dec 25, 2023
1 parent ee4db5e commit d7a4921
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 1 deletion.
32 changes: 31 additions & 1 deletion client.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package youtube

import (
"bufio"
"bytes"
"context"
"encoding/json"
Expand All @@ -11,6 +12,7 @@ import (
"net/http"
"net/url"
"strconv"
"strings"
"sync/atomic"

"log/slog"
Expand All @@ -29,7 +31,7 @@ var (
)

// DefaultClient type to use. No reason to change but you could if you wanted to.
var DefaultClient = AndroidClient
var DefaultClient = IosClient

// Client offers methods to download video metadata and video streams.
type Client struct {
Expand Down Expand Up @@ -72,6 +74,29 @@ func (c *Client) GetVideoContext(ctx context.Context, url string) (*Video, error
return c.videoFromID(ctx, id)
}

func (c *Client) fetchHLS(ctx context.Context, v *Video) error {
resp, err := c.httpGet(ctx, v.HLSManifestURL)
if err != nil {
return err
}
defer resp.Body.Close()

scanner := bufio.NewScanner(resp.Body)

for scanner.Scan() {
line := scanner.Text()
if !strings.HasPrefix(line, "#EXT-X-STREAM-INF:") {

Check failure on line 88 in client.go

View workflow job for this annotation

GitHub Actions / Linters (Static Analysis) for Go (ubuntu-22.04, 1.21.x)

SA4017: HasPrefix doesn't have side effects and its return value is ignored (staticcheck)

Check failure on line 88 in client.go

View workflow job for this annotation

GitHub Actions / Linters (Static Analysis) for Go (ubuntu-22.04, 1.x)

SA4017: HasPrefix doesn't have side effects and its return value is ignored (staticcheck)
continue
}

// TODO parse line

//url := scanner.Text()
}

return nil
}

func (c *Client) videoFromID(ctx context.Context, id string) (*Video, error) {
c.assureClient()

Expand All @@ -86,6 +111,11 @@ func (c *Client) videoFromID(ctx context.Context, id string) (*Video, error) {

// return early if all good
if err = v.parseVideoInfo(body); err == nil {

if v.HLSManifestURL != "" {
c.fetchHLS(ctx, &v)

Check failure on line 116 in client.go

View workflow job for this annotation

GitHub Actions / Linters (Static Analysis) for Go (ubuntu-22.04, 1.21.x)

Error return value of `c.fetchHLS` is not checked (errcheck)

Check failure on line 116 in client.go

View workflow job for this annotation

GitHub Actions / Linters (Static Analysis) for Go (ubuntu-22.04, 1.x)

Error return value of `c.fetchHLS` is not checked (errcheck)
}

return &v, nil
}

Expand Down
4 changes: 4 additions & 0 deletions cmd/youtubedr/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"fmt"
"io"
"log"
"os"
"strconv"
"strings"
Expand Down Expand Up @@ -52,6 +53,9 @@ var infoCmd = &cobra.Command{
Description: video.Description,
}

log.Println("DASH", video.DASHManifestURL)
log.Println("HLS", video.HLSManifestURL)

for _, format := range video.Formats {
bitrate := format.AverageBitrate
if bitrate == 0 {
Expand Down
Loading

0 comments on commit d7a4921

Please sign in to comment.