@@ -12,6 +12,7 @@ import (
12
12
"github.com/devgianlu/go-librespot/vorbis"
13
13
"golang.org/x/exp/rand"
14
14
"net/http"
15
+ "net/url"
15
16
"time"
16
17
)
17
18
@@ -415,6 +416,43 @@ func (p *Player) SetSecondaryStream(source librespot.AudioSource) {
415
416
416
417
const DisableCheckMediaRestricted = true
417
418
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
+
418
456
func (p * Player ) NewStream (ctx context.Context , client * http.Client , spotId librespot.SpotifyId , bitrate int , mediaPosition int64 ) (* Stream , error ) {
419
457
log := p .log .WithField ("uri" , spotId .Uri ())
420
458
@@ -487,27 +525,11 @@ func (p *Player) NewStream(ctx context.Context, client *http.Client, spotId libr
487
525
return nil , fmt .Errorf ("failed resolving track storage: %w" , err )
488
526
}
489
527
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
-
506
528
p .events .PostStreamResolveStorage (playbackId )
507
529
508
- rawStream , err := audio . NewHttpChunkedReader (log . WithField ( "uri" , spotId . String ()), client , trackUrl )
530
+ rawStream , err := p . httpChunkedReaderFromStorageResolve (log , client , storageResolve )
509
531
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 )
511
533
}
512
534
513
535
p .events .PostStreamInitHttpChunkReader (playbackId , rawStream )
0 commit comments