gloss-mc/modules/video_player/video_player.py

332 lines
13 KiB
Python
Raw Normal View History

2007-08-14 18:10:53 -07:00
import pygtk
import gtk
import pygst
import gst
import gobject
import pango
2007-08-14 18:10:53 -07:00
import clutter
import os
from clutter import cluttergst
from VideoController import VideoController
2007-11-19 03:38:15 -08:00
from modules.video_player.cover_viewer import coverViewer
from modules.video_player.folder_menu import folderMenu
2007-08-14 18:10:53 -07:00
2008-01-06 04:11:17 -08:00
#===============================================================================
#This module displays a basic cover viewer for videos within myth's Mythvideo table
#It defines the following theme elements:
#video_menu_image (Texture): The graphic used on the menu to represent this module
#video_cover_bg_image (Texture): Graphic that serves as the background for the cover viewer grid
#===============================================================================
2007-11-19 03:38:15 -08:00
class Module():
title = "Videos"
STATE_FOLDERS, STATE_COVERS, STATE_VIDEO = range(3)
2008-01-06 04:11:17 -08:00
coverViewerWidth = 750
coverViewerHeight = 600
coverViewerPosX = 300
coverViewerPosY = 50
coverViewerRows = 3
coverViewerColumns = 4
cover_size = int(coverViewerWidth / coverViewerColumns)
2007-08-14 18:10:53 -07:00
2007-12-21 03:39:50 -08:00
def __init__(self, glossMgr, dbMgr):
self.stage = glossMgr.get_stage()
self.glossMgr = glossMgr
self.dbMgr = dbMgr
2008-01-06 04:11:17 -08:00
self.setup_ui()
self.viewerLibrary = []
self.folderLibrary = []
2007-11-19 03:38:15 -08:00
self.videoController = VideoController(self.stage)
2008-01-06 04:11:17 -08:00
#Setup initial vars
2007-08-14 18:10:53 -07:00
self.is_playing = False
self.controlState = self.STATE_FOLDERS
self.foldersPosX = (self.coverViewerPosX - self.cover_size) / 2
self.foldersPosY = (self.stage.get_height() - self.coverViewerHeight) / 2
2007-08-14 18:10:53 -07:00
#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.baseDir = dbMgr.get_setting("VideoStartupDir")
self.cwd = self.baseDir
self.folder_level = 0
base_folder_menu = folderMenu(self.stage, self.coverViewerRows, self.cover_size)
base_folder_menu.set_position(self.foldersPosX, self.foldersPosY)
self.folderLibrary.append(base_folder_menu)
self.load_base_folders(self.baseDir, base_folder_menu)
self.currentViewer = base_folder_menu.get_current_viewer()
2008-01-06 04:11:17 -08:00
def setup_ui(self):
self.menu_image = self.glossMgr.themeMgr.get_texture("video_menu_image", None, None)
#Add the background
self.covers_background = self.glossMgr.themeMgr.get_texture("video_covers_background", self.stage, None)
#backgroundImg = "ui/cover_bg_long.png"
#pixbuf = gtk.gdk.pixbuf_new_from_file(self.backgroundImg)
#self.bgImg = clutter.Texture()
#self.bgImg.set_pixbuf(pixbuf)
#bgImg_height = height - ((height - (self.cover_size * rows)) / 2) + self.detailBox_height
#self.bgImg.set_size(width, bgImg_height)
#self.bgImg.set_depth(1)
#self.bgImg.show()
#self.stage.add(self.bgImg)
def load_base_folders(self, dirPath, folder_menu):
2007-12-11 02:50:45 -08:00
try:
new_file_list = os.listdir(dirPath)
except os.error, (errno, errstr):
self.MenuMgr.display_msg("File Error", "Could not load Slideshow directory")
return
#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, cover_viewer):
if not os.path.isdir(dirPath):
print "ERROR: Invalid path"
return None
final_file_list = []
new_file_list = os.listdir(dirPath)
2007-12-11 02:50:45 -08:00
#Images and Directories
for dir_entry in new_file_list:
if os.path.isdir(dirPath + "/" + dir_entry) and not ( dir_entry[0] == "."):
cover_viewer.add_folder(dir_entry)
2007-12-21 03:39:50 -08:00
#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)
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)
2007-11-19 03:38:15 -08:00
#Action to take when menu item is selected
def action(self):
return self
2007-08-14 18:10:53 -07:00
def on_key_press_event (self, stage, event):
up = clutter.keysyms.Up
down = clutter.keysyms.Down
left = clutter.keysyms.Left
right= clutter.keysyms.Right
if event.keyval == clutter.keysyms.q:
clutter.main_quit()
#*****************************************************************
#"State based input handling
if self.controlState == self.STATE_FOLDERS:
if event.keyval == clutter.keysyms.Escape:
return True
elif event.keyval == right:
self.controlState = self.STATE_COVERS
self.currentViewer = self.folderLibrary[self.folder_level].get_current_viewer()
self.currentViewer.select_first()
self.folderLibrary[self.folder_level].on_key_press_event(event)
#**********************************************************
elif self.controlState == self.STATE_VIDEO:
if event.keyval == clutter.keysyms.Escape:
self.videoController.stop_video()
self.is_playing = False
self.controlState = self.STATE_COVERS
else:
self.videoController.on_key_press_event(event)
return False
if event.keyval == clutter.keysyms.p:
if self.paused:
self.unpause()
else:
self.pause()
#**********************************************************
elif self.controlState == self.STATE_COVERS:
if (event.keyval == up) or (event.keyval == down) or (event.keyval == left) or (event.keyval == right):
self.currentViewer.on_key_press_event(event)
if event.keyval == clutter.keysyms.Return:
#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:
self.currentViewer.select_none()
self.controlState = self.STATE_FOLDERS
2007-08-14 18:10:53 -07:00
2007-12-21 03:39:50 -08:00
def begin(self, glossMgr):
#Check that the library actually contains something
2007-12-11 02:50:45 -08:00
#if len(self.currentViewer.textureLibrary) == 0:
if self.currentViewer is None:
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
2007-08-14 18:10:53 -07:00
#Create a backdrop for the player. In this case we just use the same background as the menus
self.backdrop = glossMgr.get_themeMgr().get_texture("background", None, None) #clutter.CloneTexture(glossMgr.get_skinMgr().get_Background())
2007-08-14 18:10:53 -07:00
self.backdrop.set_size(self.stage.get_width(), self.stage.get_height())
self.backdrop.set_opacity(0)
self.backdrop.show()
self.stage.add(self.backdrop)
#Add the covers background
self.covers_background.set_opacity(0)
self.covers_background.show()
self.stage.add(self.covers_background)
#Add the folders menu
self.stage.add(self.folderLibrary[0])
self.folderLibrary[0].show()
#Add the cover viewer
self.currentViewer.set_opacity(0)
self.currentViewer.show_all()
self.currentViewer.show()
#self.currentViewer_clip.show()
self.currentViewer.set_position(self.coverViewerPosX, self.coverViewerPosY)
#self.stage.add(self.currentViewer)
self.stage.add(self.currentViewer)
#Fade everything in
timeline_begin = clutter.Timeline(10,40)
alpha = clutter.Alpha(timeline_begin, clutter.ramp_inc_func)
self.begin_behaviour = clutter.BehaviourOpacity(opacity_start=0, opacity_end=255, alpha=alpha)
self.begin_behaviour.apply(self.backdrop)
self.begin_behaviour.apply(self.covers_background)
self.begin_behaviour.apply(self.currentViewer)
#self.viewerLibrary[0].set_position(50, 40)
self.currentViewer.toggle_details() #Turns the details group on
#self.currentViewer.select_first()
2007-08-14 18:10:53 -07:00
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)
2007-08-14 18:10:53 -07:00
def stop(self):
2007-12-21 03:39:50 -08:00
self.glossMgr.currentPlugin = None
#Fade everything out
timeline_stop = clutter.Timeline(10,30)
alpha = clutter.Alpha(timeline_stop, clutter.ramp_inc_func)
self.stop_behaviour = clutter.BehaviourOpacity(opacity_start=255, opacity_end=0, alpha=alpha)
self.stop_behaviour.apply(self.currentViewer)
self.stop_behaviour.apply(self.backdrop)
self.stop_behaviour.apply(self.folderLibrary[self.folder_level])
timeline_stop.connect('completed', self.destroyPlugin)
timeline_stop.start()
def destroyPlugin(self, data):
self.stage.remove(self.currentViewer)
self.stage.remove(self.folderLibrary[self.folder_level])
self.backdrop.hide()
#self.stage.remove(self.overlay)
def play_video(self):
vid = self.currentViewer.get_current_item().video
uri = "file://" + str(vid.filename)
self.videoController.play_video(uri, self)
self.is_playing = True
self.controlState = self.STATE_VIDEO
self.stage.remove(self.currentViewer)
def stop_video(self):
if not self.is_playing:
return
self.is_playing = False
2007-08-14 18:10:53 -07:00
2007-11-19 03:38:15 -08:00
timeline = clutter.Timeline(15, 25)
self.currentViewer.set_opacity(0)
2007-11-19 03:38:15 -08:00
alpha = clutter.Alpha(timeline, clutter.ramp_inc_func)
self.behaviour = clutter.BehaviourOpacity(opacity_start=0, opacity_end=255, alpha=alpha)
self.behaviour.apply(self.currentViewer)
2007-11-19 03:38:15 -08:00
self.stage.add(self.currentViewer)
self.currentViewer.show()
2007-11-19 03:38:15 -08:00
timeline.start()
2007-08-14 18:10:53 -07:00
def pause(self):
pass
def unpause(self):
pass
2007-08-14 18:10:53 -07:00
class videoItem():
def __init(self):
self.mythID = None
def importFromMythObject(self, mythObject):
self.mythID = mythObject[0]
self.title = mythObject[1]
self.director = mythObject[2]
self.plot = mythObject[3]
self.rating = mythObject[4]
self.inetRef = mythObject[5]
self.year = mythObject[6]
self.userRating = mythObject[7]
self.length = mythObject[8]
self.showLevel = mythObject[9]
self.filename = mythObject[10]
self.coverfile = mythObject[11]
self.childID = mythObject[12]
self.browse = mythObject[13]
self.playCommand = mythObject[14]
self.category = mythObject[15]
def getTitle(self):
return self.title
def getCoverfile(self):
return self.coverfile