From db1f91606edf1245985f0bc22e5c676800fa3f4f Mon Sep 17 00:00:00 2001 From: Evan Fiordeliso Date: Sat, 15 Apr 2023 12:38:33 -0400 Subject: [PATCH] Remove format grouping and add support for playlists --- go.mod | 2 ++ go.sum | 4 ++++ web/formats.go | 34 ++++++++++++++++++++++++++ web/serve.go | 11 +-------- web/views.go | 14 +++++++++++ web/views/download.html | 48 ++++++++++++++++++++++++++----------- web/views/layouts/main.html | 12 ++++++++++ ytdl/data.go | 7 +++++- ytdl/meta.go | 9 +++---- ytdl/stream.go | 1 + 10 files changed, 113 insertions(+), 29 deletions(-) create mode 100644 web/formats.go diff --git a/go.mod b/go.mod index cbfd027..81f027e 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,9 @@ require ( github.com/adrg/xdg v0.4.0 github.com/gofiber/fiber/v2 v2.43.0 github.com/gofiber/template v1.8.0 + github.com/htfy96/reformism v0.0.0-20160819020323-e5bfca398e73 github.com/samber/lo v1.38.1 + github.com/samber/mo v1.8.0 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.10.0 github.com/sujit-baniya/flash v0.1.8 diff --git a/go.sum b/go.sum index d27a5e5..be9b205 100644 --- a/go.sum +++ b/go.sum @@ -244,6 +244,8 @@ github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOn github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/htfy96/reformism v0.0.0-20160819020323-e5bfca398e73 h1:Shcv21tstWAyUkKxbn5bTARYej9sgEgFgTRxUPk1J8o= +github.com/htfy96/reformism v0.0.0-20160819020323-e5bfca398e73/go.mod h1:i2jduFeVras6pm8GnBWdfVKj97mGEXJogjMHzyJhukY= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -348,6 +350,8 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/samber/mo v1.8.0 h1:vYjHTfg14JF9tD2NLhpoUsRi9bjyRoYwa4+do0nvbVw= +github.com/samber/mo v1.8.0/go.mod h1:BfkrCPuYzVG3ZljnZB783WIJIGk1mcZr9c9CPf8tAxs= github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 h1:rmMl4fXJhKMNWl+K+r/fq4FbbKI+Ia2m9hYBLm2h4G4= github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94/go.mod h1:90zrgN3D/WJsDd1iXHT96alCoN2KJo6/4x1DZC3wZs8= github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d/go.mod h1:Gy+0tqhJvgGlqnTF8CVGP0AaGRjwBtXs/a5PA0Y3+A4= diff --git a/web/formats.go b/web/formats.go new file mode 100644 index 0000000..a2e6398 --- /dev/null +++ b/web/formats.go @@ -0,0 +1,34 @@ +package web + +import ( + "github.com/samber/lo" + "go.fifitido.net/ytdl-web/ytdl" +) + +type Video struct { + Meta ytdl.Metadata + Formats []ytdl.Format +} + +func GetVideos(meta ytdl.Metadata) []Video { + if meta.Type == "playlist" { + return lo.Map(meta.Entries, func(video ytdl.Metadata, _ int) Video { + return GetVideos(video)[0] + }) + } + + formats := lo.Filter(meta.Formats, func(item ytdl.Format, _ int) bool { + return item.ACodec != "none" && item.VCodec != "none" && item.Protocol != "m3u8_native" + }) + + for i, j := 0, len(formats)-1; i < j; i, j = i+1, j-1 { + formats[i], formats[j] = formats[j], formats[i] + } + + return []Video{ + { + Meta: meta, + Formats: formats, + }, + } +} diff --git a/web/serve.go b/web/serve.go index c3c5ebc..f1a327d 100644 --- a/web/serve.go +++ b/web/serve.go @@ -3,7 +3,6 @@ package web import ( "fmt" "net/url" - "sort" "github.com/gofiber/fiber/v2" "github.com/samber/lo" @@ -52,19 +51,11 @@ func Serve() error { }).Redirect("/") } - formats := lo.Filter(meta.Formats, func(item ytdl.Format, _ int) bool { - return item.ACodec != "none" && item.VCodec != "none" && item.Protocol != "m3u8_native" - }) - - sort.Slice(formats, func(i, j int) bool { - return formats[i].Width > formats[j].Width - }) - return c.Render("views/download", fiber.Map{ "BasePath": viper.GetString("base_path"), "Url": url, "Meta": meta, - "Formats": formats, + "Videos": GetVideos(meta), "Version": version.Version, "Build": version.Build, "YtdlpVersion": ytdl.GetVersion(), diff --git a/web/views.go b/web/views.go index 488cdfa..26c6d4f 100644 --- a/web/views.go +++ b/web/views.go @@ -8,6 +8,8 @@ import ( "net/url" "github.com/gofiber/template/html" + "github.com/htfy96/reformism" + "go.fifitido.net/ytdl-web/ytdl" ) //go:embed views/* @@ -34,5 +36,17 @@ func ViewsEngine() *html.Engine { return string(j), nil }, ) + engine.AddFunc( + "downloadContext", func(meta ytdl.Metadata, url, basePath string, format ytdl.Format) map[string]any { + return map[string]any{ + "Meta": meta, + "Url": url, + "BasePath": basePath, + "Format": format, + } + }, + ) + + engine.AddFuncMap(reformism.FuncsHTML) return engine } diff --git a/web/views/download.html b/web/views/download.html index 6cf3295..f9da057 100644 --- a/web/views/download.html +++ b/web/views/download.html @@ -1,30 +1,50 @@

Download Video

-

{{.Meta.Title}}

+

{{.Meta.Title}}

{{.Url}}

- {{.Meta.Title}} Download Another Video
-{{$id := .Meta.ID}} -{{$url := .Url}} -{{$basePath := .BasePath}} +{{$root := .}} -
- {{range .Formats}} -
-
{{.Format}}
+{{define "download"}} +
{{.Format.Format}}
+ +{{end}} + +{{range $vidIndex, $video := .Videos}} +{{if not (eq $vidIndex 0)}} +
+{{end}} +
+
+ {{.Meta.Title}} +
+
+ {{range $index, $format := $video.Formats}} +
{{$format.Format}}
+ {{end}}
- {{end}} -
\ No newline at end of file +
+{{end}} \ No newline at end of file diff --git a/web/views/layouts/main.html b/web/views/layouts/main.html index fd09a71..840c7ad 100644 --- a/web/views/layouts/main.html +++ b/web/views/layouts/main.html @@ -25,6 +25,18 @@ filter: none; opacity: 1; } + + .downloads { + display: grid; + grid-template-columns: minmax(auto, max-content) auto; + gap: 1.5rem; + align-items: start; + } + + .see-more-btn, + .collapse { + grid-column: span 2; + } diff --git a/ytdl/data.go b/ytdl/data.go index 8f147f3..5dfa2f4 100644 --- a/ytdl/data.go +++ b/ytdl/data.go @@ -1,6 +1,11 @@ package ytdl -type Metdata struct { +type Metadata struct { + Type string `json:"_type"` + + // A list of videos in the playlist + Entries []Metadata + // Video identifier. ID string `json:"id"` diff --git a/ytdl/meta.go b/ytdl/meta.go index b643d6d..44e0e42 100644 --- a/ytdl/meta.go +++ b/ytdl/meta.go @@ -6,10 +6,11 @@ import ( "os/exec" ) -func GetMetadata(url string) (Metdata, error) { +func GetMetadata(url string) (Metadata, error) { cmd := exec.Command( "yt-dlp", "-J", + "--cookies-from-browser", "firefox", url, ) @@ -17,12 +18,12 @@ func GetMetadata(url string) (Metdata, error) { cmd.Stdout = &out if err := cmd.Run(); err != nil { - return Metdata{}, err + return Metadata{}, err } - var meta Metdata + var meta Metadata if err := json.Unmarshal(out.Bytes(), &meta); err != nil { - return Metdata{}, err + return Metadata{}, err } return meta, nil diff --git a/ytdl/stream.go b/ytdl/stream.go index b6f7f2a..01fa008 100644 --- a/ytdl/stream.go +++ b/ytdl/stream.go @@ -11,6 +11,7 @@ func Stream(wr io.Writer, url string, format Format) error { "-o", "-", "-f", format.FormatID, "--merge-output-format", "mkv", + "--cookies-from-browser", "firefox", url, )