Skip to content

Commit cf27c00

Browse files
committed
feat: try all CDN URLs available before failing
See #188
1 parent 3e1cbe4 commit cf27c00

File tree

1 file changed

+40
-18
lines changed

1 file changed

+40
-18
lines changed

player/player.go

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/devgianlu/go-librespot/vorbis"
1313
"golang.org/x/exp/rand"
1414
"net/http"
15+
"net/url"
1516
"time"
1617
)
1718

@@ -415,6 +416,43 @@ func (p *Player) SetSecondaryStream(source librespot.AudioSource) {
415416

416417
const DisableCheckMediaRestricted = true
417418

419+
func (p *Player) httpChunkedReaderFromStorageResolve(log librespot.Logger, client *http.Client, storageResolve *downloadpb.StorageResolveResponse) (*audio.HttpChunkedReader, error) {
420+
if storageResolve.Result == downloadpb.StorageResolveResponse_STORAGE {
421+
return nil, fmt.Errorf("old storage not supported")
422+
} else if storageResolve.Result == downloadpb.StorageResolveResponse_RESTRICTED {
423+
return nil, fmt.Errorf("storage is restricted")
424+
} else if storageResolve.Result == downloadpb.StorageResolveResponse_CDN {
425+
if len(storageResolve.Cdnurl) == 0 {
426+
return nil, fmt.Errorf("no cdn urls")
427+
}
428+
429+
log.Tracef("found %d cdn urls", len(storageResolve.Cdnurl))
430+
431+
var err error
432+
for i := 0; i < len(storageResolve.Cdnurl); i++ {
433+
var cdnUrl *url.URL
434+
cdnUrl, err = url.Parse(storageResolve.Cdnurl[i])
435+
if err != nil {
436+
log.WithError(err).WithField("url", storageResolve.Cdnurl[i]).Warnf("failed parsing cdn url, trying next url")
437+
continue
438+
}
439+
440+
var rawStream *audio.HttpChunkedReader
441+
rawStream, err = audio.NewHttpChunkedReader(log, client, cdnUrl.String())
442+
if err != nil {
443+
log.WithError(err).WithField("url", cdnUrl.String()).Warnf("failed creating chunked reader for %s, trying next url", cdnUrl.Host)
444+
continue
445+
}
446+
447+
return rawStream, nil
448+
}
449+
450+
return nil, fmt.Errorf("failed creating chunked reader for any cdn url: %w", err)
451+
} else {
452+
return nil, fmt.Errorf("unknown storage resolve result: %s", storageResolve.Result)
453+
}
454+
}
455+
418456
func (p *Player) NewStream(ctx context.Context, client *http.Client, spotId librespot.SpotifyId, bitrate int, mediaPosition int64) (*Stream, error) {
419457
log := p.log.WithField("uri", spotId.Uri())
420458

@@ -487,27 +525,11 @@ func (p *Player) NewStream(ctx context.Context, client *http.Client, spotId libr
487525
return nil, fmt.Errorf("failed resolving track storage: %w", err)
488526
}
489527

490-
var trackUrl string
491-
switch storageResolve.Result {
492-
case downloadpb.StorageResolveResponse_CDN:
493-
if len(storageResolve.Cdnurl) == 0 {
494-
return nil, fmt.Errorf("no cdn urls")
495-
}
496-
497-
trackUrl = storageResolve.Cdnurl[0]
498-
case downloadpb.StorageResolveResponse_STORAGE:
499-
return nil, fmt.Errorf("old storage not supported")
500-
case downloadpb.StorageResolveResponse_RESTRICTED:
501-
return nil, fmt.Errorf("storage is restricted")
502-
default:
503-
return nil, fmt.Errorf("unknown storage resolve result: %s", storageResolve.Result)
504-
}
505-
506528
p.events.PostStreamResolveStorage(playbackId)
507529

508-
rawStream, err := audio.NewHttpChunkedReader(log.WithField("uri", spotId.String()), client, trackUrl)
530+
rawStream, err := p.httpChunkedReaderFromStorageResolve(log, client, storageResolve)
509531
if err != nil {
510-
return nil, fmt.Errorf("failed initializing chunked reader: %w", err)
532+
return nil, fmt.Errorf("failed creating chunked reader: %w", err)
511533
}
512534

513535
p.events.PostStreamInitHttpChunkReader(playbackId, rawStream)

0 commit comments

Comments
 (0)