This repository has been archived on 2024-08-27. You can view files and clone it, but cannot push or open issues or pull requests.
negromate_origins/gui/negromate/karaoke/karaoke.py

197 lines
5.5 KiB
Python
Executable File

#!/usr/bin/env python
import json
import os
import subprocess
import sys
from pathlib import Path
import kivy
kivy.require('1.11.1')
from kivy.app import App
from kivy.config import Config
from kivy.core.window import Window
from kivy.properties import StringProperty, ObjectProperty, ListProperty, BooleanProperty
from kivy.resources import resource_add_path
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 == 'cover.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_title = self.ids['current_song_title']
current_song_image.source = value.cover
current_song_title.text = value.name
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 = os.path.join(os.path.dirname(__file__, ), '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)
songs.sort(key=lambda a: a.name.lower())
self.root.songs = songs
return self.root
def main():
if len(sys.argv) == 2:
path = sys.argv[1]
else:
path = '../bideoak/'
# Window.fullscreen = True
resource_add_path(os.path.dirname(__file__))
Config.set('graphics', 'font_name', 'resources/fonts/CyrBit.ttf')
Config.write()
KaraokeApp(Path(path)).run()
if __name__ == '__main__':
main()