The 'Get the lead out' commit.
Addition of some introduction code that will become the OSD Starting working on the cover browser in video module.
This commit is contained in:
parent
5f8f4ae748
commit
34f2c43832
60
TVPlayer.py
60
TVPlayer.py
|
@ -7,7 +7,7 @@ import clutter
|
|||
from clutter import cluttergst
|
||||
from myth.MythBackendConn import MythBackendConnection
|
||||
from Menu import Menu
|
||||
from VideoController import VideoController
|
||||
from VideoController import osd
|
||||
|
||||
class TVPlayer:
|
||||
|
||||
|
@ -16,17 +16,8 @@ class TVPlayer:
|
|||
self.video.connect('size-change', self.video_size_change)
|
||||
self.stage = stage
|
||||
self.dbMgr = dbMgr
|
||||
#audio.set_filename('cast1.avi')
|
||||
#audio.show()
|
||||
|
||||
#test = cluttercairo.Cairo()
|
||||
#audio = cluttergst.Audio()
|
||||
#audio.set_filename('test.mp3')
|
||||
|
||||
#stage.add(audio)
|
||||
#audio.set_playing(True)
|
||||
|
||||
#self.db_conn = mythVideoDB()
|
||||
self.isRunning = False
|
||||
|
||||
|
||||
def begin(self, menuMgr):
|
||||
self.menuMgr = menuMgr
|
||||
|
@ -35,20 +26,15 @@ class TVPlayer:
|
|||
(server, port) = self.dbMgr.get_backend_server()
|
||||
self.myConn = MythBackendConnection(self, server, port)
|
||||
self.myConn.start()
|
||||
#vid = VideoController()
|
||||
self.osd = osd(self.stage)
|
||||
#vid.begin(self.stage)
|
||||
#self.begin_playback(self.buffer_file_reader.fileno())
|
||||
|
||||
self.isRunning = True
|
||||
|
||||
def begin_playback(self, fd):
|
||||
#self.video.set_filename("test.mpg")
|
||||
#print "File Descriptor: " + str(fd)
|
||||
#self.buffer_file = open("test.mpg","r")
|
||||
#fd = self.buffer_file.fileno()
|
||||
#print os.read(fd, 100)
|
||||
stage = self.menuMgr.get_stage()
|
||||
self.menuMgr.get_selector_bar().set_spinner(False)
|
||||
self.video.set_uri("fd://"+str(fd))
|
||||
#self.video.set_property("fullscreen", True)
|
||||
self.video.set_opacity(0)
|
||||
self.video.show()
|
||||
|
||||
|
@ -59,7 +45,6 @@ class TVPlayer:
|
|||
|
||||
self.stage.add(self.video)
|
||||
self.video.set_playing(True)
|
||||
self.video.set_size(400, 300)
|
||||
timeline.start()
|
||||
#return None
|
||||
|
||||
|
@ -73,39 +58,8 @@ class TVPlayer:
|
|||
height = int (width / xy_ratio)
|
||||
height = 768
|
||||
|
||||
print "Width: " + str(width)
|
||||
print "Height: " + str(height)
|
||||
|
||||
|
||||
self.video.set_size(width, height)
|
||||
|
||||
|
||||
|
||||
"""
|
||||
playbin = self.video.get_playbin() .get_by_name("decodebin0")
|
||||
for element in playbin.elements():
|
||||
print element.get_name()
|
||||
|
||||
sink = playbin.elements().next()
|
||||
deinterlace = gst.element_factory_make("ffdeinterlace", "deinterlace")
|
||||
playbin.add(deinterlace)
|
||||
#gst.element_link_many(sink, deinterlace)
|
||||
self.video.set_size(stage.get_width(), stage.get_height())
|
||||
|
||||
#self.video.set_height(stage.get_height())
|
||||
|
||||
|
||||
|
||||
self.video_texture = clutter.Texture()
|
||||
self.pipeline = gst.Pipeline("mypipeline")
|
||||
self.pbin = gst.element_factory_make("playbin", "pbin");
|
||||
self.sink = cluttergst.video_sink_new(self.video_texture)
|
||||
self.pbin.set_property("uri", "fd://"+str(fd))
|
||||
|
||||
# add elements to the pipeline
|
||||
self.pipeline.add(self.pbin)
|
||||
self.pipeline.set_state(gst.STATE_PLAYING)
|
||||
"""
|
||||
def stop(self):
|
||||
if self.video.get_playing():
|
||||
self.video.set_playing(False)
|
||||
|
@ -124,6 +78,8 @@ class TVPlayer:
|
|||
self.stage.remove(self.video)
|
||||
|
||||
def on_key_press_event (self, stage, event):
|
||||
if self.isRunning:
|
||||
self.osd.on_key_press_event(event)
|
||||
#print event.hardware_keycode
|
||||
|
||||
"""if event.keyval == clutter.keysyms.p:
|
||||
|
|
BIN
TVPlayer.pyc
BIN
TVPlayer.pyc
Binary file not shown.
|
@ -1,4 +1,5 @@
|
|||
import sys, clutter, clutter.cluttergst, gst
|
||||
import sys, clutter, clutter.cluttergst, gst, pygst, gtk, pygtk
|
||||
import threading
|
||||
|
||||
|
||||
class VideoController:
|
||||
|
@ -6,21 +7,133 @@ class VideoController:
|
|||
def __init__(self):
|
||||
# Primary video texture & sink definition
|
||||
self.video_texture = clutter.cluttergst.VideoTexture()
|
||||
video_sink = clutter.cluttergst.VideoSink(self.video_texture)
|
||||
self.video_sink = clutter.cluttergst.VideoSink(self.video_texture)
|
||||
self.video_texture.set_position(0,0)
|
||||
|
||||
# Gst pipeline def
|
||||
|
||||
self.pipeline = gst.Pipeline()
|
||||
#self.tester()
|
||||
"""
|
||||
src = gst.element_factory_make ("videotestsrc")
|
||||
colorspace = gst.element_factory_make ("ffmpegcolorspace")
|
||||
bus = self.pipeline.get_bus()
|
||||
gst.Bus.add_signal_watch (bus)
|
||||
gst.Bin.add (self.pipeline, src, colorspace, video_sink)
|
||||
gst.element_link_many (src, colorspace, video_sink)
|
||||
|
||||
gst.Bin.add (self.pipeline, filesrc, colorspace, deinterlace, video_sink)
|
||||
gst.element_link_many (filesrc, colorspace, deinterlace, video_sink)
|
||||
"""
|
||||
|
||||
|
||||
def begin(self, stage):
|
||||
self.osd = osd(stage)
|
||||
self.osd.enter()
|
||||
|
||||
return None
|
||||
stage.add(self.video_texture)
|
||||
self.video_texture.show()
|
||||
self.pipeline.set_state(gst.STATE_PLAYING)
|
||||
|
||||
|
||||
def tester(self):
|
||||
self.src = gst.element_factory_make("filesrc", "src");
|
||||
self.src.set_property("location", "/home/josh/clutter/toys/gloss/test.mpg")
|
||||
self.demux = gst.element_factory_make("ffdemux_mpegts", "demux")
|
||||
self.queue1 = gst.element_factory_make("queue", "queue1")
|
||||
self.queue2 = gst.element_factory_make("queue", "queue2")
|
||||
#self.deinterlace = gst.element_factory_make("ffdeinterlace", "deinterlace")
|
||||
self.vdecode = gst.element_factory_make("mpeg2dec", "vdecode")
|
||||
self.adecode = gst.element_factory_make("mad", "adecode")
|
||||
#self.vsink = gst.element_factory_make("xvimagesink", "vsink")
|
||||
self.vsink = self.video_sink #cluttergst.VideoSink(self.video_texture)
|
||||
self.asink = gst.element_factory_make("alsasink", "asink")
|
||||
|
||||
|
||||
# add elements to the pipeline
|
||||
self.pipeline.add(self.src)
|
||||
self.pipeline.add(self.demux)
|
||||
self.pipeline.add(self.queue1)
|
||||
self.pipeline.add(self.queue2)
|
||||
self.pipeline.add(self.vdecode)
|
||||
#self.pipeline.add(self.deinterlace)
|
||||
self.pipeline.add(self.adecode)
|
||||
self.pipeline.add(self.vsink)
|
||||
self.pipeline.add(self.asink)
|
||||
|
||||
bus = self.pipeline.get_bus()
|
||||
gst.Bus.add_signal_watch (bus)
|
||||
|
||||
# we can't link demux until the audio and video pads are added
|
||||
# we need to listen for "pad-added" signals
|
||||
self.demux.connect("pad-added", self.on_pad_added)
|
||||
|
||||
# link all elements apart from demux
|
||||
gst.element_link_many(self.src, self.demux)
|
||||
gst.element_link_many(self.queue1, self.vdecode, self.vsink) #self.deinterlace, self.vsink)
|
||||
gst.element_link_many(self.queue2, self.adecode, self.asink)
|
||||
|
||||
def on_pad_added(self, element, src_pad):
|
||||
caps = src_pad.get_caps()
|
||||
name = caps[0].get_name()
|
||||
# link demux to vdecode when video/mpeg pad added to demux
|
||||
if name == "video/mpeg":
|
||||
sink_pad = self.queue1.get_pad("sink")
|
||||
elif name == "audio/mpeg":
|
||||
sink_pad = self.queue2.get_pad("sink")
|
||||
else:
|
||||
return
|
||||
if not sink_pad.is_linked():
|
||||
src_pad.link(sink_pad)
|
||||
|
||||
class osd:
|
||||
|
||||
def __init__(self, stage):
|
||||
self.stage = stage
|
||||
|
||||
self.bar_group = clutter.Group()
|
||||
|
||||
self.background = clutter.Texture()
|
||||
self.background.set_pixbuf( gtk.gdk.pixbuf_new_from_file("ui/osd_bar.png") )
|
||||
self.background.set_opacity(120)
|
||||
self.background.set_width(stage.get_width())
|
||||
self.bar_group.add(self.background)
|
||||
self.bar_group.show_all()
|
||||
|
||||
def enter(self):
|
||||
self.stage.add(self.bar_group)
|
||||
self.bar_group.show()
|
||||
|
||||
self.bar_group.set_position(0, self.stage.get_height())
|
||||
bar_position_y = int(self.stage.get_height() - self.background.get_height())
|
||||
|
||||
knots = (\
|
||||
(self.bar_group.get_x(), self.bar_group.get_y()),\
|
||||
(self.bar_group.get_x(), bar_position_y) \
|
||||
)
|
||||
|
||||
self.timeline = clutter.Timeline(25, 50)
|
||||
self.alpha = clutter.Alpha(self.timeline, clutter.ramp_inc_func)
|
||||
self.enter_behaviour_path = clutter.BehaviourPath(self.alpha, knots)
|
||||
|
||||
self.enter_behaviour_path.apply(self.bar_group)
|
||||
|
||||
self.timeline.start()
|
||||
|
||||
self.timer = threading.Timer(3.0, self.exit)
|
||||
self.timer.start()
|
||||
|
||||
def exit(self):
|
||||
|
||||
knots = (\
|
||||
(self.bar_group.get_x(), self.bar_group.get_y()),\
|
||||
(self.bar_group.get_x(), int(self.stage.get_height())) \
|
||||
)
|
||||
|
||||
self.timeline = clutter.Timeline(25, 50)
|
||||
self.timeline.connect('completed', self.exit_end_event)
|
||||
self.alpha = clutter.Alpha(self.timeline, clutter.ramp_inc_func)
|
||||
self.exit_behaviour_path = clutter.BehaviourPath(self.alpha, knots)
|
||||
|
||||
self.exit_behaviour_path.apply(self.bar_group)
|
||||
self.timeline.start()
|
||||
def exit_end_event(self, data):
|
||||
self.stage.remove(self.bar_group)
|
||||
|
||||
def on_key_press_event(self, event):
|
||||
self.enter()
|
||||
|
||||
|
||||
|
|
168
VideoPlayer.py
168
VideoPlayer.py
|
@ -11,7 +11,6 @@ class VideoPlayer():
|
|||
def __init__(self, stage, dbMgr):
|
||||
self.stage = stage
|
||||
self.cover_viewer = coverViewer(self.stage)
|
||||
self.videoLibrary = []
|
||||
|
||||
self.is_playing = False
|
||||
|
||||
|
@ -25,8 +24,8 @@ class VideoPlayer():
|
|||
for record in results:
|
||||
tempVideo = videoItem()
|
||||
tempVideo.importFromMythObject(record)
|
||||
self.videoLibrary.append(tempVideo)
|
||||
self.cover_viewer.add_image(tempVideo.getCoverfile())
|
||||
self.cover_viewer.add_video(tempVideo)
|
||||
#self.cover_viewer.add_image(tempVideo.getCoverfile())
|
||||
#dbMgr.close_db()
|
||||
################################################################################
|
||||
|
||||
|
@ -38,6 +37,16 @@ class VideoPlayer():
|
|||
self.pause()
|
||||
if event.keyval == clutter.keysyms.q:
|
||||
clutter.main_quit()
|
||||
|
||||
up = clutter.keysyms.Up
|
||||
down = clutter.keysyms.Down
|
||||
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_cursor_press_event(event)
|
||||
|
||||
|
||||
|
||||
|
||||
def begin(self, MenuMgr):
|
||||
|
||||
|
@ -144,19 +153,24 @@ class videoItem():
|
|||
return self.coverfile
|
||||
|
||||
class coverViewer(clutter.Group):
|
||||
scaleFactor = 1.4
|
||||
|
||||
def __init__(self, stage):
|
||||
clutter.Group.__init__(self)
|
||||
self.stage = stage
|
||||
self.covers = []
|
||||
self.videoLibrary = []
|
||||
self.num_covers = 0
|
||||
self.cover_size = 200 #A cover will be cover_size * cover_size (X * Y)
|
||||
self.cover_gap = 10
|
||||
self.cover_gap = 1
|
||||
|
||||
self.num_rows = 2
|
||||
self.num_columns = int(self.stage.get_width() / self.cover_size)
|
||||
self.num_rows = 3
|
||||
self.num_columns = 4 #int(self.stage.get_width() / self.cover_size)
|
||||
|
||||
def add_image(self, imagePath):
|
||||
self.currentSelection = 0
|
||||
|
||||
def add_video(self, video):
|
||||
self.videoLibrary.append(video)
|
||||
imagePath = video.getCoverfile()
|
||||
tempTexture = clutter.Texture()
|
||||
pixbuf = gtk.gdk.pixbuf_new_from_file(imagePath)
|
||||
tempTexture.set_pixbuf(pixbuf)
|
||||
|
@ -175,104 +189,46 @@ class coverViewer(clutter.Group):
|
|||
self.add(tempTexture)
|
||||
self.num_covers = self.num_covers +1
|
||||
|
||||
def select_item(self, incomingItem, outgoingItem):
|
||||
outgoingTexture = self.get_nth_child(outgoingItem)
|
||||
incomingTexture = self.get_nth_child(incomingItem)
|
||||
|
||||
#Make sure the new texture is on the top
|
||||
#incomingTexture.raise_top()
|
||||
|
||||
self.timeline = clutter.Timeline(20,80)
|
||||
alpha = clutter.Alpha(self.timeline, clutter.ramp_inc_func)
|
||||
behaviourNew = clutter.BehaviourScale(alpha, 1, self.scaleFactor, clutter.GRAVITY_CENTER)
|
||||
behaviourOld = clutter.BehaviourScale(alpha, self.scaleFactor, 1, clutter.GRAVITY_CENTER)
|
||||
|
||||
behaviourNew.apply(incomingTexture)
|
||||
behaviourOld.apply(outgoingTexture)
|
||||
|
||||
self.currentSelection = incomingItem
|
||||
|
||||
self.timeline.start()
|
||||
|
||||
def on_cursor_press_event(self, event):
|
||||
newItem = None
|
||||
if event.keyval == clutter.keysyms.Left:
|
||||
newItem = self.currentSelection - self.num_rows
|
||||
if event.keyval == clutter.keysyms.Right:
|
||||
newItem = self.currentSelection + self.num_rows
|
||||
if event.keyval == clutter.keysyms.Down:
|
||||
#Check if we're already on the bottom row
|
||||
if not ((self.currentSelection % self.num_rows) == (self.num_rows-1)):
|
||||
newItem = self.currentSelection + 1
|
||||
if event.keyval == clutter.keysyms.Up:
|
||||
#Check if we're already on the top row
|
||||
if not (self.currentSelection % self.num_rows) == 0:
|
||||
newItem = self.currentSelection - 1
|
||||
|
||||
if (newItem < 0) and (not newItem == None):
|
||||
newItem = self.currentSelection
|
||||
|
||||
#If there is movement, make the scale happen
|
||||
if not newItem == None:
|
||||
self.select_item(newItem, self.currentSelection)
|
||||
|
||||
|
||||
#Redo positioning on all textures to add new one :(
|
||||
"""for i in range(self.num_covers):
|
||||
tempTexture = self.get_nth_child(i)
|
||||
x = (self.cover_gap + self.cover_size) * i
|
||||
y = (i % self.num_rows) * self.cover_size
|
||||
tempTexture.set_position(x, y)"""
|
||||
|
||||
class customBin:
|
||||
|
||||
def __init__(self):
|
||||
self.gstInit()
|
||||
|
||||
def gstInit(self):
|
||||
self.texture = gobject.new(cluttergst.VideoTexture, tiled=False) # , "sync-size=False"
|
||||
|
||||
#self.texture = clutter.Texture() #cluttergst.VideoTexture()
|
||||
self.texture.set_property("sync-size", False)
|
||||
|
||||
# declare our pipeline and GST elements
|
||||
self.pipeline = gst.Pipeline("mypipeline")
|
||||
"""
|
||||
|
||||
self.src = gst.element_factory_make("filesrc", "src");
|
||||
self.src.set_property("location", "test.mpg")
|
||||
self.demux = gst.element_factory_make("ffdemux_mpegts", "demux")
|
||||
self.queue1 = gst.element_factory_make("queue", "queue1")
|
||||
self.queue2 = gst.element_factory_make("queue", "queue2")
|
||||
self.deinterlace = gst.element_factory_make("ffdeinterlace", "deinterlace")
|
||||
self.vdecode = gst.element_factory_make("mpeg2dec", "vdecode")
|
||||
self.adecode = gst.element_factory_make("mad", "adecode")
|
||||
#self.vsink = gst.element_factory_make("xvimagesink", "vsink")
|
||||
self.vsink = cluttergst.VideoSink(self.video_texture)
|
||||
self.asink = gst.element_factory_make("alsasink", "asink")
|
||||
"""
|
||||
self.src = gst.element_factory_make("videotestsrc", "src")
|
||||
#self.warp = gst.element_factory_make ("warptv", "warp")
|
||||
self.colorspace = gst.element_factory_make ("ffmpegcolorspace", "color")
|
||||
self.pipeline.add(self.colorspace)
|
||||
#self.demux = gst.element_factory_make("ffdemux_mpegts", "demux")
|
||||
self.sink = cluttergst.VideoSink (self.texture)
|
||||
#self.sink = gst.element_factory_make("autovideosink", "vsink")
|
||||
self.sink.set_property("qos", True)
|
||||
self.sink.set_property("sync", True)
|
||||
|
||||
# add elements to the pipeline
|
||||
self.pipeline.add(self.src)
|
||||
#self.pipeline.add(self.warp)
|
||||
#self.pipeline.add(self.demux)
|
||||
#self.pipeline.add(self.colorspace)
|
||||
self.pipeline.add(self.sink)
|
||||
|
||||
"""
|
||||
self.pipeline.add(self.demux)
|
||||
self.pipeline.add(self.queue1)
|
||||
self.pipeline.add(self.queue2)
|
||||
self.pipeline.add(self.vdecode)
|
||||
self.pipeline.add(self.deinterlace)
|
||||
self.pipeline.add(self.adecode)
|
||||
self.pipeline.add(self.vsink)
|
||||
self.pipeline.add(self.asink)
|
||||
|
||||
|
||||
# we can"t link demux until the audio and video pads are added
|
||||
# we need to listen for "pad-added" signals
|
||||
self.demux.connect("pad-added", self.on_pad_added)
|
||||
"""
|
||||
self.texture.set_width(200)
|
||||
self.texture.set_height(200)
|
||||
#self.pipeline.add_signal_watch()
|
||||
#self.pipeline.add_many(self.pipeline, self.src, self.warp, self.colorspace, self.sink)
|
||||
gst.element_link_many(self.src, self.sink) #self.warp, self.colorspace,
|
||||
# link all elements apart from demux
|
||||
#gst.element_link_many(self.src, self.demux)
|
||||
#gst.element_link_many(self.queue1, self.vsink) #self.vdecode, self.deinterlace,
|
||||
#gst.element_link_many(self.queue2, self.adecode, self.asink)
|
||||
|
||||
#self.pipeline.set_state(gst.STATE_PLAYING)
|
||||
|
||||
def on_pad_added(self, element, src_pad):
|
||||
caps = src_pad.get_caps()
|
||||
name = caps[0].get_name()
|
||||
# link demux to vdecode when video/mpeg pad added to demux
|
||||
if name == "video/mpeg":
|
||||
sink_pad = self.queue1.get_pad("sink")
|
||||
elif name == "audio/mpeg":
|
||||
sink_pad = self.queue2.get_pad("sink")
|
||||
else:
|
||||
return
|
||||
|
||||
if not sink_pad.is_linked():
|
||||
src_pad.link(sink_pad)
|
||||
|
||||
def startPlayback(self):
|
||||
# start playback
|
||||
self.pipeline.set_state(gst.STATE_PLAYING)
|
||||
|
||||
def get_texture(self):
|
||||
return self.texture
|
||||
|
||||
|
|
BIN
VideoPlayer.pyc
BIN
VideoPlayer.pyc
Binary file not shown.
Loading…
Reference in New Issue