Much work on improving video playback controls.
Case of gstreamer codec not being found is handled (Although not reported back to the user) Fixed some display bugs in the cover viewer
This commit is contained in:
parent
b6eabe1c83
commit
f42fc2d1db
|
@ -44,6 +44,7 @@ class SplashScr():
|
||||||
pos_x = self.spinner.get_x()
|
pos_x = self.spinner.get_x()
|
||||||
pos_x = pos_x + int (self.spinner.get_width() * 1.1)
|
pos_x = pos_x + int (self.spinner.get_width() * 1.1)
|
||||||
self.message.set_position(pos_x, 0)
|
self.message.set_position(pos_x, 0)
|
||||||
|
self.message.set_text("dslkfjlds")
|
||||||
self.main_group.add(self.message)
|
self.main_group.add(self.message)
|
||||||
|
|
||||||
self.detail = clutter.Label()
|
self.detail = clutter.Label()
|
||||||
|
|
|
@ -32,7 +32,7 @@ class TVPlayer:
|
||||||
def begin_playback(self, buffer_file):
|
def begin_playback(self, buffer_file):
|
||||||
self.menuMgr.get_selector_bar().set_spinner(False)
|
self.menuMgr.get_selector_bar().set_spinner(False)
|
||||||
uri = "file://" + os.getcwd() +"/" + buffer_file
|
uri = "file://" + os.getcwd() +"/" + buffer_file
|
||||||
self.videoController.play_video(uri)
|
self.videoController.play_video(uri, self)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
timeline = clutter.Timeline(15, 25)
|
timeline = clutter.Timeline(15, 25)
|
||||||
|
@ -61,7 +61,9 @@ class TVPlayer:
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.videoController.stop_video()
|
self.videoController.stop_video()
|
||||||
self.myConn.stop() # Stops the backend / frontend streaming
|
self.myConn.stop() # Stops the backend / frontend streaming
|
||||||
|
|
||||||
|
def stop_video(self):
|
||||||
|
self.stop()
|
||||||
|
|
||||||
def on_key_press_event (self, stage, event):
|
def on_key_press_event (self, stage, event):
|
||||||
if self.isRunning:
|
if self.isRunning:
|
||||||
|
|
BIN
TVPlayer.pyc
BIN
TVPlayer.pyc
Binary file not shown.
|
@ -1,4 +1,4 @@
|
||||||
import sys, clutter, clutter.cluttergst, gst, pygst, gtk, pygtk
|
import sys, clutter, clutter.cluttergst, gst, pygst, gtk, pygtk, gobject
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,33 +31,59 @@ class VideoController:
|
||||||
|
|
||||||
#self.osd.enter()
|
#self.osd.enter()
|
||||||
|
|
||||||
def play_video(self, uri):
|
def play_video(self, uri, player):
|
||||||
|
self.player = player
|
||||||
self.stage.add(self.video_texture)
|
self.stage.add(self.video_texture)
|
||||||
self.video_texture.set_uri(uri)
|
self.video_texture.set_uri(uri)
|
||||||
self.video_texture.set_position(0, 0)
|
self.video_texture.set_position(0, 0)
|
||||||
self.video_texture.show()
|
self.video_texture.show()
|
||||||
|
|
||||||
|
#We need to connect to the message queue on the playbin to watch for any message (ie codec or file not found errors)
|
||||||
|
bus = self.video_texture.get_playbin().get_bus()
|
||||||
|
bus.add_signal_watch()
|
||||||
|
bus.connect('message', self.on_bus_message)
|
||||||
|
|
||||||
|
#Now we can start the video
|
||||||
self.video_texture.set_playing(True)
|
self.video_texture.set_playing(True)
|
||||||
self.isPlaying = True
|
self.isPlaying = True
|
||||||
|
|
||||||
return self.video_texture
|
return self.video_texture
|
||||||
|
|
||||||
|
def on_bus_message(self, bus, message):
|
||||||
|
t = message.type
|
||||||
|
|
||||||
|
if t == gst.MESSAGE_ELEMENT:
|
||||||
|
#This occurs when an invalid codec is attempted to be played
|
||||||
|
#Need to insert some form of message to the user here
|
||||||
|
struc = message.structure
|
||||||
|
if struc is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
if struc.get_name() == "missing-plugin":
|
||||||
|
self.isPlaying = False
|
||||||
|
self.video_texture.set_playing(False)
|
||||||
|
self.player.stop_video()
|
||||||
|
elif t == gst.STREAM_ERROR:
|
||||||
|
print "OHH NOES!"
|
||||||
|
|
||||||
def stop_video(self):
|
def stop_video(self):
|
||||||
if self.video_texture.get_playing():
|
if self.video_texture.get_playing():
|
||||||
self.isPlaying = False
|
self.isPlaying = False
|
||||||
|
self.player = None
|
||||||
self.video_texture.set_playing(False)
|
self.video_texture.set_playing(False)
|
||||||
|
|
||||||
timeline = clutter.Timeline(15, 25)
|
timeline = clutter.Timeline(15, 25)
|
||||||
timeline.connect('completed', self.end_video_event)
|
timeline.connect('completed', self.end_video_event)
|
||||||
alpha = clutter.Alpha(timeline, clutter.ramp_inc_func)
|
alpha = clutter.Alpha(timeline, clutter.ramp_inc_func)
|
||||||
behaviour = clutter.BehaviourOpacity(alpha, 255,0)
|
self.behaviour = clutter.BehaviourOpacity(alpha, 255,0)
|
||||||
behaviour.apply(self.video_texture)
|
self.behaviour.apply(self.video_texture)
|
||||||
behaviour.apply(self.blackdrop)
|
#behaviour.apply(self.blackdrop)
|
||||||
|
|
||||||
timeline.start()
|
timeline.start()
|
||||||
|
|
||||||
def end_video_event(self, data):
|
def end_video_event(self, data):
|
||||||
self.stage.remove(self.video_texture)
|
self.stage.remove(self.video_texture)
|
||||||
self.stage.remove(self.blackdrop)
|
# self.stage.remove(self.blackdrop)
|
||||||
self.blackdrop = None
|
self.blackdrop = None
|
||||||
|
|
||||||
def customBin(self):
|
def customBin(self):
|
||||||
|
@ -247,6 +273,7 @@ class osd:
|
||||||
|
|
||||||
self.exit_behaviour_path.apply(self.bar_group)
|
self.exit_behaviour_path.apply(self.bar_group)
|
||||||
self.timeline.start()
|
self.timeline.start()
|
||||||
|
|
||||||
def exit_end_event(self, data):
|
def exit_end_event(self, data):
|
||||||
self.stage.remove(self.bar_group)
|
self.stage.remove(self.bar_group)
|
||||||
|
|
||||||
|
@ -254,10 +281,10 @@ class osd:
|
||||||
def shift_video(self, video, shift_amount):
|
def shift_video(self, video, shift_amount):
|
||||||
#Firstly check whether the label is already there from last time
|
#Firstly check whether the label is already there from last time
|
||||||
if self.timerRunning:
|
if self.timerRunning:
|
||||||
self.timer.cancel()
|
#self.timer.cancel()
|
||||||
self.timer = threading.Timer(1.5, self.label_exit)
|
#self.timer = threading.Timer(1.5, self.label_exit)
|
||||||
self.timerRunning = True
|
#self.timerRunning = True
|
||||||
self.timer.start()
|
#self.timer.start()
|
||||||
return
|
return
|
||||||
|
|
||||||
shiftDistance = 100
|
shiftDistance = 100
|
||||||
|
@ -286,17 +313,18 @@ class osd:
|
||||||
|
|
||||||
self.incoming_text_timeline = clutter.Timeline(20, 60)
|
self.incoming_text_timeline = clutter.Timeline(20, 60)
|
||||||
alpha = clutter.Alpha(self.incoming_text_timeline, clutter.ramp_inc_func)
|
alpha = clutter.Alpha(self.incoming_text_timeline, clutter.ramp_inc_func)
|
||||||
behaviour1 = clutter.BehaviourPath(alpha, incoming_label_knots)
|
self.behaviour1 = clutter.BehaviourPath(alpha, incoming_label_knots)
|
||||||
behaviour2 = clutter.BehaviourOpacity(alpha, 0, 120)
|
self.behaviour2 = clutter.BehaviourOpacity(alpha, 0, 120)
|
||||||
|
|
||||||
behaviour1.apply(self.shift_label)
|
self.behaviour1.apply(self.shift_label)
|
||||||
behaviour2.apply(self.shift_label)
|
self.behaviour2.apply(self.shift_label)
|
||||||
self.stage.add(self.shift_label)
|
self.stage.add(self.shift_label)
|
||||||
self.shift_label.show()
|
self.shift_label.show()
|
||||||
|
|
||||||
self.timer = threading.Timer(1.5, self.label_exit)
|
#self.timer = threading.Timer(1.5, self.label_exit)
|
||||||
|
gobject.timeout_add(1500, self.label_exit)
|
||||||
self.timerRunning = True
|
self.timerRunning = True
|
||||||
self.timer.start()
|
#self.timer.start()
|
||||||
|
|
||||||
self.incoming_text_timeline.start()
|
self.incoming_text_timeline.start()
|
||||||
#print time.strftime("%H:%M:%S", time.gmtime(amount))
|
#print time.strftime("%H:%M:%S", time.gmtime(amount))
|
||||||
|
@ -318,14 +346,16 @@ class osd:
|
||||||
self.outgoing_text_timeline = clutter.Timeline(20, 60)
|
self.outgoing_text_timeline = clutter.Timeline(20, 60)
|
||||||
self.outgoing_text_timeline.connect('completed', self.removeLabel)
|
self.outgoing_text_timeline.connect('completed', self.removeLabel)
|
||||||
alpha = clutter.Alpha(self.outgoing_text_timeline, clutter.ramp_inc_func)
|
alpha = clutter.Alpha(self.outgoing_text_timeline, clutter.ramp_inc_func)
|
||||||
behaviour1 = clutter.BehaviourPath(alpha, outgoing_label_knots)
|
self.behaviour1 = clutter.BehaviourPath(alpha, outgoing_label_knots)
|
||||||
behaviour2 = clutter.BehaviourOpacity(alpha, self.shift_label.get_opacity() , 0)
|
self.behaviour2 = clutter.BehaviourOpacity(alpha, self.shift_label.get_opacity() , 0)
|
||||||
|
|
||||||
behaviour1.apply(self.shift_label)
|
self.behaviour1.apply(self.shift_label)
|
||||||
behaviour2.apply(self.shift_label)
|
self.behaviour2.apply(self.shift_label)
|
||||||
|
|
||||||
self.outgoing_text_timeline.start()
|
self.outgoing_text_timeline.start()
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def removeLabel(self, data):
|
def removeLabel(self, data):
|
||||||
self.stage.remove(self.shift_label)
|
self.stage.remove(self.shift_label)
|
||||||
|
|
||||||
|
|
|
@ -52,12 +52,12 @@ class VideoPlayer():
|
||||||
left = clutter.keysyms.Left
|
left = clutter.keysyms.Left
|
||||||
right= clutter.keysyms.Right
|
right= clutter.keysyms.Right
|
||||||
if (event.keyval == up) or (event.keyval == down) or (event.keyval == left) or (event.keyval == right):
|
if (event.keyval == up) or (event.keyval == down) or (event.keyval == left) or (event.keyval == right):
|
||||||
self.cover_viewer.on_cursor_press_event(event)
|
self.cover_viewer.on_key_press_event(event)
|
||||||
|
|
||||||
if event.keyval == clutter.keysyms.Return:
|
if event.keyval == clutter.keysyms.Return:
|
||||||
vid = self.cover_viewer.get_current_video()
|
vid = self.cover_viewer.get_current_video()
|
||||||
uri = "file://" + str(vid.filename)
|
uri = "file://" + str(vid.filename)
|
||||||
self.videoController.play_video(uri)
|
self.videoController.play_video(uri, self)
|
||||||
self.is_playing = True
|
self.is_playing = True
|
||||||
|
|
||||||
if event.keyval == clutter.keysyms.Escape:
|
if event.keyval == clutter.keysyms.Escape:
|
||||||
|
@ -108,6 +108,11 @@ class VideoPlayer():
|
||||||
self.backdrop.hide()
|
self.backdrop.hide()
|
||||||
#self.stage.remove(self.overlay)
|
#self.stage.remove(self.overlay)
|
||||||
|
|
||||||
|
def stop_video(self):
|
||||||
|
if not self.is_playing:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.is_playing = False
|
||||||
|
|
||||||
def pause(self):
|
def pause(self):
|
||||||
pass
|
pass
|
||||||
|
@ -225,8 +230,8 @@ class coverViewer(clutter.Group):
|
||||||
self.num_covers = self.num_covers +1
|
self.num_covers = self.num_covers +1
|
||||||
|
|
||||||
def select_item(self, incomingItem, outgoingItem):
|
def select_item(self, incomingItem, outgoingItem):
|
||||||
self.current_video_details.set_video(self.videoLibrary[incomingItem])
|
self.timeline = clutter.Timeline(10,35)
|
||||||
self.timeline = clutter.Timeline(20,80)
|
self.current_video_details.set_video(self.videoLibrary[incomingItem], self.timeline)
|
||||||
|
|
||||||
#Check if the cover is currently not visible
|
#Check if the cover is currently not visible
|
||||||
rolling = False
|
rolling = False
|
||||||
|
@ -240,7 +245,7 @@ class coverViewer(clutter.Group):
|
||||||
outgoingTexture = self.textureLibrary[outgoingItem]
|
outgoingTexture = self.textureLibrary[outgoingItem]
|
||||||
incomingTexture = self.textureLibrary[incomingItem]
|
incomingTexture = self.textureLibrary[incomingItem]
|
||||||
|
|
||||||
alpha = clutter.Alpha(self.timeline, clutter.ramp_inc_func)
|
alpha = clutter.Alpha(self.timeline, clutter.smoothstep_inc_func)# clutter.ramp_inc_func)
|
||||||
self.behaviourNew_scale = clutter.BehaviourScale(alpha, 1, self.scaleFactor, clutter.GRAVITY_CENTER)
|
self.behaviourNew_scale = clutter.BehaviourScale(alpha, 1, self.scaleFactor, clutter.GRAVITY_CENTER)
|
||||||
self.behaviourNew_z = clutter.BehaviourDepth(alpha, 1, 2)
|
self.behaviourNew_z = clutter.BehaviourDepth(alpha, 1, 2)
|
||||||
#If we're performing a roll (See above) then the incoming opacity should start at 0 rather than the normal inactive opacity
|
#If we're performing a roll (See above) then the incoming opacity should start at 0 rather than the normal inactive opacity
|
||||||
|
@ -265,8 +270,9 @@ class coverViewer(clutter.Group):
|
||||||
self.timeline.start()
|
self.timeline.start()
|
||||||
|
|
||||||
def select_first(self):
|
def select_first(self):
|
||||||
self.current_video_details.set_video(self.videoLibrary[0])
|
|
||||||
self.timeline = clutter.Timeline(20,80)
|
self.timeline = clutter.Timeline(20,80)
|
||||||
|
self.current_video_details.set_video(self.videoLibrary[0], self.timeline)
|
||||||
|
|
||||||
|
|
||||||
incomingItem = 0
|
incomingItem = 0
|
||||||
incomingTexture = self.textureLibrary[incomingItem]
|
incomingTexture = self.textureLibrary[incomingItem]
|
||||||
|
@ -296,6 +302,10 @@ class coverViewer(clutter.Group):
|
||||||
max_outgoing = min_outgoing + self.num_columns
|
max_outgoing = min_outgoing + self.num_columns
|
||||||
min_incoming = (self.max_visible_rows-1) * self.num_columns
|
min_incoming = (self.max_visible_rows-1) * self.num_columns
|
||||||
max_incoming = min_incoming + self.num_columns
|
max_incoming = min_incoming + self.num_columns
|
||||||
|
|
||||||
|
#Quick check to make sure that max_incoming isn't greater than the max number of images (This occurs when the final row is incomplete)
|
||||||
|
if max_incoming > self.num_covers:
|
||||||
|
max_incoming = min_incoming + (self.num_covers % self.num_columns)
|
||||||
else:
|
else:
|
||||||
new_y = self.covers_group.get_y() + self.cover_size
|
new_y = self.covers_group.get_y() + self.cover_size
|
||||||
self.max_visible_rows = self.max_visible_rows - 1
|
self.max_visible_rows = self.max_visible_rows - 1
|
||||||
|
@ -305,7 +315,11 @@ class coverViewer(clutter.Group):
|
||||||
min_incoming = (self.min_visible_rows) * self.num_columns
|
min_incoming = (self.min_visible_rows) * self.num_columns
|
||||||
max_incoming = min_incoming + self.num_columns
|
max_incoming = min_incoming + self.num_columns
|
||||||
min_outgoing = (self.max_visible_rows) * self.num_columns
|
min_outgoing = (self.max_visible_rows) * self.num_columns
|
||||||
max_outgoing = min_outgoing + self.num_columns
|
max_outgoing = min_outgoing + self.num_columns
|
||||||
|
|
||||||
|
#Quick check to make sure that max_outgoing isn't greater than the max number of images (This occurs when the final row is incomplete)
|
||||||
|
if max_outgoing > self.num_covers:
|
||||||
|
max_outgoing = min_outgoing + (self.num_covers % self.num_columns)
|
||||||
|
|
||||||
|
|
||||||
knots = (\
|
knots = (\
|
||||||
|
@ -328,24 +342,21 @@ class coverViewer(clutter.Group):
|
||||||
def get_current_video(self):
|
def get_current_video(self):
|
||||||
return self.videoLibrary[self.currentSelection]
|
return self.videoLibrary[self.currentSelection]
|
||||||
|
|
||||||
def on_cursor_press_event(self, event):
|
def on_key_press_event(self, event):
|
||||||
newItem = None
|
newItem = None
|
||||||
if event.keyval == clutter.keysyms.Left:
|
if event.keyval == clutter.keysyms.Left:
|
||||||
#Make sure we're not already on the first cover
|
#Make sure we're not already on the first cover
|
||||||
if not self.currentSelection == 0:
|
if not self.currentSelection == 0:
|
||||||
newItem = self.currentSelection - 1
|
newItem = self.currentSelection - 1
|
||||||
|
elif event.keyval == clutter.keysyms.Right:
|
||||||
if event.keyval == clutter.keysyms.Right:
|
|
||||||
#This check makes sure that we're not on the last cover already
|
#This check makes sure that we're not on the last cover already
|
||||||
if not self.currentSelection == (self.get_n_children()-1):
|
if not self.currentSelection == (self.num_covers-1):
|
||||||
newItem = self.currentSelection + 1
|
newItem = self.currentSelection + 1
|
||||||
|
elif event.keyval == clutter.keysyms.Down:
|
||||||
if event.keyval == clutter.keysyms.Down:
|
|
||||||
#Check if we're already on the bottom row
|
#Check if we're already on the bottom row
|
||||||
if not (self.currentSelection > (len(self.textureLibrary)-1 - self.num_columns)):
|
if not (self.currentSelection > (len(self.textureLibrary)-1 - self.num_columns)):
|
||||||
newItem = self.currentSelection + self.num_columns
|
newItem = self.currentSelection + self.num_columns
|
||||||
|
elif event.keyval == clutter.keysyms.Up:
|
||||||
if event.keyval == clutter.keysyms.Up:
|
|
||||||
#Check if we're already on the top row
|
#Check if we're already on the top row
|
||||||
if not (self.currentSelection < self.num_columns):
|
if not (self.currentSelection < self.num_columns):
|
||||||
newItem = self.currentSelection - self.num_columns
|
newItem = self.currentSelection - self.num_columns
|
||||||
|
@ -408,7 +419,11 @@ class video_details_group(clutter.Group):
|
||||||
|
|
||||||
self.show_all()
|
self.show_all()
|
||||||
|
|
||||||
def set_video(self, video):
|
def set_video_bare(self,video):
|
||||||
|
self.timeline = clutter.Timeline(10,45)
|
||||||
|
self.set_video(video, self.timeline)
|
||||||
|
|
||||||
|
def set_video(self, video, timeline):
|
||||||
self.video = video
|
self.video = video
|
||||||
|
|
||||||
self.title.set_text(video.title)
|
self.title.set_text(video.title)
|
||||||
|
|
BIN
VideoPlayer.pyc
BIN
VideoPlayer.pyc
Binary file not shown.
8
gloss.py
8
gloss.py
|
@ -3,7 +3,7 @@ import clutter
|
||||||
#import gobject
|
#import gobject
|
||||||
import pygtk
|
import pygtk
|
||||||
import gtk
|
import gtk
|
||||||
import thread
|
import threading
|
||||||
from SplashScr import SplashScr
|
from SplashScr import SplashScr
|
||||||
from Menu import Menu
|
from Menu import Menu
|
||||||
from MenuMgr import MenuMgr
|
from MenuMgr import MenuMgr
|
||||||
|
@ -34,8 +34,10 @@ class MainApp:
|
||||||
#Display a loading / splash screen
|
#Display a loading / splash screen
|
||||||
self.splashScreen = SplashScr(self.stage)
|
self.splashScreen = SplashScr(self.stage)
|
||||||
self.splashScreen.display()
|
self.splashScreen.display()
|
||||||
|
#self.timer = threading.Timer(1, self.loadGloss)
|
||||||
|
#self.timer.start()
|
||||||
|
|
||||||
def loadGloss(self, arg):
|
def loadGloss(self):
|
||||||
|
|
||||||
|
|
||||||
self.menuMgr = MenuMgr(self.stage)
|
self.menuMgr = MenuMgr(self.stage)
|
||||||
|
@ -124,7 +126,7 @@ def main (args):
|
||||||
app = MainApp()
|
app = MainApp()
|
||||||
#thread.start_new_thread(app.run, (None,))
|
#thread.start_new_thread(app.run, (None,))
|
||||||
#thread.start_new_thread(app.loadGloss, (None,))
|
#thread.start_new_thread(app.loadGloss, (None,))
|
||||||
app.loadGloss(None)
|
app.loadGloss()
|
||||||
app.run()
|
app.run()
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue