Fix proxy endpoint for playlists
This commit is contained in:
		
							parent
							
								
									7e5c4856b4
								
							
						
					
					
						commit
						8052c02af1
					
				| 
						 | 
					@ -11,7 +11,7 @@ type Video struct {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetVideos(meta *metadata.Metadata) []Video {
 | 
					func GetVideos(meta *metadata.Metadata) []Video {
 | 
				
			||||||
	if meta.Type == "playlist" {
 | 
						if meta.IsPlaylist() {
 | 
				
			||||||
		return lo.Map(meta.Entries, func(video metadata.Metadata, _ int) Video {
 | 
							return lo.Map(meta.Entries, func(video metadata.Metadata, _ int) Video {
 | 
				
			||||||
			return GetVideos(&video)[0]
 | 
								return GetVideos(&video)[0]
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,7 +92,15 @@ func (r *routes) DownloadProxyHandler(c *fiber.Ctx) error {
 | 
				
			||||||
		return fiber.ErrInternalServerError
 | 
							return fiber.ErrInternalServerError
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	format, ok := lo.Find(meta.Formats, func(format metadata.Format) bool {
 | 
						videos := GetVideos(meta)
 | 
				
			||||||
 | 
						index := c.QueryInt("index")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if index < 0 || index >= len(videos) {
 | 
				
			||||||
 | 
							return fiber.ErrBadRequest
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						video := videos[index]
 | 
				
			||||||
 | 
						format, ok := lo.Find(video.Formats, func(format metadata.Format) bool {
 | 
				
			||||||
		return format.FormatID == formatId
 | 
							return format.FormatID == formatId
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
| 
						 | 
					@ -106,5 +114,9 @@ func (r *routes) DownloadProxyHandler(c *fiber.Ctx) error {
 | 
				
			||||||
		c.Set("Content-Length", fmt.Sprint(*format.FilesizeApprox))
 | 
							c.Set("Content-Length", fmt.Sprint(*format.FilesizeApprox))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return r.ytdl.Download(c.Response().BodyWriter(), url, format.FormatID)
 | 
						if len(videos) == 1 {
 | 
				
			||||||
 | 
							index = -1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return r.ytdl.Download(c.Response().BodyWriter(), url, format.FormatID, index)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,20 +9,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{$root := .}}
 | 
					{{$root := .}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{define "download"}}
 | 
					 | 
				
			||||||
<div style="font-size: smaller">{{.Format.Format}}</div>
 | 
					 | 
				
			||||||
<div class="flex-grow-1 d-flex gap-3">
 | 
					 | 
				
			||||||
  <a class="btn btn-primary flex-grow-1" download="{{.Meta.ID}}-{{.Format.Resolution}}.{{.Format.Ext}}" P
 | 
					 | 
				
			||||||
    href="{{.Format.Url}}">
 | 
					 | 
				
			||||||
    Download (direct)
 | 
					 | 
				
			||||||
  </a>
 | 
					 | 
				
			||||||
  <a class="btn btn-primary flex-grow-1" download="{{.Meta.ID}}-{{.Format.Resolution}}.{{.Format.Ext}}"
 | 
					 | 
				
			||||||
    href="{{.BasePath}}/download/proxy?url={{queryEscape .Url}}&format={{.Format.FormatID}}">
 | 
					 | 
				
			||||||
    Download (proxied)
 | 
					 | 
				
			||||||
  </a>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
{{end}}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{{range $vidIndex, $video := .Videos}}
 | 
					{{range $vidIndex, $video := .Videos}}
 | 
				
			||||||
{{if not (eq $vidIndex 0)}}
 | 
					{{if not (eq $vidIndex 0)}}
 | 
				
			||||||
<hr class="mt-5" />
 | 
					<hr class="mt-5" />
 | 
				
			||||||
| 
						 | 
					@ -40,7 +26,7 @@
 | 
				
			||||||
        Download (direct)
 | 
					        Download (direct)
 | 
				
			||||||
      </a>
 | 
					      </a>
 | 
				
			||||||
      <a class="btn btn-primary flex-grow-1" download="{{$root.Meta.ID}}-{{$format.Resolution}}.{{$format.Ext}}"
 | 
					      <a class="btn btn-primary flex-grow-1" download="{{$root.Meta.ID}}-{{$format.Resolution}}.{{$format.Ext}}"
 | 
				
			||||||
        href="{{$root.BasePath}}/download/proxy?url={{queryEscape $root.Url}}&format={{$format.FormatID}}">
 | 
					        href="{{$root.BasePath}}/download/proxy?url={{queryEscape $root.Url}}&format={{$format.FormatID}}&index={{$vidIndex}}">
 | 
				
			||||||
        Download (proxied)
 | 
					        Download (proxied)
 | 
				
			||||||
      </a>
 | 
					      </a>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,7 @@ package ytdl
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,3 +100,10 @@ func WithDebug() Option {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func WithPlaylistIndex(index int) Option {
 | 
				
			||||||
 | 
						return func(opts *Options) error {
 | 
				
			||||||
 | 
							opts.args = append(opts.args, "--playlist-items", fmt.Sprint(index+1))
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -176,3 +176,7 @@ type Metadata struct {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Chapters []Chapter `json:"chapters"`
 | 
						Chapters []Chapter `json:"chapters"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m Metadata) IsPlaylist() bool {
 | 
				
			||||||
 | 
						return m.Type == "playlist"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,7 @@ import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Ytdl interface {
 | 
					type Ytdl interface {
 | 
				
			||||||
	GetMetadata(url string) (*metadata.Metadata, error)
 | 
						GetMetadata(url string) (*metadata.Metadata, error)
 | 
				
			||||||
	Download(w io.Writer, url, format string) error
 | 
						Download(w io.Writer, url, format string, index int) error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ytdlImpl struct {
 | 
					type ytdlImpl struct {
 | 
				
			||||||
| 
						 | 
					@ -82,13 +82,17 @@ func (y *ytdlImpl) GetMetadata(url string) (*metadata.Metadata, error) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Download implements Ytdl
 | 
					// Download implements Ytdl
 | 
				
			||||||
func (y *ytdlImpl) Download(w io.Writer, url, format string) error {
 | 
					func (y *ytdlImpl) Download(w io.Writer, url, format string, index int) error {
 | 
				
			||||||
	options := append(
 | 
						options := append(
 | 
				
			||||||
		y.baseOptions(url),
 | 
							y.baseOptions(url),
 | 
				
			||||||
		WithFormat(format),
 | 
							WithFormat(format),
 | 
				
			||||||
		WithStreamOutput(w),
 | 
							WithStreamOutput(w),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if index >= 0 {
 | 
				
			||||||
 | 
							options = append(options, WithPlaylistIndex(index))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := Exec(y.cfg.Ytdlp.BinaryPath, url, options...); err != nil {
 | 
						if err := Exec(y.cfg.Ytdlp.BinaryPath, url, options...); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue