We have added a lot of functions to the previously created "Automatically display the lyrics of the song being played on iTunes in Python".
--Supports song skipping --Speed up display --App control --Automatic scrolling --Improved lyrics search accuracy
Once the lyrics page of a song was opened, the page was displayed until the end of that song, but if you skip to the next song, the lyrics will also display the next song.
Change before
while True:
start = time.time() # delete
# ~~~~~~~~
time.sleep(music_time - (time.time() - start)) # delete
After change
prev_track_name = "" # add
while True:
#Song name, album name, artist name, song length being played
name = music.current_track.name.get()
artist = music.current_track.artist.get()
album = music.current_track.album.get()
music_time = music.current_track.time.get() # m:s str
# add-start
if name == prev_track_name:
time.sleep(1)
continue
prev_track_name = name
# add-end
# ~~~~~~~~
time.sleep(1) # add
I set a timeout because it took a long time to display the lyrics page.
After change
driver = webdriver.Chrome(executable_path="chromedriver")
driver.get("https://www.google.com/") #Initial tab
driver.set_page_load_timeout(5) #Maximum read wait time (5 seconds in this case)# add
The lyrics themselves can be read in 5 seconds, but other images will take a long time to load the page, so it will be forcibly terminated after 5 seconds. By the way, "Scroll to the position of the lyrics" was also changed to find the position of the lyrics and scroll to that position.
Change before
while True:
# ~~~~~~~~
try:
# ~~~~~~~~
#Open in new tab
driver.execute_script("window.open()")
driver.switch_to.window(driver.window_handles[1])
driver.get("https://www.uta-net.com/" + name_url)
driver.execute_script("window.scrollTo(0, 380);") #Scroll to the position of the lyrics
#Close previous tab
driver.switch_to.window(driver.window_handles[0])
driver.close()
driver.switch_to.window(driver.window_handles[0])
After change
while True:
# ~~~~~~~~
try:
# ~~~~~~~~
#Open in new tab
driver.execute_script("window.open()")
driver.switch_to.window(driver.window_handles[1])
# add-start
try:
driver.get("https://www.uta-net.com/" + name_url)
except:
pass
#Scroll to the position of the lyrics
driver.execute_script("arguments[0].scrollIntoView();", driver.find_element_by_id("view_kashi"))
# add-end
#Close previous tab
driver.switch_to.window(driver.window_handles[0])
driver.close()
driver.switch_to.window(driver.window_handles[0])
It's almost a bonus, but I made it possible to control "playback" and "to the next song" even on the terminal. First is the basic operation.
basic operation
music = appscript.app("Music")
#Regeneration
music.play()
#pause
music.pause()
#Play / Pause
music.playpause()
#To the previous track
music.previous_track()
#To the next track
music.next_track()
Use this as it is. Also, with normal ʻinput ()`, it is not possible to wait until input is made and perform other processing, so I used input with a timeout.
Input with timeout
from select import select
import sys
#The arguments are "read", "write", "exception", and "waiting time" in order, and this time only read is used.
#Wait time is 0.Specified as 5 seconds
# 0.If there is no input after 5 seconds, an empty list is returned
read, _, _ = select([sys.stdin], [], [], 0.5)
if read:
command = sys.stdin.readline().strip()
else:
command = ""
I will put the above in the code as it is.
After change
while True:
#Access the Music app
music = appscript.app("Music")
# add-start
# ----App control----
#Input with timeout
read, _, _ = select([sys.stdin], [], [], 0.5)
if read:
command = sys.stdin.readline().strip()
else:
command = ""
if command == "b": #To the previous track
music.previous_track()
elif command == "p": #Play / Pause
music.playpause()
elif command == "n": #To the next track
music.next_track()
# add-end
# ~~~~~~~~
Since the entire lyrics may not be displayed, the lyrics are automatically scrolled.
After change
while True:
# ~~~~~~~~
if name == prev_track_name:
time.sleep(1)
# add-start
count += 1
if count % 5 == 0:
driver.execute_script(
"window.scrollTo(window.pageXOffset, window.pageYOffset + " + str(kashi_length // music_time * 5) + ");"
)
# add-end
continue
# ~~~~~~~~
#Open in new tab
driver.execute_script("window.open()")
driver.switch_to.window(driver.window_handles[1])
try:
driver.get("https://www.uta-net.com/" + name_url)
except:
pass
#Scroll to the position of the lyrics
driver.execute_script("arguments[0].scrollIntoView();", driver.find_element_by_id("view_kashi"))
# add-start
#The length of the lyrics part on the page
kashi_length = driver.find_element_by_id("view_mylink").location["y"] - \
driver.find_element_by_id("view_kashi").location["y"]
# add-end
#Close previous tab
driver.switch_to.window(driver.window_handles[0])
driver.close()
driver.switch_to.window(driver.window_handles[0])
Get the length of the lyrics part in the page (lyric length / song length) * 5 Scroll down every 5 seconds to scroll at a reasonable pace.
First, convert the full-width alphabet to half-width. Also, when searching, "exact match" was changed to "contains".
After change
while True:
# ~~~~~~~~
# ----Access the lyrics site----
#Full-width to half-width# add
name = str(name).translate(str.maketrans({chr(0xFF01 + i): chr(0x21 + i) for i in range(94)}))
name = parse.quote(name) #Percent encoding
url = "https://www.uta-net.com/search/?Aselect=2&Keyword=" + name + "&Bselect=3&x=0&y=0" # Bselect=4 to Bselect=To 3
In addition, the position of the singer's name may shift due to the influence of the crown mark on the page with a lot of access, so this has been fixed.
After change
while True:
# ~~~~~~~~
try:
# ~~~~~~~~
name_url = ""
flag = False
for tag_tr in tr:
a = tag_tr.find_all("a")
for i, tag_a in enumerate(a):
if i == 0: #Song title
name_url = tag_a.get("href")
elif i == 1 or i == 2: #Singer name#Add 2 where there was only 1
if tag_a.string == artist:
flag = True
break
if flag:
break
import time
import sys
from select import select
import appscript
from urllib import request, parse
from bs4 import BeautifulSoup
from selenium import webdriver
driver = webdriver.Chrome(executable_path="chromedriver")
driver.get("https://www.google.com/") #Initial tab
driver.set_page_load_timeout(5) #It can be shorter depending on the speed of the line
music_time = 0
prev_track_name = ""
count = 0
kashi_length = 0
while True:
#Access the Music app
music = appscript.app("Music")
# ----App control----
#Input with timeout
read, _, _ = select([sys.stdin], [], [], 0.5)
if read:
command = sys.stdin.readline().strip()
else:
command = ""
if command == "b": #To the previous track
music.previous_track()
elif command == "p": #Play / Pause
music.playpause()
elif command == "n": #To the next track
music.next_track()
# ----Get song title----
#Song name, album name, artist name, song length being played
name = music.current_track.name.get()
artist = music.current_track.artist.get()
album = music.current_track.album.get()
music_time = music.current_track.time.get() # m:s str
# music_time to seconds
music_time = music_time.split(":")
music_time = int(music_time[0]) * 60 + int(music_time[1])
if name == prev_track_name:
time.sleep(1)
count += 1
if count % 5 == 0:
driver.execute_script(
"window.scrollTo(window.pageXOffset, window.pageYOffset + " + str(kashi_length // music_time * 5) + ");"
)
continue
prev_track_name = name
print("{} / {} / {}".format(name, artist, album))
# ----Access the lyrics site----
#Full-width to half-width
name = str(name).translate(str.maketrans({chr(0xFF01 + i): chr(0x21 + i) for i in range(94)}))
name = parse.quote(name) #Percent encoding
url = "https://www.uta-net.com/search/?Aselect=2&Keyword=" + name + "&Bselect=3&x=0&y=0"
try:
html = request.urlopen(url)
soup = BeautifulSoup(html, "html.parser")
tr = soup.find_all("tr")
name_url = ""
flag = False
for tag_tr in tr:
a = tag_tr.find_all("a")
for i, tag_a in enumerate(a):
if i == 0: #Song title
name_url = tag_a.get("href")
elif i == 1 or i == 2: #Singer name
if tag_a.string == artist:
flag = True
break
if flag:
break
#Open in new tab
driver.execute_script("window.open()")
driver.switch_to.window(driver.window_handles[1])
try:
driver.get("https://www.uta-net.com/" + name_url)
except:
pass
#Scroll to the position of the lyrics
driver.execute_script("arguments[0].scrollIntoView();", driver.find_element_by_id("view_kashi"))
kashi_length = driver.find_element_by_id("view_mylink").location["y"] - \
driver.find_element_by_id("view_kashi").location["y"]
#Close previous tab
driver.switch_to.window(driver.window_handles[0])
driver.close()
driver.switch_to.window(driver.window_handles[0])
except:
pass
print("b:Before| p:Play / Pause| n:Next")
print()
time.sleep(1)
Recommended Posts