Skip to content

Commit

Permalink
load playlist
Browse files Browse the repository at this point in the history
You can load playlist songs
  • Loading branch information
fluffy-melli committed Nov 18, 2024
1 parent bd3eace commit d96d223
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 6 deletions.
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ chardet == 5.2.0
pytubefix == 7.1rc2
pyvidplayer2 == 0.9.24
opencv-python == 4.6.0.66
moviepy == 1.0.3
moviepy == 1.0.3
yt_dlp == 2024.8.6
3 changes: 3 additions & 0 deletions setting.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"volume": 10
}
14 changes: 13 additions & 1 deletion src/down/download.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import os,pygame,shutil
import os,pygame,shutil,yt_dlp
from pytubefix import YouTube,Search
from pytubefix.cli import on_progress
####################################
Expand Down Expand Up @@ -34,6 +34,18 @@ def search(q:str,result:int):
list = Search(query=q)
return list.videos

def get_playlist_video(playlist_url):
ydl_opts = {
'extract_flat': True,
'force_generic_extractor': True,
}
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
result = ydl.extract_info(playlist_url, download=False)
if 'entries' in result:
return [entry['url'] for entry in result['entries']]
else:
return []

def search_infos(videos):
res = []
for video in videos:
Expand Down
34 changes: 32 additions & 2 deletions src/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ class VideoState:
def is_url(url: str) -> bool:
match = re.search(src.win.setting.SEARCH_PATTERN, url)
return bool(match)
def is_playlist(url: str) -> bool:
match = re.search(src.win.setting.PLAYLIST_SEARCH_PATTERN, url)
return bool(match)

def frame_to_ascii(frame, width=100):
"""
Expand Down Expand Up @@ -83,7 +86,7 @@ def handle_key_event(key: str) -> None:
"""
if not key:
return

if key == "r":
src.win.screen.vid.restart()
state.msg_text = "Restarted"
Expand All @@ -99,7 +102,7 @@ def handle_key_event(key: str) -> None:
elif key in ["up", "down"]:
volume_delta = 10 if key == "up" else -10
if 0 <= src.win.setting.volume + volume_delta <= 100:
src.win.setting.volume += volume_delta
src.win.setting.change_setting_data('volume',src.win.setting.volume + volume_delta)
src.win.screen.vid.set_volume(src.win.setting.volume/100)
state.msg_text = f"Volume: {src.win.setting.volume}%"
elif key in ["right", "left"]:
Expand Down Expand Up @@ -290,6 +293,33 @@ def wait():
src.win.screen.win.blit(text_surface, text_rect)
pygame.display.update()
if key == "enter" or key == "return":
# TEST URL 'https://youtube.com/playlist?list=PLWe0uF1Zfq3K4ao8lvh2fM3NDqBAxhdaZ&si=JO4TZBYAokbwWzHe'
if is_playlist(state.search):
video_urls = download.get_playlist_video(state.search)
src.win.setting.video_list.extend(video_urls)
trys = 0
while len(src.win.setting.video_list) != 0:
try:
run(src.win.setting.video_list[0])
src.win.setting.video_list.remove(src.win.setting.video_list[0])
except Exception as e:
if src.win.screen.vid == None:
src.win.screen.reset((state.search_width, state.search_height))
else:
src.win.screen.reset((src.win.screen.vid.current_size[0],src.win.screen.vid.current_size[1]+5), vid=True)
if trys >= 10:
print("fail")
break
print(f"An error occurred during playback. Trying again... ({trys}/10) > \n{e}")
text_surface = src.win.screen.font.render(f"An error occurred during playback. Trying again... ({trys}/10) >", True, (255,255,255))
text_surface_2 = src.win.screen.font.render(f"{e}", True, (255,255,255))
text_rect = text_surface.get_rect(center=(src.win.screen.win.get_size()[0]/2,src.win.screen.win.get_size()[1]/2))
text_rect_2 = text_surface_2.get_rect(center=(src.win.screen.win.get_size()[0]/2,src.win.screen.win.get_size()[1]/2+30))
src.win.screen.win.blit(text_surface, text_rect)
src.win.screen.win.blit(text_surface_2, text_rect_2)
pygame.display.flip()
time.sleep(0.5)
trys += 1
if is_url(state.search):
a = state.search
state.search = ""
Expand Down
19 changes: 19 additions & 0 deletions src/utils/json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import json

def read(file_path):
"""read json file"""
try:
with open(file_path, 'r', encoding='utf-8') as file:
return json.load(file)
except FileNotFoundError:
return None
except json.JSONDecodeError:
return None

def write(file_path, data):
"""write json file"""
try:
with open(file_path, 'w', encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=4)
except Exception as e:
print(f"Error: 파일 저장 중 오류가 발생했습니다. {e}")
26 changes: 24 additions & 2 deletions src/win/setting.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
volume = 10
import src.utils.json as json
json_file_path = "./setting.json"
def init_file():
data = {}
data['volume'] = 10
return data
def change_setting_data(key:str,value):
data = json.read(json_file_path)
if data == None:
data = init_file()
data[key] = value
json.write(json_file_path,data)
reload_setting_file()
def reload_setting_file():
global volume
data = json.read(json_file_path)
if data == None:
data = init_file()
json.write(json_file_path,data)
volume = data['volume']
volume = None
loop = False
video_list = []
SEARCH_PATTERN = r"(?:v=|\/)([0-9A-Za-z_-]{11}).*"
PLAYLIST_SEARCH_PATTERN = r"(?:list=)([A-Za-z0-9_-]{34})"
MESSAGE_DISPLAY_TIME = 2.0
ASCII_CHARS = ["$", "@", "B", "%", "8", "&", "W", "M", "#", "*", "o", "a", "h", "k", "b", "d",
"p", "q", "w", "m", "Z", "O", "0", "Q", "L", "C", "J", "U", "Y", "X", "z", "c",
"v", "u", "n", "x", "r", "j", "f", "t", "/", "\\", "|", "(", ")", "1", "{", "}",
"[", "]", "?", "-", "_", "+", "~", "<", ">", "i", "!", "l", "I", ";", ":", ",",
"\"", "^", "`", "'", ".", " "]
"\"", "^", "`", "'", ".", " "]
reload_setting_file()

0 comments on commit d96d223

Please sign in to comment.