refactor: remove all playlist support, fix message ordering
All checks were successful
CI / build (push) Successful in 54s
All checks were successful
CI / build (push) Successful in 54s
- Remove playlist handler, keyboard, and all related callback routing - Strip playlist parameter from YouTube Music radio URLs, reject pure playlists - Send media preview before format selection prompt (correct ordering) - Remove DetectPlaylist/GetPlaylistInfo methods (no longer needed) - Remove IsPlaylist, PlaylistCount, PlaylistEntries from MediaInfo - Remove PlaylistState struct, keep PlaylistEntry for search results - Update README to reflect removal of playlist feature
This commit is contained in:
@@ -151,19 +151,11 @@ func (c *Client) GetMediaInfo(url string) (*domain.MediaInfo, error) {
|
||||
}
|
||||
|
||||
mi := &domain.MediaInfo{
|
||||
URL: url,
|
||||
Title: info.Title,
|
||||
Uploader: info.Uploader,
|
||||
Thumbnail: info.Thumbnail,
|
||||
Duration: info.Duration,
|
||||
IsPlaylist: info.Playlist != "",
|
||||
}
|
||||
|
||||
if mi.IsPlaylist {
|
||||
mi.PlaylistCount = info.PlaylistCount
|
||||
mi.PlaylistEntries = c.parsePlaylistEntries(info.Entries)
|
||||
c.setCache(url, mi)
|
||||
return mi, nil
|
||||
URL: url,
|
||||
Title: info.Title,
|
||||
Uploader: info.Uploader,
|
||||
Thumbnail: info.Thumbnail,
|
||||
Duration: info.Duration,
|
||||
}
|
||||
|
||||
langSet := make(map[string]bool)
|
||||
@@ -171,8 +163,6 @@ func (c *Client) GetMediaInfo(url string) (*domain.MediaInfo, error) {
|
||||
for _, f := range info.Formats {
|
||||
ff := c.convertFormat(f)
|
||||
mi.Formats = append(mi.Formats, ff)
|
||||
// Only consider languages from formats with audio or video to avoid
|
||||
// prompting for subtitle-only or auto-generated caption languages.
|
||||
if (ff.HasAudio || ff.HasVideo) && ff.Language != "" && !langSet[ff.Language] {
|
||||
langSet[ff.Language] = true
|
||||
mi.Languages = append(mi.Languages, ff.Language)
|
||||
@@ -187,68 +177,6 @@ func (c *Client) GetMediaInfo(url string) (*domain.MediaInfo, error) {
|
||||
return mi, nil
|
||||
}
|
||||
|
||||
// GetPlaylistInfo fetches a flat playlist listing (fast, no format detail).
|
||||
func (c *Client) GetPlaylistInfo(url string) (*domain.MediaInfo, error) {
|
||||
if cached := c.getCached(url); cached != nil {
|
||||
slog.Debug("cache hit", "url", url)
|
||||
return cached, nil
|
||||
}
|
||||
|
||||
isPlaylist, mi, err := c.DetectPlaylist(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !isPlaylist {
|
||||
mi.IsPlaylist = false
|
||||
mi.PlaylistCount = 0
|
||||
mi.PlaylistEntries = nil
|
||||
}
|
||||
|
||||
c.setCache(url, mi)
|
||||
return mi, nil
|
||||
}
|
||||
|
||||
// DetectPlaylist runs a fast flat yt-dlp check to determine if the URL is a playlist.
|
||||
// It returns basic info without format details. For non-playlist URLs it returns false.
|
||||
// Does NOT cache the result so a subsequent GetMediaInfo call fetches full format info.
|
||||
func (c *Client) DetectPlaylist(url string) (bool, *domain.MediaInfo, error) {
|
||||
args := []string{
|
||||
"-J", "--flat-playlist", "--no-download",
|
||||
"--no-warnings",
|
||||
url,
|
||||
}
|
||||
if c.cookiesFile != "" {
|
||||
args = append(args, "--cookies", c.cookiesFile)
|
||||
}
|
||||
if c.proxyURL != "" {
|
||||
args = append(args, "--proxy", c.proxyURL)
|
||||
}
|
||||
|
||||
slog.Info("detecting playlist", "url", url)
|
||||
out, err := c.run(args)
|
||||
if err != nil {
|
||||
return false, nil, fmt.Errorf("yt-dlp playlist detection failed: %w", err)
|
||||
}
|
||||
|
||||
var rawInfo ytdlpInfo
|
||||
if err := json.Unmarshal(out, &rawInfo); err != nil {
|
||||
return false, nil, fmt.Errorf("parse yt-dlp output: %w", err)
|
||||
}
|
||||
|
||||
mi := &domain.MediaInfo{
|
||||
URL: url,
|
||||
Title: rawInfo.Title,
|
||||
Uploader: rawInfo.Uploader,
|
||||
Thumbnail: rawInfo.Thumbnail,
|
||||
Duration: rawInfo.Duration,
|
||||
IsPlaylist: rawInfo.Playlist != "",
|
||||
PlaylistCount: rawInfo.PlaylistCount,
|
||||
PlaylistEntries: c.parsePlaylistEntries(rawInfo.Entries),
|
||||
}
|
||||
|
||||
return mi.IsPlaylist, mi, nil
|
||||
}
|
||||
|
||||
func (c *Client) parsePlaylistEntries(entries []json.RawMessage) []domain.PlaylistEntry {
|
||||
var result []domain.PlaylistEntry
|
||||
for _, raw := range entries {
|
||||
|
||||
Reference in New Issue
Block a user