feat(media): fallback to lower quality if requested format is unavailable
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/mathismqn/godeez/internal/config"
|
"github.com/mathismqn/godeez/internal/config"
|
||||||
@@ -53,6 +54,8 @@ func newDownloadCmd(resourceType string) *cobra.Command {
|
|||||||
}
|
}
|
||||||
cmd.SetContext(context.WithValue(cmd.Context(), "appConfig", appConfig))
|
cmd.SetContext(context.WithValue(cmd.Context(), "appConfig", appConfig))
|
||||||
|
|
||||||
|
opts.Quality = strings.ToLower(opts.Quality)
|
||||||
|
|
||||||
return opts.Validate()
|
return opts.Validate()
|
||||||
},
|
},
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
|||||||
@@ -98,10 +98,8 @@ func (c *Client) FetchMedia(ctx context.Context, song *Song, quality string) (*M
|
|||||||
case "mp3_128":
|
case "mp3_128":
|
||||||
formats = `[{"cipher":"BF_CBC_STRIPE","format":"MP3_128"}]`
|
formats = `[{"cipher":"BF_CBC_STRIPE","format":"MP3_128"}]`
|
||||||
case "mp3_320":
|
case "mp3_320":
|
||||||
formats = `[{"cipher":"BF_CBC_STRIPE","format":"MP3_320"}]`
|
formats = `[{"cipher":"BF_CBC_STRIPE","format":"MP3_320"},{"cipher":"BF_CBC_STRIPE","format":"MP3_128"}]`
|
||||||
case "flac":
|
case "flac", "best":
|
||||||
formats = `[{"cipher":"BF_CBC_STRIPE","format":"FLAC"}]`
|
|
||||||
case "best":
|
|
||||||
formats = `[{"cipher":"BF_CBC_STRIPE","format":"FLAC"},{"cipher":"BF_CBC_STRIPE","format":"MP3_320"},{"cipher":"BF_CBC_STRIPE","format":"MP3_128"}]`
|
formats = `[{"cipher":"BF_CBC_STRIPE","format":"FLAC"},{"cipher":"BF_CBC_STRIPE","format":"MP3_320"},{"cipher":"BF_CBC_STRIPE","format":"MP3_128"}]`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,15 +36,7 @@ func (m *Media) GetURL() (string, error) {
|
|||||||
return "", fmt.Errorf("no media sources found")
|
return "", fmt.Errorf("no media sources found")
|
||||||
}
|
}
|
||||||
|
|
||||||
url := m.Data[0].Media[0].Sources[0].URL
|
return m.Data[0].Media[0].Sources[0].URL, nil
|
||||||
for _, source := range m.Data[0].Media[0].Sources {
|
|
||||||
if source.Provider == "ak" {
|
|
||||||
url = source.URL
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return url, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Media) GetFormat() (string, error) {
|
func (m *Media) GetFormat() (string, error) {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -168,7 +169,7 @@ func (c *Client) downloadSong(ctx context.Context, resource deezer.Resource, son
|
|||||||
|
|
||||||
media, err := c.deezerClient.FetchMedia(ctx, song, opts.Quality)
|
media, err := c.deezerClient.FetchMedia(ctx, song, opts.Quality)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return warnings, fmt.Errorf("failed to fetch media: %w", err)
|
return nil, fmt.Errorf("failed to fetch media: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fileName := song.GetFileName(c.resourceType, song, media)
|
fileName := song.GetFileName(c.resourceType, song, media)
|
||||||
@@ -176,11 +177,11 @@ func (c *Client) downloadSong(ctx context.Context, resource deezer.Resource, son
|
|||||||
|
|
||||||
mediaFormat, err := media.GetFormat()
|
mediaFormat, err := media.GetFormat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return warnings, fmt.Errorf("failed to get media format: %w", err)
|
return nil, fmt.Errorf("failed to get media format: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if path, skip := c.shouldSkipDownload(ctx, song.ID, mediaFormat); skip {
|
if path, skip := c.shouldSkipDownload(ctx, song.ID, mediaFormat); skip {
|
||||||
return warnings, SkipError{Path: path}
|
return nil, SkipError{Path: path}
|
||||||
}
|
}
|
||||||
|
|
||||||
var metricsChan chan *bpm.Metrics
|
var metricsChan chan *bpm.Metrics
|
||||||
@@ -201,7 +202,7 @@ func (c *Client) downloadSong(ctx context.Context, resource deezer.Resource, son
|
|||||||
|
|
||||||
stream, err := c.deezerClient.GetMediaStream(ctx, media, song.ID)
|
stream, err := c.deezerClient.GetMediaStream(ctx, media, song.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return warnings, fmt.Errorf("failed to get media stream: %w", err)
|
return nil, fmt.Errorf("failed to get media stream: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
dlCtx, cancel := context.WithTimeout(ctx, opts.Timeout)
|
dlCtx, cancel := context.WithTimeout(ctx, opts.Timeout)
|
||||||
@@ -211,7 +212,11 @@ func (c *Client) downloadSong(ctx context.Context, resource deezer.Resource, son
|
|||||||
if err := c.streamToFile(dlCtx, stream, outputPath, key); err != nil {
|
if err := c.streamToFile(dlCtx, stream, outputPath, key); err != nil {
|
||||||
fileutil.DeleteFile(outputPath)
|
fileutil.DeleteFile(outputPath)
|
||||||
|
|
||||||
return warnings, fmt.Errorf("failed to stream to file: %w", err)
|
return nil, fmt.Errorf("failed to stream to file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.Quality != strings.ToLower(mediaFormat) {
|
||||||
|
warnings = append(warnings, fmt.Sprintf("requested quality '%s' not available, using '%s' instead", opts.Quality, strings.ToLower(mediaFormat)))
|
||||||
}
|
}
|
||||||
|
|
||||||
metrics := &bpm.Metrics{}
|
metrics := &bpm.Metrics{}
|
||||||
|
|||||||
Reference in New Issue
Block a user