Skip to content
This repository was archived by the owner on Jun 21, 2022. It is now read-only.

Commit b827d92

Browse files
committed
[v2.2] Updated sink recognition due to the replacement of PulseAudio with Pipewire in KDE + more detailed interface
1 parent 731d3ba commit b827d92

2 files changed

Lines changed: 30 additions & 27 deletions

File tree

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
## Dependencies
1212

1313
- Python 3.6 or higher
14-
- any Linux distribution with PulseAudio as its sound server
14+
- any Linux distribution with Pipewire & PulseAudio as its sound server
1515
- git, ffmpeg and pip
1616

1717

@@ -40,7 +40,7 @@
4040

4141
## Usage
4242

43-
1. Run LSD with "`python3 lsd.py`"
43+
1. Run LSD with `python3 lsd.py`
4444
2. Enter the path to your output directory. (If you always want to export to the same folder, you can also enter the path in the configuration section of "*lsd.py*")
4545
3. Open the Spotify Application and wait a few seconds until LSD has initialized the recording interface using PulseAudio
4646
4. Now you can play a playlist, audiobook, podcast or individual tracks. Everything is recorded and then separated and tagged fully automatically.
@@ -51,4 +51,4 @@
5151

5252
## License
5353

54-
Fastr is under the terms of the [Apapche 2.0 license](https://www.apache.org/licenses/LICENSE-2.0), following all clarifications stated in the [license file](https://raw.githubusercontent.com/DevEmperor/LSD/master/LICENSE)
54+
LSD is under the terms of the [Apapche 2.0 license](https://www.apache.org/licenses/LICENSE-2.0), following all clarifications stated in the [license file](https://raw.githubusercontent.com/DevEmperor/LSD/master/LICENSE)

lsd.py

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
# main-function
3232
if __name__ == '__main__':
3333
# verify that the Pulseaudio and the parec-command is installed on this system
34-
if subprocess.Popen("parec --help && pacmd --help", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, shell=True).wait() != 0:
35-
exit("{} This script needs a Linux system with Pulseaudio installed (e.g. KDE) to record tracks.".format(ERROR))
34+
if subprocess.Popen("parec --help && pw-cli --help", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, shell=True).wait() != 0:
35+
exit("{} This script needs a Linux system with Pipewire & Pulseaudio installed (e.g. KDE) to record tracks.".format(ERROR))
3636

3737
# always check for ctrl+c
3838
try:
@@ -47,15 +47,16 @@
4747
gap + f"██{RED}{RST} {YELLOW}╚════{RST}██{YELLOW}{RST} ██{GREEN}{RST} ██{GREEN}{RST}" +
4848
gap + f"███████{RED}{RST} ███████{YELLOW}{RST} ██████{GREEN}╔╝{RST}" +
4949
gap + f"{RED}╚══════╝{RST} {YELLOW}╚══════╝{RST} {GREEN}╚═════╝{RST}" +
50-
"\n" + " " * (T_WIDTH // 2 - 14) + " Linux-Spotify-Downloader 2.1" +
50+
"\n" + " " * (T_WIDTH // 2 - 14) + " Linux-Spotify-Downloader 2.2" +
5151
gap + " developed by Jannis Zahn")
5252

5353
# specify the output-directory
5454
print("\n" + "---- CONFIGURATION " + "-" * (T_WIDTH - 19) + "\n")
5555
if not os.path.isdir(OUTPUT_DIR):
5656
while True:
5757
OUTPUT_DIR = input("{} Please specify an existing and writable output-directory: ".format(REQUEST))
58-
if os.path.isdir(OUTPUT_DIR): break
58+
if os.path.isdir(OUTPUT_DIR):
59+
break
5960
OUTPUT_DIR = os.path.abspath(OUTPUT_DIR)
6061
print("{} Output-Directory: {}".format(INFO, OUTPUT_DIR))
6162

@@ -74,39 +75,40 @@
7475
print("\r{} OK, I have found a running Spotify-Application".format(INFO))
7576

7677
# find spotify-input-sink and create monitor to record from
77-
print("{} I have to play a track to create a new recording interface ...".format(INFO), end="", flush=True)
78+
print("{} I have to play a track to create a new recording interface ...".format(INFO))
7879
methods_if.Play()
79-
time.sleep(3)
80+
time.sleep(1)
8081
while True:
81-
sink_inputs = subprocess.run(["pacmd", "list-sink-inputs"], stdout=subprocess.PIPE).stdout.decode()
82-
if "application.name = \"Spotify\"" in sink_inputs: break
82+
sink_inputs = subprocess.run("pw-cli ls Node".split(), stdout=subprocess.PIPE).stdout.decode()
83+
if "application.name = \"spotify\"" in sink_inputs:
84+
break
8385
time.sleep(1)
8486
methods_if.Pause()
8587
time.sleep(0.5)
86-
sink_index = sink_inputs.split("application.name = \"Spotify\"")[0].split("index: ")[-1].split("\n")[0]
87-
if subprocess.Popen(f"pactl load-module module-null-sink sink_name=lsd && pactl move-sink-input {sink_index} "
88-
f"lsd", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, shell=True).wait() == 0:
89-
print("\r{} I have successfully created the recording interface to record from Spotify only.\n".format(INFO)
90-
+ "{} I will now listen for tracks to be played ... Please close Spotify as soon as you finished "
91-
"playing all songs!{}".format(BOLD, RST))
88+
sink_index = sink_inputs.split("application.name = \"spotify\"")[0].split("\tid ")[-1].split(",")[0]
89+
if subprocess.Popen("pactl load-module module-null-sink sink_name=lsd && pactl move-sink-input {} lsd".format(sink_index),
90+
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, shell=True).wait() == 0:
91+
print("{}{} I will now listen for tracks to be played ..."
92+
"Please close Spotify as soon as you finished playing all songs!{}".format(INFO, BOLD, RST))
9293
else:
9394
exit("\r{} Error while creating the recording device for Spotify.".format(ERROR))
9495

9596
# start the recording with parec (PulseAudio-Recording)
9697
print("\n" + "---- RECORDING " + "-" * (T_WIDTH - 15) + "\n")
97-
recording_process = subprocess.Popen(f"parec -d lsd.monitor --file-format=wav".split() + [OUTPUT_DIR + "/.temp.wav"])
98+
recording_process = subprocess.Popen("parec -d lsd.monitor --file-format=wav".split() + [OUTPUT_DIR + "/.temp.wav"])
9899

99100
# initialize some variables
100101
last_url = ""
101102
counter = 0
102103
tracks = []
103104
ad = False
104105

105-
# wait until first song starts (to make it possible to record also the current song)
106-
while prop_if.Get("org.mpris.MediaPlayer2.Player", "PlaybackStatus") != "Playing": time.sleep(0.01)
107-
108106
# continue reading dbus-properties until Spotify gets closed
109107
try:
108+
# wait until first song starts (to make it possible to record also the current song)
109+
while prop_if.Get("org.mpris.MediaPlayer2.Player", "PlaybackStatus") != "Playing":
110+
time.sleep(0.01)
111+
110112
while True:
111113
# get all meta-information about the current track
112114
meta = prop_if.Get("org.mpris.MediaPlayer2.Player", "Metadata")
@@ -125,7 +127,7 @@
125127

126128
except dbus.exceptions.DBusException: # means that Spotify is closed, because there is no bus any more
127129
recording_process.terminate() # stop the recording
128-
subprocess.Popen(["pulseaudio", "-k"]) # restore original pulseaudio-configuration
130+
subprocess.Popen("systemctl --user restart pipewire pipewire-pulse".split()) # restore original pulseaudio-configuration
129131
print("{} I have recorded {} track(s).".format(INFO, counter))
130132

131133
if counter > 0:
@@ -149,9 +151,9 @@
149151
for idx, audio in enumerate(chunks):
150152
if audio.duration_seconds >= 40:
151153
song = sp.track(tracks[idx - skipped])
152-
print("\r{} Converting and tagging \"{}\" ...".format(INFO, song["name"]) + " " * (T_WIDTH - 33 - len(song["name"])), end="", flush=True)
154+
print("{} Converting and tagging \"{}\" ...".format(INFO, song["name"]))
153155

154-
if genius.access_token == "Bearer asd":
156+
if genius.access_token.startswith("Bearer"):
155157
genius_song = genius.search_song(song["name"], song["artists"][0]["name"])
156158
if genius_song is not None:
157159
lyrics = genius_song.lyrics
@@ -177,12 +179,13 @@
177179

178180
audio.export(OUTPUT_DIR + "/" + song["name"].replace("-", "~").replace("/", "~")
179181
.replace("|", "~") + ".mp3", format="mp3", bitrate="192k", tags=tags, cover=OUTPUT_DIR + "/.cover.jpg")
180-
else: skipped += 1
182+
else:
183+
skipped += 1
181184
os.remove(OUTPUT_DIR + "/.temp.mp3") # remove all temporary files
182185
os.remove(OUTPUT_DIR + "/.cover.jpg")
183186
os.remove(OUTPUT_DIR + "/.temp.wav")
184-
print("\r{}{} Done!".format(INFO, GREEN) + " " * (T_WIDTH - 9))
187+
print("{}{} Done!".format(INFO, GREEN))
185188

186189
except KeyboardInterrupt:
187-
subprocess.Popen(["pulseaudio", "-k"])
190+
subprocess.Popen("systemctl --user restart pipewire pipewire-pulse".split())
188191
exit("\n{}Detected Ctrl+C (Keyboard-Interrupt) ... Bye! :-)".format(RED))

0 commit comments

Comments
 (0)