import threading import time from tkinter import * import platform import sys, subprocess, os import urllib.parse import json try: import vlc except: subprocess.check_call([sys.executable, "-m", "pip", "install", 'python-vlc']) import vlc try: import pafy except: subprocess.check_call([sys.executable, "-m", "pip", "install", 'pafy']) import pafy try: import requests except: subprocess.check_call([sys.executable, "-m", "pip", "install", 'requests']) import requests try: from PyQt5 import QtCore, QtGui, QtWidgets except: subprocess.check_call([sys.executable, "-m", "pip", "install", 'PyQt5']) from PyQt5 import QtCore, QtGui, QtWidgets def cls(): os.system('cls' if os.name == 'nt' else 'clear') instance = vlc.Instance() media = None mediaplayer = instance.media_player_new() is_paused = False timeToSleep = 0 playnext = True newindex = 0 class Ui_MainWindow(QtWidgets.QMainWindow): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(801, 580) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.timeline = QtWidgets.QSlider(self.centralwidget) self.timeline.setGeometry(QtCore.QRect(10, 490, 781, 22)) self.timeline.setPageStep(1) self.timeline.setOrientation(QtCore.Qt.Horizontal) self.timeline.setObjectName("timeline") self.timeline.setMaximum(1000) self.playpausebutton = QtWidgets.QPushButton(self.centralwidget) self.playpausebutton.setEnabled(True) self.playpausebutton.setGeometry(QtCore.QRect(390, 520, 40, 40)) font = QtGui.QFont() font.setKerning(True) self.playpausebutton.setFont(font) self.playpausebutton.setStyleSheet("background-color: rgba(10, 0, 0, 0);\n" "") self.playpausebutton.setText("") self.playpausebutton.setObjectName("playpausebutton") self.playpausePicture = QtWidgets.QLabel(self.centralwidget) self.playpausePicture.setGeometry(QtCore.QRect(390, 520, 40, 40)) self.playpausePicture.setText("") self.playpausePicture.setPixmap(QtGui.QPixmap("resources/MultiMate40x40.png")) self.playpausePicture.setTextInteractionFlags(QtCore.Qt.NoTextInteraction) self.playpausePicture.setObjectName("playpausePicture") self.hardstopbutton = QtWidgets.QPushButton(self.centralwidget) self.hardstopbutton.setEnabled(True) self.hardstopbutton.setGeometry(QtCore.QRect(290, 520, 40, 40)) font = QtGui.QFont() font.setKerning(True) self.hardstopbutton.setFont(font) self.hardstopbutton.setStyleSheet("background-color: rgba(10, 0, 0, 0);\n" "") self.hardstopbutton.setText("") self.hardstopbutton.setObjectName("hardstopbutton") self.hardstopPicture = QtWidgets.QLabel(self.centralwidget) self.hardstopPicture.setGeometry(QtCore.QRect(290, 520, 40, 40)) self.hardstopPicture.setText("") self.hardstopPicture.setPixmap(QtGui.QPixmap("resources/hardstopbutton.png")) self.hardstopPicture.setTextInteractionFlags(QtCore.Qt.NoTextInteraction) self.hardstopPicture.setObjectName("hardstopPicture") self.prevbutton = QtWidgets.QPushButton(self.centralwidget) self.prevbutton.setEnabled(True) self.prevbutton.setGeometry(QtCore.QRect(340, 520, 40, 40)) font = QtGui.QFont() font.setKerning(True) self.prevbutton.setFont(font) self.prevbutton.setStyleSheet("background-color: rgba(10, 0, 0, 0);\n" "") self.prevbutton.setText("") self.prevbutton.setObjectName("prevbutton") self.prevPicture = QtWidgets.QLabel(self.centralwidget) self.prevPicture.setGeometry(QtCore.QRect(340, 520, 40, 40)) self.prevPicture.setText("") self.prevPicture.setPixmap(QtGui.QPixmap("resources/prev.png")) self.prevPicture.setTextInteractionFlags(QtCore.Qt.NoTextInteraction) self.prevPicture.setObjectName("prevPicture") self.nextbutton = QtWidgets.QPushButton(self.centralwidget) self.nextbutton.setEnabled(True) self.nextbutton.setGeometry(QtCore.QRect(440, 520, 40, 40)) font = QtGui.QFont() font.setKerning(True) self.nextbutton.setFont(font) self.nextbutton.setStyleSheet("background-color: rgba(10, 0, 0, 0);\n" "") self.nextbutton.setText("") self.nextbutton.setObjectName("nextbutton") self.nextPicture = QtWidgets.QLabel(self.centralwidget) self.nextPicture.setGeometry(QtCore.QRect(440, 520, 40, 40)) self.nextPicture.setText("") self.nextPicture.setPixmap(QtGui.QPixmap("resources/next.png")) self.nextPicture.setTextInteractionFlags(QtCore.Qt.NoTextInteraction) self.nextPicture.setObjectName("nextPicture") self.hardplaybutton = QtWidgets.QPushButton(self.centralwidget) self.hardplaybutton.setEnabled(True) self.hardplaybutton.setGeometry(QtCore.QRect(490, 520, 40, 40)) font = QtGui.QFont() font.setKerning(True) self.hardplaybutton.setFont(font) self.hardplaybutton.setStyleSheet("background-color: rgba(10, 0, 0, 0);\n" "") self.hardplaybutton.setText("") self.hardplaybutton.setObjectName("hardplaybutton") self.hardplayPicture = QtWidgets.QLabel(self.centralwidget) self.hardplayPicture.setGeometry(QtCore.QRect(490, 520, 40, 40)) self.hardplayPicture.setText("") self.hardplayPicture.setPixmap(QtGui.QPixmap("resources/hardplaybutton.png")) self.hardplayPicture.setTextInteractionFlags(QtCore.Qt.NoTextInteraction) self.hardplayPicture.setObjectName("hardplayPicture") self.speedBox = QtWidgets.QDoubleSpinBox(self.centralwidget) self.speedBox.setGeometry(QtCore.QRect(10, 515, 62, 22)) self.speedBox.setDecimals(1) self.speedBox.setProperty("value", 1.0) self.speedBox.setObjectName("speedBox") self.timenow = QtWidgets.QTextEdit(self.centralwidget) self.timenow.setGeometry(QtCore.QRect(713, 515, 81, 23)) self.timenow.setTextInteractionFlags(QtCore.Qt.NoTextInteraction) self.timenow.setObjectName("timenow") self.speedTextLabel = QtWidgets.QLabel(self.centralwidget) self.speedTextLabel.setGeometry(QtCore.QRect(25, 536, 47, 13)) self.speedTextLabel.setObjectName("speedTextLabel") self.timeTextLabel = QtWidgets.QLabel(self.centralwidget) self.timeTextLabel.setGeometry(QtCore.QRect(740, 536, 47, 13)) self.timeTextLabel.setObjectName("timeTextLabel") self.volumeDial = QtWidgets.QDial(self.centralwidget) self.volumeDial.setGeometry(QtCore.QRect(719, 0, 81, 81)) self.volumeDial.setStyleSheet("") self.volumeDial.setMinimum(1) self.volumeDial.setMaximum(100) self.volumeDial.setPageStep(1) self.volumeDial.setProperty("value", 100) self.volumeDial.setObjectName("volumeDial") self.VolDialBG = QtWidgets.QLabel(self.centralwidget) self.VolDialBG.setGeometry(QtCore.QRect(720, 0, 81, 81)) self.VolDialBG.setText("") self.VolDialBG.setPixmap(QtGui.QPixmap("resources/MultiMate80x80.png")) self.VolDialBG.setObjectName("VolDialBG") self.playlistsComboBox = QtWidgets.QComboBox(self.centralwidget) self.playlistsComboBox.setGeometry(QtCore.QRect(0, 0, 231, 22)) self.playlistsComboBox.setCurrentText("") self.playlistsComboBox.setDuplicatesEnabled(True) self.playlistsComboBox.setObjectName("playlistsComboBox") for playlist in os.listdir(os.getcwd()): self.playlistsComboBox.addItem(playlist) self.nowPlaying = QtWidgets.QTextBrowser(self.centralwidget) self.nowPlaying.setGeometry(QtCore.QRect(10, 460, 781, 23)) self.nowPlaying.setObjectName("nowPlaying") self.openPlaylistButton = QtWidgets.QPushButton(self.centralwidget) self.openPlaylistButton.setGeometry(QtCore.QRect(230, 0, 75, 23)) self.openPlaylistButton.setObjectName("openPlaylistButton") self.songList = QtWidgets.QTextBrowser(self.centralwidget) self.songList.setGeometry(QtCore.QRect(0, 43, 301, 411)) self.songList.setObjectName("songList") self.TextAllSongs = QtWidgets.QTextEdit(self.centralwidget) self.TextAllSongs.setGeometry(QtCore.QRect(0, 20, 301, 23)) self.TextAllSongs.setTextInteractionFlags(QtCore.Qt.NoTextInteraction) self.TextAllSongs.setObjectName("TextAllSongs") self.toFindName = QtWidgets.QTextEdit(self.centralwidget) self.toFindName.setGeometry(QtCore.QRect(310, 0, 331, 23)) self.toFindName.setObjectName("toFindName") self.findSongButton = QtWidgets.QPushButton(self.centralwidget) self.findSongButton.setGeometry(QtCore.QRect(640, 0, 75, 23)) self.findSongButton.setObjectName("findSongButton") self.foundSongs = QtWidgets.QComboBox(self.centralwidget) self.foundSongs.setGeometry(QtCore.QRect(310, 30, 331, 22)) self.foundSongs.setObjectName("foundSongs") self.addThisSongButton = QtWidgets.QPushButton(self.centralwidget) self.addThisSongButton.setGeometry(QtCore.QRect(640, 30, 75, 23)) self.addThisSongButton.setObjectName("addThisSongButton") self.mixButton = QtWidgets.QPushButton(self.centralwidget) self.mixButton.setGeometry(QtCore.QRect(720, 90, 75, 41)) self.mixButton.setObjectName("mixButton") self.settingsButton = QtWidgets.QPushButton(self.centralwidget) self.settingsButton.setGeometry(QtCore.QRect(720, 140, 75, 51)) self.settingsButton.setObjectName("settingsButton") if platform.system() == "Darwin": # for MacOS self.videoframe = QtWidgets.QMacCocoaViewContainer(self.centralwidget) else: self.videoframe = QtWidgets.QFrame(self.centralwidget) self.videoframe.setGeometry(QtCore.QRect(310, 70, 401, 381)) self.videoframe.setObjectName("videoframe") self.timeline.raise_() self.playpausePicture.raise_() self.prevPicture.raise_() self.nextPicture.raise_() self.speedBox.raise_() self.nextbutton.raise_() self.prevbutton.raise_() self.playpausebutton.raise_() self.timenow.raise_() self.speedTextLabel.raise_() self.timeTextLabel.raise_() self.VolDialBG.raise_() self.volumeDial.raise_() self.playlistsComboBox.raise_() self.nowPlaying.raise_() self.openPlaylistButton.raise_() self.songList.raise_() self.TextAllSongs.raise_() self.toFindName.raise_() self.findSongButton.raise_() self.foundSongs.raise_() self.addThisSongButton.raise_() self.mixButton.raise_() self.restartPlayerButton.raise_() self.videoframe.raise_() self.hardplaybutton.raise_() self.hardstopbutton.raise_() MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 801, 21)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) self.timer = QtCore.QTimer(self) self.timer.timeout.connect(self.update_ui) def update_ui(self): global mediaplayer global playnext media_pos = int(mediaplayer.get_position() * 1000) if mediaplayer.get_position() > 0.99: playallpl(newindex) self.timeline.setValue(media_pos) if not mediaplayer.is_playing(): self.timer.stop() def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.speedBox.setPrefix(_translate("MainWindow", "x")) self.speedTextLabel.setText(_translate("MainWindow", "Speed")) self.timeTextLabel.setText(_translate("MainWindow", "Time")) self.nowPlaying.setPlaceholderText(_translate("MainWindow", "Nothing here...")) self.openPlaylistButton.setText(_translate("MainWindow", "Open playlist")) self.songList.setPlaceholderText(_translate("MainWindow", "Nothing here...")) self.TextAllSongs.setHtml(_translate("MainWindow", "\n" "
\n" "Songs in playlist
")) self.findSongButton.setText(_translate("MainWindow", "Find song")) self.addThisSongButton.setText(_translate("MainWindow", "Add this song")) self.mixButton.setText(_translate("MainWindow", "Mix")) self.settingsButton.setText(_translate("MainWindow", "Settings")) class YoutubeSearch: def __init__(self, search_terms: str, max_results=None): self.search_terms = search_terms self.max_results = max_results self.videos = self._search() def _search(self): encoded_search = urllib.parse.quote_plus(self.search_terms) BASE_URL = "https://youtube.com" url = f"{BASE_URL}/search?q={encoded_search}" response = requests.get(url).text while "ytInitialData" not in response: response = requests.get(url).text results = self._parse_html(response) if self.max_results is not None and len(results) > self.max_results: return results[: self.max_results] return results def _parse_html(self, response): results = [] start = ( response.index("ytInitialData") + len("ytInitialData") + 3 ) end = response.index("};", start) + 1 json_str = response[start:end] data = json.loads(json_str) videos = data["contents"]["twoColumnSearchResultsRenderer"]["primaryContents"][ "sectionListRenderer" ]["contents"][0]["itemSectionRenderer"]["contents"] for video in videos: res = {} if "videoRenderer" in video.keys(): video_data = video.get("videoRenderer", {}) res["id"] = video_data.get("videoId", None) res["thumbnails"] = [thumb.get("url", None) for thumb in video_data.get("thumbnail", {}).get("thumbnails", [{}]) ] res["title"] = video_data.get("title", {}).get("runs", [[{}]])[0].get("text", None) res["long_desc"] = video_data.get("descriptionSnippet", {}).get("runs", [{}])[0].get("text", None) res["channel"] = video_data.get("longBylineText", {}).get("runs", [[{}]])[0].get("text", None) res["duration"] = video_data.get("lengthText", {}).get("simpleText", 0) res["views"] = video_data.get("viewCountText", {}).get("simpleText", 0) res["publish_time"] = video_data.get("publishedTimeText", {}).get("simpleText", 0) res["url_suffix"] = video_data.get("navigationEndpoint", {}).get("commandMetadata", {}).get("webCommandMetadata", {}).get("url", None) results.append(res) return results def to_dict(self, clear_cache=True): result = self.videos if clear_cache: self.videos = "" return result def to_json(self, clear_cache=True): result = json.dumps({"videos": self.videos}) if clear_cache: self.videos = "" return result def readpl(plname): playlistfile = open(plname) playlist = json.load(playlistfile) playlistfile.close() return playlist def searchinYT(): global results search = ui.toFindName.toPlainText() results = YoutubeSearch(search, max_results=10).to_dict() for i in range(len(results)): ui.foundSongs.addItem(results[i]["channel"] + ": " + results[i]["title"]) return results results = dict() def addtopl(): global results global playlist whichres = ui.foundSongs.currentIndex() url = "https://www.youtube.com" + results[whichres]["url_suffix"] print(str(len(list(playlist)))) willbesong = {} willbesong['name'] = results[whichres]["title"] willbesong['author'] = results[whichres]["channel"] willbesong['url'] = url playlist[str(len(list(playlist)))] = willbesong playlistfile = open(ui.playlistsComboBox.currentText(), 'w+') json.dump(playlist, playlistfile, indent=3, ensure_ascii=False) playlistfile.close() getplaylist() def set_position(): global instance global media global mediaplayer global is_paused ui.timer.stop() pos = ui.timeline.value() mediaplayer.set_position(pos / 1000.0) ui.timer.start(100) def playmusic(url, name, author): video = pafy.new(url) best = video.getbest() playurl = best.url global instance global media global mediaplayer global is_paused global timeToSleep global playnext playnext = False media = instance.media_new(playurl) mediaplayer.set_media(media) if platform.system() == "Linux": # for Linux using the X Server mediaplayer.set_xwindow(int(ui.videoframe.winId())) elif platform.system() == "Windows": # for Windows mediaplayer.set_hwnd(int(ui.videoframe.winId())) elif platform.system() == "Darwin": # for MacOS mediaplayer.set_nsobject(int(ui.videoframe.winId())) if mediaplayer.is_playing(): mediaplayer.pause() is_paused = True ui.timer.stop() else: mediaplayer.play() ui.timer.start(100) is_paused = False mediaplayer.audio_set_volume(100) time.sleep(0.5) timeToSleep = mediaplayer.get_length() / 1000 cls() print("Playing " + author + " - " + name) app = QtWidgets.QApplication(sys.argv) MainWindow = QtWidgets.QMainWindow() ui = Ui_MainWindow() ui.setupUi(MainWindow) playlist = {} def getplaylist(): global playlist global newindex newindex = 0 playlist = readpl(ui.playlistsComboBox.currentText()) ui.songList.clear() for item in list(playlist): ui.songList.append(str(playlist[item]['author'] + " - " + playlist[item]['name'])) # addtopl(playlist, 'play.list') def playallpl(index=0): global newindex listplaylist = list(playlist) item = listplaylist[index] playmusic(playlist[item]['url'], playlist[item]['name'], playlist[item]['author']) newindex += 1 def playnextsong(): global newindex playallpl(newindex) def playprevsong(): global newindex newindex -= 2 playallpl(newindex) def stopandclear(): mediaplayer.set_media(None) def playpause(): global is_paused if mediaplayer.is_playing(): mediaplayer.pause() is_paused = True ui.timer.stop() else: mediaplayer.play() ui.timer.start(100) is_paused = False def changevolume(): mediaplayer.audio_set_volume(ui.volumeDial.value()) def addtofoundsongs(): ui.toFindName.toPlainText() MainWindow.show() ui.openPlaylistButton.clicked.connect(getplaylist) ui.hardplaybutton.clicked.connect(playallpl) ui.timeline.sliderMoved.connect(set_position) ui.timeline.sliderPressed.connect(set_position) ui.nextbutton.clicked.connect(playnextsong) ui.prevbutton.clicked.connect(playprevsong) ui.hardstopbutton.clicked.connect(stopandclear) ui.playpausebutton.clicked.connect(playpause) ui.volumeDial.valueChanged.connect(changevolume) ui.findSongButton.clicked.connect(searchinYT) ui.addThisSongButton.clicked.connect(addtopl) sys.exit(app.exec_())