Two streaming options
This commit is contained in:
17
gui/gui.py
17
gui/gui.py
@@ -14,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
|||||||
class Ui_MainWindow(object):
|
class Ui_MainWindow(object):
|
||||||
def setupUi(self, MainWindow):
|
def setupUi(self, MainWindow):
|
||||||
MainWindow.setObjectName("MainWindow")
|
MainWindow.setObjectName("MainWindow")
|
||||||
MainWindow.resize(815, 500)
|
MainWindow.resize(815, 484)
|
||||||
icon = QtGui.QIcon()
|
icon = QtGui.QIcon()
|
||||||
icon.addPixmap(QtGui.QPixmap(":/img/img/kotopad.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
icon.addPixmap(QtGui.QPixmap(":/img/img/kotopad.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||||
MainWindow.setWindowIcon(icon)
|
MainWindow.setWindowIcon(icon)
|
||||||
@@ -274,7 +274,17 @@ class Ui_MainWindow(object):
|
|||||||
self.use_original_streaming_method_check.setChecked(True)
|
self.use_original_streaming_method_check.setChecked(True)
|
||||||
self.use_original_streaming_method_check.setObjectName("use_original_streaming_method_check")
|
self.use_original_streaming_method_check.setObjectName("use_original_streaming_method_check")
|
||||||
self.audio_devices_settings_tab_lay.addWidget(self.use_original_streaming_method_check)
|
self.audio_devices_settings_tab_lay.addWidget(self.use_original_streaming_method_check)
|
||||||
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
self.use_original_streaming_method_desc = QtWidgets.QLabel(self.audio_devices_settings_tab)
|
||||||
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(self.use_original_streaming_method_desc.sizePolicy().hasHeightForWidth())
|
||||||
|
self.use_original_streaming_method_desc.setSizePolicy(sizePolicy)
|
||||||
|
self.use_original_streaming_method_desc.setMaximumSize(QtCore.QSize(16777215, 33))
|
||||||
|
self.use_original_streaming_method_desc.setWordWrap(True)
|
||||||
|
self.use_original_streaming_method_desc.setObjectName("use_original_streaming_method_desc")
|
||||||
|
self.audio_devices_settings_tab_lay.addWidget(self.use_original_streaming_method_desc, 0, QtCore.Qt.AlignTop)
|
||||||
|
spacerItem = QtWidgets.QSpacerItem(20, 0, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||||
self.audio_devices_settings_tab_lay.addItem(spacerItem)
|
self.audio_devices_settings_tab_lay.addItem(spacerItem)
|
||||||
self.settings_tabs_widget.addTab(self.audio_devices_settings_tab, "")
|
self.settings_tabs_widget.addTab(self.audio_devices_settings_tab, "")
|
||||||
self.general_settings_tab = QtWidgets.QWidget()
|
self.general_settings_tab = QtWidgets.QWidget()
|
||||||
@@ -430,7 +440,8 @@ class Ui_MainWindow(object):
|
|||||||
self.restream_micro_checkbox.setText(_translate("MainWindow", "Restream microphone"))
|
self.restream_micro_checkbox.setText(_translate("MainWindow", "Restream microphone"))
|
||||||
self.input_device_restream_label.setText(_translate("MainWindow", "Input microphone"))
|
self.input_device_restream_label.setText(_translate("MainWindow", "Input microphone"))
|
||||||
self.output_device_restream_label.setText(_translate("MainWindow", "Output device (virtual mic input)"))
|
self.output_device_restream_label.setText(_translate("MainWindow", "Output device (virtual mic input)"))
|
||||||
self.use_original_streaming_method_check.setText(_translate("MainWindow", "Use direct stream method (cuts last second of audio, not recommended if playing short files)"))
|
self.use_original_streaming_method_check.setText(_translate("MainWindow", "Use direct stream method"))
|
||||||
|
self.use_original_streaming_method_desc.setText(_translate("MainWindow", "Direct stream loads faster and doesn\'t lags app on first sound load, it is more reliable method when playing from YouTube or Spotify. If you are trying to play short files and it cuts end of sound, uncheck this box."))
|
||||||
self.settings_tabs_widget.setTabText(self.settings_tabs_widget.indexOf(self.audio_devices_settings_tab), _translate("MainWindow", "Audio"))
|
self.settings_tabs_widget.setTabText(self.settings_tabs_widget.indexOf(self.audio_devices_settings_tab), _translate("MainWindow", "Audio"))
|
||||||
self.theme_label.setText(_translate("MainWindow", " App theme (restart needed)"))
|
self.theme_label.setText(_translate("MainWindow", " App theme (restart needed)"))
|
||||||
self.theme_box.setItemText(0, _translate("MainWindow", "Dark gray"))
|
self.theme_box.setItemText(0, _translate("MainWindow", "Dark gray"))
|
||||||
|
|||||||
30
gui/gui.ui
30
gui/gui.ui
@@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>815</width>
|
<width>815</width>
|
||||||
<height>500</height>
|
<height>484</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -853,22 +853,44 @@ QListWidget:item:selected {
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="use_original_streaming_method_check">
|
<widget class="QCheckBox" name="use_original_streaming_method_check">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Use direct stream method (cuts last second of audio, not recommended if playing short files)</string>
|
<string>Use direct stream method</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checked">
|
<property name="checked">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item alignment="Qt::AlignTop">
|
||||||
|
<widget class="QLabel" name="use_original_streaming_method_desc">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>33</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Direct stream loads faster and doesn't lags app on first sound load, it is more reliable method when playing from YouTube or Spotify. If you are trying to play short files and it cuts end of sound, uncheck this box.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="audio_devices_settings_tab_spacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>20</width>
|
<width>20</width>
|
||||||
<height>40</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
|
|||||||
@@ -40,3 +40,5 @@ def fill_settings(ui: Ui_MainWindow):
|
|||||||
|
|
||||||
ui.spotify_client_id_box.setText(SpotifyConfig.get().client_id)
|
ui.spotify_client_id_box.setText(SpotifyConfig.get().client_id)
|
||||||
ui.spotify_client_secret_box.setText(SpotifyConfig.get().client_secret)
|
ui.spotify_client_secret_box.setText(SpotifyConfig.get().client_secret)
|
||||||
|
|
||||||
|
ui.use_original_streaming_method_check.setChecked(Config.get().direct_stream)
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ def register_handlers(ui: Ui_MainWindow):
|
|||||||
lambda: SpotifyConfig.update("client_secret", ui.spotify_client_secret_box.text())
|
lambda: SpotifyConfig.update("client_secret", ui.spotify_client_secret_box.text())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ui.use_original_streaming_method_check.stateChanged.connect(
|
||||||
|
lambda: Config.update("direct_stream", ui.use_original_streaming_method_check.isChecked())
|
||||||
|
)
|
||||||
|
|
||||||
ui.clear_temp_button.clicked.connect(
|
ui.clear_temp_button.clicked.connect(
|
||||||
lambda: shutil.rmtree('temp', ignore_errors=True)
|
lambda: shutil.rmtree('temp', ignore_errors=True)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,3 +12,4 @@ class ConfigModel:
|
|||||||
in_micro: str
|
in_micro: str
|
||||||
out_micro: str
|
out_micro: str
|
||||||
restream: bool
|
restream: bool
|
||||||
|
direct_stream: bool
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ class Config:
|
|||||||
"preview_device": str(),
|
"preview_device": str(),
|
||||||
"in_micro": str(),
|
"in_micro": str(),
|
||||||
"out_micro": str(),
|
"out_micro": str(),
|
||||||
"restream": False
|
"restream": False,
|
||||||
|
"direct_stream": True
|
||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import pydub
|
import pydub
|
||||||
import validators
|
import validators
|
||||||
from io import BytesIO
|
from modules.config import Config
|
||||||
from rich import print
|
from rich import print
|
||||||
import pafy
|
import pafy
|
||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
from modules.spotify.spotify_dl import Spotify
|
from modules.spotify.spotify_dl import Spotify
|
||||||
from gui.modules.core.popup import popup
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
|
||||||
@@ -15,28 +14,40 @@ def get_raw_link(url):
|
|||||||
if 'spotify' in url:
|
if 'spotify' in url:
|
||||||
url = Spotify().get_youtube_url(url)
|
url = Spotify().get_youtube_url(url)
|
||||||
if 'youtu' in url:
|
if 'youtu' in url:
|
||||||
url = pafy.new(url).audiostreams[0].url
|
url = pafy.new(url).getbestaudio().url
|
||||||
else:
|
|
||||||
url = None
|
|
||||||
|
|
||||||
return url
|
return url
|
||||||
|
|
||||||
|
|
||||||
def get_silenced_media(original: str) -> str | None:
|
def get_ready_media(original: str) -> str | None:
|
||||||
if not os.path.isdir('temp'):
|
if not os.path.isdir('temp'):
|
||||||
os.mkdir('temp')
|
os.mkdir('temp')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
namehash = 'temp\\' + hashlib.md5(original.encode('utf-8')).hexdigest()
|
namehash = 'temp\\' + hashlib.md5(original.encode('utf-8')).hexdigest()
|
||||||
|
if os.path.isfile(namehash):
|
||||||
|
return namehash
|
||||||
|
|
||||||
if not os.path.isfile(original):
|
if not os.path.isfile(original):
|
||||||
if validators.url(original):
|
if validators.url(original):
|
||||||
original = BytesIO(requests.get(get_raw_link(original)).content)
|
if not Config.get().direct_stream:
|
||||||
|
with open('tempsound', 'wb') as f:
|
||||||
|
f.write(requests.get(get_raw_link(original)).content)
|
||||||
|
original = 'tempsound'
|
||||||
|
else:
|
||||||
|
original = get_raw_link(original)
|
||||||
|
|
||||||
|
if Config.get().direct_stream:
|
||||||
|
return original
|
||||||
|
|
||||||
(pydub.AudioSegment.from_file(original) + pydub.AudioSegment.silent(1500))\
|
(pydub.AudioSegment.from_file(original) + pydub.AudioSegment.silent(1500))\
|
||||||
.export(namehash, format='mp3')
|
.export(namehash, format='mp3')
|
||||||
|
|
||||||
|
if os.path.isfile('tempsound'):
|
||||||
|
os.remove('tempsound')
|
||||||
|
|
||||||
return namehash
|
return namehash
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
|
||||||
print(e)
|
print(e)
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import vlc
|
import vlc
|
||||||
from gui.gui import Ui_MainWindow
|
from gui.gui import Ui_MainWindow
|
||||||
from gui.modules.core import popup
|
from gui.modules.core import popup
|
||||||
from modules.player.convert import get_silenced_media
|
from modules.player.convert import get_ready_media
|
||||||
|
|
||||||
|
|
||||||
def get_instance() -> vlc.Instance:
|
def get_instance() -> vlc.Instance:
|
||||||
@@ -36,9 +36,9 @@ class Player(object):
|
|||||||
self.mediaplayer_out)[ui.output_device_play_box.currentText()])
|
self.mediaplayer_out)[ui.output_device_play_box.currentText()])
|
||||||
|
|
||||||
def set_media(self, media: str) -> None:
|
def set_media(self, media: str) -> None:
|
||||||
if get_silenced_media(media):
|
if get_ready_media(media):
|
||||||
self.mediaplayer_preview.set_media(self.instance_preview.media_new(get_silenced_media(media)))
|
self.mediaplayer_preview.set_media(self.instance_preview.media_new(get_ready_media(media)))
|
||||||
self.mediaplayer_out.set_media(self.instance_out.media_new(get_silenced_media(media)))
|
self.mediaplayer_out.set_media(self.instance_out.media_new(get_ready_media(media)))
|
||||||
else:
|
else:
|
||||||
popup.popup('Error', 'Error playing this media. \nIf it uses link, check is this link valid.')
|
popup.popup('Error', 'Error playing this media. \nIf it uses link, check is this link valid.')
|
||||||
self.mediaplayer_preview.set_media(None)
|
self.mediaplayer_preview.set_media(None)
|
||||||
|
|||||||
Reference in New Issue
Block a user