Skip to content

Commit

Permalink
Fake the UserAgent: Spotify has started blocking lyric requests from …
Browse files Browse the repository at this point in the history
…my app 🤣 + reset PersistentID and SpotifyID vars on song end (we only ever reach this on Apple Music) (necessary for songs on repeat in apple music, my fake lyric at the end is not long enough for apple music songs)
  • Loading branch information
aviwad committed Apr 11, 2024
1 parent 58e34a0 commit 682b60f
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
3 changes: 3 additions & 0 deletions SongObject+CoreDataClass.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ public class SongObject: NSManagedObject, Decodable {
self.downloadDate = Date.now
let container = try decoder.container(keyedBy: CodingKeys.self)
if let syncType = try? container.decode(String.self, forKey: .syncType), syncType == "LINE_SYNCED", var lyrics = try? container.decode([LyricLine].self, forKey: .lines) {
// Dummy lyric at the end to keep the timer going past the last lyric, necessary for someone playing a single song on repeat
// Spotify doesn't give playback notifications when it's the same song on repeat
// Apple Music does, but unfortunately has every song slightly longer than it's spotify counterpart so this doesn't help us
if !lyrics.isEmpty {
lyrics.append(LyricLine(startTime: duration-1400, words: "Now Playing: \(title)"))
}
Expand Down
16 changes: 15 additions & 1 deletion SpotifyLyricsInMenubar/viewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ import MediaPlayer
@AppStorage("spDcCookie") var cookie = ""
let decoder = JSONDecoder()

// Fake Spotify User Agent
// Spotify's started blocking my app's useragent. A win honestly 🤣

This comment has been minimized.

Copy link
@miraclx

miraclx Apr 12, 2024

wins 😆

This comment has been minimized.

Copy link
@aviwad

aviwad Apr 12, 2024

Author Owner

❤️ thanks for the comment. do you have any feedback for Lyric Fever?

This comment has been minimized.

Copy link
@miraclx

miraclx Apr 12, 2024

Works great, thanks for building this. Determining the truncation length is sorta trial and error, but I took the time to find the right one for me, moving menu bar items around until I got the best case. Prior to that, it would disappear at intervals and it looked like a glitch, but now it's perfect.

It would be nice if there's some way for the app to auto-detect the available width before hitting limits. Might be tricky, but have you looked into this?

I also noticed the apparent-Spotify block, but you had already fixed it before I could file an issue 💪🏽

Anyway, again.. nice tool, maybe rename the repo so it's more inline with the app name? Aside that, it's perfect. Shared to my friends too

I've wanted this for a long time, for context, before Lyric Fever, on Linux (KDE), I'd spawn a new border-less alacritty window, shrink its dimensions, apply some transparency and pin it to the top of the desktop within which I'd run sptlrx and that worked.. no issues there, but it wasn't a hassle-free solution by any means. And sometimes that overlay would get in the way and I'd have to move it, keeping in mind that it's borderless and a terminal so not easily draggable (gotta remember the right modifier keys).

And since hopping on the macOS train, I've been unable to replicate that.

So this is great.

Paired this up with bartender in it's own dedicated menu item group and now it's collapsible as well so it can take up more of the menu bar when uncollapsed.

CleanShot 2024-04-12 at 20 56 58

This comment has been minimized.

Copy link
@aviwad

aviwad Apr 12, 2024

Author Owner

Yeah, macOS doesn't let you know anything about the menubar's dimensions so I have no way to tell if it's too long or if it's been hidden.

I am also stuck with the current repo name because the Sparkle updater's url has been set to https://aviwad.github.io/SpotifyLyricsInMenubar/appcast.xml and changing the repo name will break the updater for anyone on an older version 😭. Maybe I can set-up a dummy repo with this name, rename this one to LyricFever. Will have to test and try. Curious though, how did you discover this project?

This comment has been minimized.

Copy link
@miraclx

miraclx Apr 12, 2024

Yeah, macOS doesn't let you know anything about the menubar's dimensions so I have no way to tell if it's too long or if it's been hidden.

Yeah, I figured.. I can see Apple being against that.

because the Sparkle updater's url has been set to

ah, bummer.. yeah, a dummy repo should suffice I think

how did you discover this project?

from my browsing history, looks like I searched "macos lyrics hover spotify github" 😄

CleanShot 2024-04-12 at 21 47 13@2x

This comment has been minimized.

Copy link
@aviwad

aviwad Apr 12, 2024

Author Owner

Cool cool. The dummy repo means that all of Google's results are broken now :(

let fakeSpotifyUserAgentconfig = URLSessionConfiguration.default
let fakeSpotifyUserAgentSession: URLSession

init() {
// Load framework
let bundle = CFBundleCreate(kCFAllocatorDefault, NSURL(fileURLWithPath: "/System/Library/PrivateFrameworks/MediaRemote.framework"))
Expand All @@ -62,6 +67,10 @@ import MediaPlayer

updaterController = SPUStandardUpdaterController(startingUpdater: true, updaterDelegate: nil, userDriverDelegate: nil)
coreDataContainer = NSPersistentContainer(name: "Lyrics")

fakeSpotifyUserAgentconfig.httpAdditionalHeaders = ["User-Agent": "Spotify/121000760 Win32/0 (PC laptop)"]
fakeSpotifyUserAgentSession = URLSession(configuration: fakeSpotifyUserAgentconfig)

coreDataContainer.loadPersistentStores { description, error in
if let error = error {
fatalError("Error: \(error.localizedDescription)")
Expand Down Expand Up @@ -91,6 +100,8 @@ import MediaPlayer
// spotifyScript?.nextTrack?()
// we've reached the end of the song, we're past the last lyric
// so we set the timer till the duration of the song, in case the user skips ahead or forward
currentlyPlayingAppleMusicPersistentID = nil
currentlyPlaying = nil
return nil
}
else if currentTime > currentlyPlayingLyrics[currentlyPlayingLyricsIndex].startTimeMS, currentTime < currentlyPlayingLyrics[newIndex].startTimeMS {
Expand Down Expand Up @@ -225,8 +236,11 @@ import MediaPlayer
request.addValue("WebPlayer", forHTTPHeaderField: "app-platform")
print("the access token is \(accessToken.accessToken)")
request.addValue("Bearer \(accessToken.accessToken)", forHTTPHeaderField: "authorization")
let urlResponseAndData = try await URLSession.shared.data(for: request)

let urlResponseAndData = try await fakeSpotifyUserAgentSession.data(for: request)
print(urlResponseAndData)
if urlResponseAndData.0.isEmpty {
print("F")
return []
}
print(String(decoding: urlResponseAndData.0, as: UTF8.self))
Expand Down

0 comments on commit 682b60f

Please sign in to comment.