Skip to content

Commit

Permalink
feat: watch playlists (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
jfreeland authored Feb 12, 2021
1 parent ab4d5ad commit ffefd4d
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 3 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module github.com/soldiermoth/hlsq

go 1.14

require golang.org/x/text v0.3.4
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
82 changes: 79 additions & 3 deletions hlsq.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ import (
"fmt"
"io"
"log"
"net/http"
"os"
"strconv"
"time"

"github.com/soldiermoth/hlsq/hlsqlib"
"golang.org/x/text/unicode/norm"
)

func main() {
Expand All @@ -20,6 +24,8 @@ func main() {
query = flag.String("query", "", "Query")
chomp = flag.Bool("chomp", false, "Removes whitespace")
demuxed = flag.Bool("demuxed", false, "Set to demuxed colors")
watch = flag.Bool("watch", false, "Continuously watch the playlist (requires url)")
url = flag.String("url", "", "URL of the manifest to watch (required to watch)")
r io.Reader
err error
)
Expand Down Expand Up @@ -52,6 +58,8 @@ func main() {
if r, err = os.Open(args[0]); err != nil {
log.Fatalf("could not open file %q err=%q", args[0], err)
}
} else if *watch && *url != "" {
r = getManifest(*url)
} else {
log.Fatal("expected 1 argument of the m3u8 file to process or to read from stdin")
}
Expand All @@ -71,9 +79,59 @@ func main() {
}
opts = append([]hlsqlib.SerializeOption{hlsqlib.AttrMatch(queryFunc)}, opts...)
}
for scanner.Scan() {
line := scanner.Tag()
hlsqlib.Serialize(os.Stdout, line, opts...)
if *watch && *url != "" {
opts = append(opts, hlsqlib.Chomp)
var updatePeriod time.Duration
seen := make(map[string]bool)
ignoredTagsOnUpdate := []string{
"#EXTM3U",
"#EXT-X-VERSION",
"#EXT-X-DISCONTINUITY-SEQUENCE",
"#EXT-X-PUBLISHED-TIME",
"#EXT-X-TARGETDURATION",
"#EXT-X-MEDIA-SEQUENCE",
"#EXT-X-PROGRAM-DATE-TIME",
"#EXT-X-KEY",
}
for scanner.Scan() {
line := scanner.Tag()
if line.Name == "#EXT-X-TARGETDURATION" {
d, _ := strconv.Atoi(line.Attrs[0].Key)
updatePeriod = time.Duration(d) * time.Second
}
if line.Name == "#EXTINF" {
segment := norm.NFC.Bytes([]byte(string(line.Trailing[0])))
seen[string(segment)] = true
}
hlsqlib.Serialize(os.Stdout, line, opts...)
}
for range time.Tick(updatePeriod) {
r = getManifest(*url)
scanner = hlsqlib.NewScanner(r)
updated := false
for scanner.Scan() {
line := scanner.Tag()
if stringInSlice(line.Name, ignoredTagsOnUpdate) {
continue
}
segment := norm.NFC.Bytes([]byte(string(line.Trailing[0])))
if line.Name == "#EXTINF" && seen[string(segment)] {
continue
} else if line.Name == "#EXTINF" && !seen[string(segment)] {
seen[string(segment)] = true
}
hlsqlib.Serialize(os.Stdout, line, opts...)
updated = true
}
if !updated {
fmt.Println("manifest did not change this period")
}
}
} else {
for scanner.Scan() {
line := scanner.Tag()
hlsqlib.Serialize(os.Stdout, line, opts...)
}
}
fmt.Fprintln(os.Stdout)
}
Expand All @@ -86,9 +144,27 @@ func (f flagColor) String() string {
}
return hlsqlib.NewColorizer(*f.Color).S("Example")
}

func (f flagColor) Set(s string) (err error) {
if s != "" {
*f.Color, err = hlsqlib.ParseColor(s)
}
return
}

func getManifest(url string) io.ReadCloser {
resp, err := http.Get(url)
if err != nil {
log.Fatalf("could not fetch manifest: %v\n", err)
}
return resp.Body
}

func stringInSlice(a string, list []string) bool {
for _, b := range list {
if b == a {
return true
}
}
return false
}

0 comments on commit ffefd4d

Please sign in to comment.