From ec3c6a40330b11f08e044a0b9a1250604d3d1bc1 Mon Sep 17 00:00:00 2001 From: noisymime Date: Mon, 3 Dec 2007 13:19:43 +0000 Subject: [PATCH] Huge changes to the video player module. Its currently broken so don't even bother with it. Bling is coming... --- modules/video_player/CoverItem.py | 70 ++++++++++++++ modules/video_player/cover_viewer.py | 91 ++++--------------- modules/video_player/folder_menu.py | 71 +++++++++++++++ modules/video_player/video_player.py | 131 ++++++++++++++++++++------- myth/MythMySQL.py | 9 +- myth/MythMySQL.pyc | Bin 3391 -> 3318 bytes 6 files changed, 257 insertions(+), 115 deletions(-) create mode 100644 modules/video_player/CoverItem.py create mode 100644 modules/video_player/folder_menu.py diff --git a/modules/video_player/CoverItem.py b/modules/video_player/CoverItem.py new file mode 100644 index 0000000..0ef9c2d --- /dev/null +++ b/modules/video_player/CoverItem.py @@ -0,0 +1,70 @@ +import pygtk +import gtk +import pango +import clutter + +class cover_item(clutter.Group): + font = "Lucida Grande " + title_font_size = 30 + main_font_size = 22 + plot_font_size = 18 + + def __init__(self, video, folder_name, cover_size): + clutter.Group.__init__(self) + self.width = cover_size + self.height = cover_size + + #Set whether or not this is a folder or a video cover + if not folder_name is None: + imagePath = "ui/mv_gallery_folder_sel.png" + pixbuf = gtk.gdk.pixbuf_new_from_file(imagePath) + self.isFolder = True + else: + imagePath = video.getCoverfile() + pixbuf = gtk.gdk.pixbuf_new_from_file(imagePath) + self.isFolder = False + self.video = video + + self.main_pic = clutter.Texture() + self.main_pic.set_pixbuf(pixbuf) + self.main_pic.show() + (x, y) = (0, 0) + if self.main_pic.get_height() > self.main_pic.get_width(): + xy_ratio = float(self.main_pic.get_width()) / self.main_pic.get_height() + self.main_pic.set_height(cover_size) + width = int(cover_size * xy_ratio) + self.main_pic.set_width(width) + x = x + (cover_size - width)/2 + else: + xy_ratio = float(self.main_pic.get_height()) / float(self.main_pic.get_width()) + self.main_pic.set_width(cover_size) + height = int(cover_size * xy_ratio) + self.main_pic.set_height(height) + y = y + (cover_size - height)/2 + + self.main_pic.set_position(x, y) + + self.add(self.main_pic) + + #If this is a folder, we also add a title + if not folder_name is None: + self.add_label(folder_name) + + def add_label(self, label): + #Adds a label in the centre of the item + self.title = clutter.Label() + self.title.set_font_name(self.font + str(self.title_font_size)) + self.title.set_color(clutter.color_parse('White')) + self.title.set_text(label) + if self.title.get_width() > self.get_width(): + self.title.set_width(self.get_width()) + + #Add an ellipsis + self.title.set_ellipsize(pango.ELLIPSIZE_END) + #Centre the label + y = (self.height - self.title.get_height())/2 + x = (self.width - self.title.get_width())/2 + self.title.set_position(x, y) + + self.title.show() + self.add(self.title) \ No newline at end of file diff --git a/modules/video_player/cover_viewer.py b/modules/video_player/cover_viewer.py index f0c782f..16939a8 100644 --- a/modules/video_player/cover_viewer.py +++ b/modules/video_player/cover_viewer.py @@ -6,18 +6,17 @@ import gobject import pango import clutter import os +from modules.video_player.CoverItem import cover_item class coverViewer(clutter.Group): scaleFactor = 1.4 inactiveOpacity = 150 - def __init__(self, stage, width, height): + def __init__(self, stage, width, height, rows, columns): clutter.Group.__init__(self) self.stage = stage self.videoLibrary = [] - #self.VidLibrary_byName = [] - #self.VidLibrary_byGenre = [] self.textureLibrary = [] self.folderLibrary = [] self.current_video_details = video_details_group(width) @@ -26,9 +25,9 @@ class coverViewer(clutter.Group): self.cover_gap = 1 - self.num_visible_rows = 3 - self.num_columns = 4 - self.cover_size = int(width / self.num_columns) #200 #A cover will be cover_size * cover_size (X * Y) + self.num_visible_rows = rows + self.num_columns = columns + self.cover_size = int(width / self.num_columns) #A cover will be cover_size * cover_size (X * Y) #Setup the current min and max viewable rows self.min_visible_rows = 0 @@ -140,7 +139,10 @@ class coverViewer(clutter.Group): def select_first(self): self.timeline = clutter.Timeline(20,80) - self.current_video_details.set_video(self.videoLibrary[0], self.timeline) + if not len(self.folderLibrary) == 0: + pass + else: + self.current_video_details.set_video(self.videoLibrary[0], self.timeline) incomingItem = 0 @@ -223,8 +225,14 @@ class coverViewer(clutter.Group): self.covers_group.add(self.textureLibrary[i]) self.textureLibrary[i].show() - def get_current_video(self): - return self.videoLibrary[self.currentSelection] + def get_current_item(self): + return self.textureLibrary[self.currentSelection] + #If the current item # is greater than the number of folders, we have a video + if self.currentSelection >= len(self.folderLibrary): + selection = self.currentSelection - len(self.folderLibrary) + return self.videoLibrary[selection] + else: + return self.folderLibrary[self.currentSelection] def on_key_press_event(self, event): newItem = None @@ -252,71 +260,6 @@ class coverViewer(clutter.Group): #If there is movement, make the scale happen if not newItem == None: self.select_item(newItem, self.currentSelection) - -class cover_item(clutter.Group): - font = "Lucida Grande " - title_font_size = 30 - main_font_size = 22 - plot_font_size = 18 - - def __init__(self, video, folder_name, cover_size): - clutter.Group.__init__(self) - self.width = cover_size - self.height = cover_size - - #Set whether or not this is a folder or a video cover - if not folder_name is None: - imagePath = "ui/mv_gallery_folder_sel.png" - pixbuf = gtk.gdk.pixbuf_new_from_file(imagePath) - self.isFolder = True - else: - imagePath = video.getCoverfile() - pixbuf = gtk.gdk.pixbuf_new_from_file(imagePath) - self.isFolder = False - - self.main_pic = clutter.Texture() - self.main_pic.set_pixbuf(pixbuf) - self.main_pic.show() - (x, y) = (0, 0) - if self.main_pic.get_height() > self.main_pic.get_width(): - xy_ratio = float(self.main_pic.get_width()) / self.main_pic.get_height() - self.main_pic.set_height(cover_size) - width = int(cover_size * xy_ratio) - self.main_pic.set_width(width) - x = x + (cover_size - width)/2 - else: - xy_ratio = float(self.main_pic.get_height()) / float(self.main_pic.get_width()) - self.main_pic.set_width(cover_size) - height = int(cover_size * xy_ratio) - self.main_pic.set_height(height) - y = y + (cover_size - height)/2 - - self.main_pic.set_position(x, y) - - self.add(self.main_pic) - - #If this is a folder, we also add a title - if not folder_name is None: - self.add_label(folder_name) - - def add_label(self, label): - #Adds a label in the centre of the item - self.title = clutter.Label() - self.title.set_font_name(self.font + str(self.title_font_size)) - self.title.set_color(clutter.color_parse('White')) - self.title.set_text(label) - if self.title.get_width() > self.get_width(): - self.title.set_width(self.get_width()) - - #Add an ellipsis - self.title.set_ellipsize(pango.ELLIPSIZE_END) - #Centre the label - y = (self.height - self.title.get_height())/2 - x = (self.width - self.title.get_width())/2 - self.title.set_position(x, y) - - self.title.show() - self.add(self.title) class video_details_group(clutter.Group): font = "Lucida Grande " diff --git a/modules/video_player/folder_menu.py b/modules/video_player/folder_menu.py new file mode 100644 index 0000000..6967eae --- /dev/null +++ b/modules/video_player/folder_menu.py @@ -0,0 +1,71 @@ +import pygtk +import gtk +import pygst +import gst +import gobject +import pango +import clutter +import os +from modules.video_player.CoverItem import cover_item + +class folderMenu(clutter.Group): + scaleFactor = 1.4 + inactiveOpacity = 150 + + def __init__(self, stage, rows, item_size): + clutter.Group.__init__(self) + self.max_rows = rows + self.item_size = item_size + self.currentItemNo = None + + self.folderLibrary = [] + self.viewerLibrary = [] + + def add_base_dir(self, folderName, cover_viewer): + tempItem = cover_item(None, folderName, self.item_size) + rows = len(self.folderLibrary) + x = 0 #Change this later to center it + y = rows * self.item_size + tempItem.set_position(x, y) + tempItem.show() + self.add(tempItem) + + #Check if this is the first folder + if len(self.folderLibrary) == 0: + self.currentItemNo = 0 + + self.folderLibrary.append(tempItem) + self.viewerLibrary.append(cover_viewer) + + def get_current_viewer(self): + return self.viewerLibrary[self.currentItemNo] + + def set_dir_cover_viewer(self, cover_view): + timeline = clutter.Timeline(10,35) + alpha = clutter.Alpha(timeline, clutter.smoothstep_inc_func)# clutter.ramp_inc_func) + self.behaviour_opacity_outgoing = clutter.BehaviourOpacity(alpha, 255, 0) + + num_folders = len(cover_view.folderLibrary) + count = 0 + for item in cover_view.textureLibrary: + if count < num_folders: + self.add_folder(item, timeline) + else: + self.behaviour_opacity_outgoing.apply(item) + + timeline.start() + + def add_folder(self, cover_viewer_item, timeline): + #First we clone the textures pixbuf + #tempFolderTexture = clutter.CloneTexture(cover_viewer_texture) + #tempFolderTexture.set_pixbuf(cover_viewer_texture.get_pixbuf()) + #tempFolderTexture.set_parent_texture(cover_viewer_texture) + + """ + knots = (\ + (group_x, group_y),\ + (group_x, new_y )\ + ) + """ + self.add(cover_viewer_item) + \ No newline at end of file diff --git a/modules/video_player/video_player.py b/modules/video_player/video_player.py index 91f3e3c..a34dbe8 100644 --- a/modules/video_player/video_player.py +++ b/modules/video_player/video_player.py @@ -9,32 +9,54 @@ import os from clutter import cluttergst from VideoController import VideoController from modules.video_player.cover_viewer import coverViewer +from modules.video_player.folder_menu import folderMenu class Module(): title = "Videos" menu_image= "videos.png" + coverViewerWidth = 800 + coverViewerHeight = 600 + coverViewerRows = 3 + coverViewerColumns = 4 + cover_size = int(coverViewerWidth / coverViewerColumns) def __init__(self, MenuMgr, dbMgr): self.stage = MenuMgr.get_stage() self.MenuMgr = MenuMgr - self.cover_viewer = coverViewer(self.stage, 800, 600) + self.dbMgr = dbMgr + self.viewerLibrary = [] + self.folderLibrary = [] self.videoController = VideoController(self.stage) self.is_playing = False #This block can be moved to begin() but causes a performance hit when loading the module *shrug* + #base_cover_viewer = coverViewer(self.stage, self.coverViewerWidth, self.coverViewerHeight) + #self.viewerLibrary.append(base_cover_viewer) + #self.currentViewer = base_cover_viewer self.baseDir = dbMgr.get_setting("VideoStartupDir") - self.loadDir(self.baseDir) - results = dbMgr.get_videos() - if results == None: - print "VideoPlayer: No connection to DB or no videos found in DB" - return None - #Load the videos into the cover viewer - for record in results: - tempVideo = videoItem() - tempVideo.importFromMythObject(record) - self.cover_viewer.add_video(tempVideo) + self.cwd = self.baseDir + self.folder_level = 0 + base_folder_menu = folderMenu(self.stage, self.coverViewerRows, self.cover_size) + self.folderLibrary.append(base_folder_menu) + self.load_base_folders(self.baseDir, base_folder_menu) + self.currentViewer = base_folder_menu.get_current_viewer() + self.stage.add(base_folder_menu) + base_folder_menu.show() + #self.loadDir(self.baseDir, base_cover_viewer) + #results = dbMgr.get_videos() + + def load_base_folders(self, dirPath, folder_menu): + new_file_list = os.listdir(dirPath) + + #Images and Directories + for dir_entry in new_file_list: + tempPath = dirPath + "/" + dir_entry + if os.path.isdir(tempPath) and not ( dir_entry[0] == "."): + tempViewer = coverViewer(self.stage, self.coverViewerWidth, self.coverViewerHeight, self.coverViewerRows, self.coverViewerColumns) + self.loadDir(tempPath, tempViewer) + folder_menu.add_base_dir(dir_entry, tempViewer) - def loadDir(self, dirPath): + def loadDir(self, dirPath, cover_viewer): if not os.path.isdir(dirPath): print "ERROR: Invalid path" return None @@ -45,10 +67,42 @@ class Module(): #Images and Directories for dir_entry in new_file_list: if os.path.isdir(dirPath + "/" + dir_entry) and not ( dir_entry[0] == "."): - self.cover_viewer.add_folder(dir_entry) + cover_viewer.add_folder(dir_entry) print dir_entry else: final_file_list.append(dir_entry) + + #Check if we're empty + if len(final_file_list) == 0: + return + + #Make sure the dirPath ends in "/" + if not dirPath[-1] == "/": + dirPath = dirPath + "/" + + #Generate some SQL to retrieve videos that were in the final_file_list + #Load the videos into the cover viewer + sql = "SELECT * FROM videometadata WHERE filename IN (" + for filename in final_file_list: + filename = dirPath + filename + sql = sql + "\"" + filename + "\", " + sqlLength = int(len(sql) - 2) + print "SQL Length: " + str(sqlLength) + sql = sql[:sqlLength] + sql = sql + ")" + print sql + results = self.dbMgr.run_sql(sql) + + #Check for null return + if results == None: + print "VideoPlayer: No connection to DB or no videos found in DB" + return None + + #Else add the entries in + for record in results: + tempVideo = videoItem() + tempVideo.importFromMythObject(record) + cover_viewer.add_video(tempVideo) #Action to take when menu item is selected def action(self): @@ -77,10 +131,15 @@ class Module(): left = clutter.keysyms.Left right= clutter.keysyms.Right if (event.keyval == up) or (event.keyval == down) or (event.keyval == left) or (event.keyval == right): - self.cover_viewer.on_key_press_event(event) + self.currentViewer.on_key_press_event(event) if event.keyval == clutter.keysyms.Return: - self.play_video() + #Find whether the current item is a folder or video + item = self.currentViewer.get_current_item() + if item.isFolder: + self.MenuMgr.display_msg("Msg", "Its a folder") + else: + self.play_video() if event.keyval == clutter.keysyms.Escape: return True @@ -90,7 +149,7 @@ class Module(): def begin(self, MenuMgr): #Check that the library actually contains something - if self.cover_viewer.num_covers == 0: + if self.currentViewer.num_covers == 0: self.MenuMgr.display_msg("Error: No videos", "There are no videos available in the library. This maybe caused by an empty library or a failed connection to the server.") self.stop() return @@ -107,19 +166,23 @@ class Module(): self.begin_behaviour = clutter.BehaviourOpacity(alpha, 0, 255) self.begin_behaviour.apply(self.backdrop) - self.cover_viewer.set_opacity(0) - self.cover_viewer.show_all() - self.cover_viewer.show() - self.stage.add(self.cover_viewer) - cover_x = self.stage.get_width() - self.cover_viewer.get_width() - #self.cover_viewer.set_position(cover_x, 40) - self.cover_viewer.set_position(50, 40) - self.cover_viewer.toggle_details() #Turns the details group on - self.cover_viewer.select_first() - self.begin_behaviour.apply(self.cover_viewer) + + self.currentViewer.set_opacity(0) + self.currentViewer.show_all() + self.currentViewer.show() + self.stage.add(self.currentViewer) + cover_x = self.stage.get_width() - int(self.currentViewer.get_width() * 1.1) + self.currentViewer.set_position(cover_x, 40) + #self.viewerLibrary[0].set_position(50, 40) + self.currentViewer.toggle_details() #Turns the details group on + self.currentViewer.select_first() + self.begin_behaviour.apply(self.currentViewer) timeline_begin.start() + self.folder_menu = folderMenu(self.stage, self.currentViewer.num_visible_rows, self.currentViewer.cover_size) + self.folder_menu.set_dir_cover_viewer(self.currentViewer) + def stop(self): self.MenuMgr.currentPlugin = None @@ -127,7 +190,7 @@ class Module(): timeline_stop = clutter.Timeline(10,30) alpha = clutter.Alpha(timeline_stop, clutter.ramp_inc_func) self.stop_behaviour = clutter.BehaviourOpacity(alpha, 255, 0) - self.stop_behaviour.apply(self.cover_viewer) + self.stop_behaviour.apply(self.currentViewer) self.stop_behaviour.apply(self.backdrop) timeline_stop.connect('completed', self.destroyPlugin) timeline_stop.start() @@ -135,17 +198,17 @@ class Module(): def destroyPlugin(self, data): - self.stage.remove(self.cover_viewer) + self.stage.remove(self.currentViewer) self.backdrop.hide() #self.stage.remove(self.overlay) def play_video(self): - vid = self.cover_viewer.get_current_video() + vid = self.currentViewer.get_current_item().video uri = "file://" + str(vid.filename) self.videoController.play_video(uri, self) self.is_playing = True - self.stage.remove(self.cover_viewer) + self.stage.remove(self.currentViewer) def stop_video(self): if not self.is_playing: @@ -154,13 +217,13 @@ class Module(): self.is_playing = False timeline = clutter.Timeline(15, 25) - self.cover_viewer.set_opacity(0) + self.currentViewer.set_opacity(0) alpha = clutter.Alpha(timeline, clutter.ramp_inc_func) self.behaviour = clutter.BehaviourOpacity(alpha, 0,255) - self.behaviour.apply(self.cover_viewer) + self.behaviour.apply(self.currentViewer) - self.stage.add(self.cover_viewer) - self.cover_viewer.show() + self.stage.add(self.currentViewer) + self.currentViewer.show() timeline.start() def pause(self): diff --git a/myth/MythMySQL.py b/myth/MythMySQL.py index 57ed3d3..c135418 100644 --- a/myth/MythMySQL.py +++ b/myth/MythMySQL.py @@ -46,21 +46,16 @@ class mythDB(): if variables[0] == "DBName": self.db = variables[1].rstrip() - - - def get_videos(self): + def run_sql(self, sql): if not self.connected: print "Unable to start video, could not establish connection to SQL server" return None - sql = "SELECT * FROM videometadata WHERE coverfile <> 'No Cover'" - self.cursor.execute(sql) # get the resultset as a tuple result = self.cursor.fetchall() - return result - + #Gets an arbitary setting from the settings table def get_setting(self, setting_name): if not self.connected: diff --git a/myth/MythMySQL.pyc b/myth/MythMySQL.pyc index 00c9a1feb944175ae0d5d7fa471092e9df8e4449..eb444b5219bd95715274724746c161d37fee4709 100644 GIT binary patch delta 118 zcmdll^-Yp}^Cw;|CWerW?2W8KObiSR%s>pHoq@R6YVs^rsmZ%oRT!Bj-)HrioXOU% zzz&osD$R>8F3d3mso?<<42)citc)B?0!;jjn?>1qm>6v~D{-naG5SsR;J(TjKUt1v NA+s zMT1>^T%AJ{v=rQe{CyS5GE-9Xb5lzaQxZ!O6~aASgIpDo^UG3;(lT>W6>RJj)cx`m zoIwKWlU3Q;Rk?sBq^Fj|gY^{~gKXgg5)6!7jI4|tOl(X7O#Don&#>_@F*