Primera prueba de gui
This commit is contained in:
parent
d222ca7133
commit
387ea6d91d
Binary file not shown.
After Width: | Height: | Size: 9.6 KiB |
|
@ -0,0 +1,178 @@
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import kivy
|
||||||
|
kivy.require('1.11.1')
|
||||||
|
|
||||||
|
from kivy.app import App
|
||||||
|
from kivy.core.window import Window
|
||||||
|
from kivy.properties import StringProperty, ObjectProperty, ListProperty, BooleanProperty
|
||||||
|
from kivy.uix.boxlayout import BoxLayout
|
||||||
|
from kivy.uix.button import Button
|
||||||
|
from kivy.uix.widget import Widget
|
||||||
|
|
||||||
|
|
||||||
|
class Song(BoxLayout):
|
||||||
|
active = BooleanProperty(False)
|
||||||
|
path = ObjectProperty('')
|
||||||
|
|
||||||
|
def on_path(self, instance, value):
|
||||||
|
self.search_media()
|
||||||
|
|
||||||
|
def search_media(self):
|
||||||
|
self.name = self.path.name
|
||||||
|
self.original = None
|
||||||
|
self.author = None
|
||||||
|
self.video = None
|
||||||
|
self.video_type = None
|
||||||
|
self.vtt = None
|
||||||
|
self.srt = None
|
||||||
|
self.ass = None
|
||||||
|
self.cover = None
|
||||||
|
self.thumbnail = None
|
||||||
|
self.files = []
|
||||||
|
for entry in self.path.iterdir():
|
||||||
|
if entry.name == 'metadata.json':
|
||||||
|
with entry.open('r') as metadatafile:
|
||||||
|
self.metadata = json.load(metadatafile)
|
||||||
|
if 'name' in self.metadata:
|
||||||
|
self.name = self.metadata['name']
|
||||||
|
if 'original' in self.metadata:
|
||||||
|
self.original = self.metadata['original']
|
||||||
|
if 'author' in self.metadata:
|
||||||
|
self.author = self.metadata['author']
|
||||||
|
elif entry.name.endswith('mp4'):
|
||||||
|
self.video = str(entry)
|
||||||
|
self.video_type = 'video/mp4'
|
||||||
|
elif entry.name.endswith('webm'):
|
||||||
|
self.video = str(entry)
|
||||||
|
self.video_type = 'video/webm'
|
||||||
|
elif entry.name.endswith('ogv'):
|
||||||
|
self.video = str(entry)
|
||||||
|
self.video_type = 'video/ogg'
|
||||||
|
elif entry.name.endswith('vtt'):
|
||||||
|
self.vtt = str(entry)
|
||||||
|
elif entry.name == "{}.srt".format(self.path.name):
|
||||||
|
self.srt = str(entry)
|
||||||
|
elif entry.name.endswith('ass'):
|
||||||
|
self.ass = str(entry)
|
||||||
|
elif entry.name == 'thumb.jpg':
|
||||||
|
self.thumbnail = str(entry)
|
||||||
|
elif entry.name.endswith('jpg'):
|
||||||
|
self.cover = str(entry)
|
||||||
|
elif entry.name == 'index.html':
|
||||||
|
continue
|
||||||
|
|
||||||
|
@property
|
||||||
|
def publish(self):
|
||||||
|
return self.video and self.subtitle
|
||||||
|
|
||||||
|
@property
|
||||||
|
def subtitle(self):
|
||||||
|
return self.ass or self.srt or self.vtt
|
||||||
|
|
||||||
|
|
||||||
|
class KaraokeGUI(BoxLayout):
|
||||||
|
active_song = ObjectProperty(None)
|
||||||
|
songs = ListProperty([])
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.keyboard = Window.request_keyboard(
|
||||||
|
self.keyboard_closed,
|
||||||
|
self,
|
||||||
|
'text',
|
||||||
|
)
|
||||||
|
self.keyboard.bind(on_key_down=self.on_key_down)
|
||||||
|
|
||||||
|
def on_key_down(self, keyboard, keycode, text, modifiers):
|
||||||
|
if text == 'a':
|
||||||
|
self.previous()
|
||||||
|
return True
|
||||||
|
elif text == 'd':
|
||||||
|
self.next()
|
||||||
|
return True
|
||||||
|
elif text == 's':
|
||||||
|
self.play()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def keyboard_closed(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def on_songs(self, instance, value):
|
||||||
|
container = self.ids['song_container']
|
||||||
|
container.clear_widgets()
|
||||||
|
for song in self.songs:
|
||||||
|
container.add_widget(song)
|
||||||
|
self.active_song = self.songs[0]
|
||||||
|
|
||||||
|
def on_active_song(self, instance, value):
|
||||||
|
for song in self.songs:
|
||||||
|
song.active = False
|
||||||
|
value.active = True
|
||||||
|
current_song_image = self.ids['current_song_image']
|
||||||
|
current_song_image.source = value.cover
|
||||||
|
|
||||||
|
scrollview = self.ids['songs_scroll']
|
||||||
|
scrollview.scroll_to(value)
|
||||||
|
|
||||||
|
def previous(self):
|
||||||
|
idx = self.songs.index(self.active_song)
|
||||||
|
|
||||||
|
if idx > 0:
|
||||||
|
idx -= 1
|
||||||
|
else:
|
||||||
|
idx = len(self.songs) - 1
|
||||||
|
|
||||||
|
self.active_song = self.songs[idx]
|
||||||
|
|
||||||
|
def next(self):
|
||||||
|
idx = self.songs.index(self.active_song)
|
||||||
|
|
||||||
|
if idx < len(self.songs) - 1:
|
||||||
|
idx += 1
|
||||||
|
else:
|
||||||
|
idx = 0
|
||||||
|
|
||||||
|
self.active_song = self.songs[idx]
|
||||||
|
|
||||||
|
def play(self):
|
||||||
|
subprocess.call([
|
||||||
|
'vlc',
|
||||||
|
'--fullscreen',
|
||||||
|
'--sub-file',
|
||||||
|
self.active_song.subtitle,
|
||||||
|
self.active_song.video,
|
||||||
|
'vlc://quit'
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
class KaraokeApp(App):
|
||||||
|
kv_directory = 'kv_templates'
|
||||||
|
|
||||||
|
def __init__(self, root_folder, **kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.root_folder = root_folder
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
super().build()
|
||||||
|
|
||||||
|
songs = []
|
||||||
|
container = self.root.ids['song_container']
|
||||||
|
for entry in self.root_folder.iterdir():
|
||||||
|
if entry.is_dir():
|
||||||
|
song = Song(
|
||||||
|
path=entry,
|
||||||
|
)
|
||||||
|
if song.publish:
|
||||||
|
songs.append(song)
|
||||||
|
self.root.songs = songs
|
||||||
|
return self.root
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
Window.fullscreen = True
|
||||||
|
KaraokeApp(Path(sys.argv[1])).run()
|
|
@ -0,0 +1,69 @@
|
||||||
|
KaraokeGUI:
|
||||||
|
|
||||||
|
<Song>:
|
||||||
|
size_hint: None, None
|
||||||
|
size: 200, 200
|
||||||
|
orientation: 'vertical'
|
||||||
|
padding: 0
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
canvas.before:
|
||||||
|
Color:
|
||||||
|
rgb: 0.9, 0.9, 0.9 if self.active else 0.3, 0.3, 0.3
|
||||||
|
Line:
|
||||||
|
rectangle: self.pos[0], self.pos[1], self.size[0], self.size[1]
|
||||||
|
|
||||||
|
Image:
|
||||||
|
source: self.parent.thumbnail
|
||||||
|
size_hint: 1, 0.8
|
||||||
|
Label:
|
||||||
|
canvas.before:
|
||||||
|
Color:
|
||||||
|
rgb: 0.3, 0.3, 0.3
|
||||||
|
Rectangle:
|
||||||
|
pos: self.pos
|
||||||
|
size: self.size
|
||||||
|
size_hint: 1, 0.1
|
||||||
|
text: self.parent.name
|
||||||
|
|
||||||
|
<KaraokeGUI>:
|
||||||
|
orientation: 'vertical'
|
||||||
|
Image:
|
||||||
|
id: current_song_image
|
||||||
|
source: ''
|
||||||
|
Button:
|
||||||
|
text: '>'
|
||||||
|
on_press: root.play()
|
||||||
|
size_hint: 1, 0.1
|
||||||
|
|
||||||
|
BoxLayout:
|
||||||
|
orientation: 'horizontal'
|
||||||
|
height: 220
|
||||||
|
size_hint: 1, None
|
||||||
|
|
||||||
|
Button:
|
||||||
|
size_hint: None, None
|
||||||
|
size: 20, 220
|
||||||
|
text: '<'
|
||||||
|
on_press: root.previous()
|
||||||
|
|
||||||
|
ScrollView:
|
||||||
|
id: songs_scroll
|
||||||
|
do_scroll_x: True
|
||||||
|
do_scroll_y: False
|
||||||
|
size_hint: 1, None
|
||||||
|
height: 220
|
||||||
|
|
||||||
|
GridLayout:
|
||||||
|
id: song_container
|
||||||
|
rows: 1
|
||||||
|
width: self.minimum_width
|
||||||
|
padding: 10
|
||||||
|
spacing: 10
|
||||||
|
size_hint: None, 1
|
||||||
|
|
||||||
|
Button:
|
||||||
|
size_hint: None, None
|
||||||
|
size: 20, 220
|
||||||
|
text: '>'
|
||||||
|
on_press: root.next()
|
Reference in New Issue