Polished off TV playback code. Now terminates cleanly (IE mythbackend doesn't segfault)

Spinner is now also working (Mostly)
This commit is contained in:
noisymime 2007-08-23 11:50:05 +00:00
parent 3157d9e078
commit 72ac4c6fdd
11 changed files with 131 additions and 38 deletions

View File

@ -184,8 +184,7 @@ class Menu:
else: else:
#move the selection bar #move the selection bar
self.menuMgr.get_selector_bar().selectItem(self.menuItems[self.selected], self.timeline) self.menuMgr.get_selector_bar().selectItem(self.menuItems[self.selected], self.timeline)
self.timeline.start() self.timeline.start()
self.moveQueue = 0 self.moveQueue = 0
@ -196,7 +195,7 @@ class Menu:
self.selectPrevious() self.selectPrevious()
def selectFirst(self, moveBar): def selectFirst(self, moveBar):
self.timeline = clutter.Timeline(15, 75) self.timeline = clutter.Timeline(1, 75)
self.selected = 0 self.selected = 0
for i in range(0,len(self.menuItems)): for i in range(0,len(self.menuItems)):
if i == 0: if i == 0:

BIN
Menu.pyc

Binary file not shown.

View File

@ -197,14 +197,42 @@ class MenuSelector(clutter.Texture):
self.menu = menu self.menu = menu
def set_spinner(self, state): def set_spinner(self, state):
self.timeline = clutter.Timeline(25, 25)
self.alpha = clutter.Alpha(self.timeline, clutter.ramp_inc_func)
self.behaviour = clutter.BehaviourOpacity(self.alpha, 0,255)
if state: if state:
self.spinner = Spinner() self.spinner = Spinner()
height = self.get_height() - int(self.get_height() * 0.11)
#Height has to be even otherwise spinner rotates on a slightly off axis
if (height % 2) == 1:
height = height -1
width = height
self.spinner.set_size(width, height)
(x, y) = self.get_abs_position()
x = x + self.get_width() - int(self.get_width() * 0.11)
y = y + int(self.get_height() * 0.05)
self.spinner.set_position(x, y)
self.spinner.set_opacity(0)
self.spinner.show() self.spinner.show()
self.menuMgr.get_stage().add(self.spinner) self.menuMgr.get_stage().add(self.spinner)
self.behaviour = clutter.BehaviourOpacity(self.alpha, 0,255)
self.spinner.start()
else: else:
self.menuMgr.get_stage().remove(self.spinner) self.behaviour = clutter.BehaviourOpacity(self.alpha, 255,0)
self.spinner = None self.timeline.connect('completed', self.spinner_end_event)
#self.menuMgr.get_stage().remove(self.spinner)
#self.spinner = None
self.behaviour.apply(self.spinner)
self.timeline.start()
def spinner_end_event(self, data):
self.menuMgr.get_stage().remove(self.spinner)
self.spinner = None
def get_x_offset(self): def get_x_offset(self):
return self.x_offset return self.x_offset

Binary file not shown.

View File

@ -9,12 +9,15 @@ class Spinner (clutter.Texture):
#self.texture = clutter.Texture() #self.texture = clutter.Texture()
pixbuf = gtk.gdk.pixbuf_new_from_file("ui/spinner.svg") pixbuf = gtk.gdk.pixbuf_new_from_file("ui/spinner.svg")
self.set_pixbuf(pixbuf) self.set_pixbuf(pixbuf)
timeline = clutter.Timeline(40,20) def start(self):
timeline.set_loop(True) self.timeline = clutter.Timeline(40,20)
alpha = clutter.Alpha(timeline, clutter.ramp_inc_func) self.timeline.set_loop(True)
alpha = clutter.Alpha(self.timeline, clutter.ramp_inc_func)
spin_behaviour = clutter.BehaviourRotate(alpha, clutter.Z_AXIS, clutter.ROTATE_CW, 0, 359) spin_behaviour = clutter.BehaviourRotate(alpha, clutter.Z_AXIS, clutter.ROTATE_CW, 0, 359)
spin_behaviour.set_center(self.get_width()/2,self.get_height()/2, 0) spin_behaviour.set_center(self.get_width()/2,self.get_height()/2, 0)
spin_behaviour.apply(self) spin_behaviour.apply(self)
self.timeline.start()
timeline.start() def stop(self):
self.timeline.stop()

Binary file not shown.

View File

@ -2,6 +2,7 @@ import gst
import pygtk import pygtk
import pygst import pygst
import os import os
import clutter
from clutter import cluttergst from clutter import cluttergst
from myth.MythBackendConn import MythBackendConnection from myth.MythBackendConn import MythBackendConnection
@ -26,9 +27,13 @@ class TVPlayer:
#self.db_conn = mythVideoDB() #self.db_conn = mythVideoDB()
def begin(self, menuMgr): def begin(self, menuMgr):
self.menuMgr = menuMgr
#self.buffer_file_reader = open("test.mpg","r")
menuMgr.get_selector_bar().set_spinner(True)
(server, port) = self.dbMgr.get_backend_server() (server, port) = self.dbMgr.get_backend_server()
self.myConn = MythBackendConnection(self, server, port) self.myConn = MythBackendConnection(self, server, port)
self.myConn.start() self.myConn.start()
#self.begin_playback(self.buffer_file_reader.fileno())
def begin_playback(self, fd): def begin_playback(self, fd):
#self.video.set_filename("test.mpg") #self.video.set_filename("test.mpg")
@ -36,14 +41,23 @@ class TVPlayer:
#self.buffer_file = open("test.mpg","r") #self.buffer_file = open("test.mpg","r")
#fd = self.buffer_file.fileno() #fd = self.buffer_file.fileno()
#print os.read(fd, 100) #print os.read(fd, 100)
""" self.menuMgr.get_selector_bar().set_spinner(False)
self.video.set_uri("fd://"+str(fd)) self.video.set_uri("fd://"+str(fd))
#self.video.set_property("fullscreen", True)
self.video.set_opacity(0)
self.video.show() self.video.show()
timeline = clutter.Timeline(15, 25)
alpha = clutter.Alpha(timeline, clutter.ramp_inc_func)
behaviour = clutter.BehaviourOpacity(alpha, 0,255)
behaviour.apply(self.video)
self.stage.add(self.video) self.stage.add(self.video)
self.video.set_playing(True) self.video.set_playing(True)
timeline.start()
return None""" return None
"""
self.pipeline = gst.Pipeline("mypipeline") self.pipeline = gst.Pipeline("mypipeline")
self.pbin = gst.element_factory_make("playbin", "pbin"); self.pbin = gst.element_factory_make("playbin", "pbin");
self.pbin.set_property("uri", "fd://"+str(fd)) self.pbin.set_property("uri", "fd://"+str(fd))
@ -51,10 +65,27 @@ class TVPlayer:
# add elements to the pipeline # add elements to the pipeline
self.pipeline.add(self.pbin) self.pipeline.add(self.pbin)
self.pipeline.set_state(gst.STATE_PLAYING) self.pipeline.set_state(gst.STATE_PLAYING)
"""
def stop(self):
if self.video.get_playing():
self.video.set_playing(False)
self.myConn.stop()
timeline = clutter.Timeline(15, 25)
timeline.connect('completed', self.end_video_event)
alpha = clutter.Alpha(timeline, clutter.ramp_inc_func)
behaviour = clutter.BehaviourOpacity(alpha, 255,0)
behaviour.apply(self.video)
timeline.start()
def end_video_event(self, data):
self.stage.remove(self.video)
def on_key_press_event (self, stage, event): def on_key_press_event (self, stage, event):
#print event.hardware_keycode #print event.hardware_keycode
#self.myConn.stop()
"""if event.keyval == clutter.keysyms.p: """if event.keyval == clutter.keysyms.p:
if self.paused: if self.paused:
self.unpause() self.unpause()

Binary file not shown.

View File

@ -82,6 +82,8 @@ class MainApp:
self.menu2.getItem(1).setAction(self.menu1) self.menu2.getItem(1).setAction(self.menu1)
#print self.menuMgr.get_selector_bar().get_abs_position()
#self.menuMgr.get_selector_bar().set_spinner(True)
def on_button_press_event (self, stage, event): def on_button_press_event (self, stage, event):

View File

@ -1,6 +1,7 @@
import socket import socket
import time import time
import threading import threading
import thread
import os import os
class MythBackendConnection(threading.Thread): class MythBackendConnection(threading.Thread):
@ -12,13 +13,16 @@ class MythBackendConnection(threading.Thread):
self.server_port = port #6543 self.server_port = port #6543
self.addr = (self.server, self.server_port) self.addr = (self.server, self.server_port)
self.videoPlayer = videoPlayer self.videoPlayer = videoPlayer
self.lock = False #Dictakes whether or not we have a signal lock
#2 Sockets, 1 for cmds, 1 for data #3 Sockets, 1 for cmds, 1 for data, 1 for monitoring messages
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.data_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.data_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.data_sock.connect((self.server, self.server_port)) self.data_sock.connect((self.server, self.server_port))
#self.data_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.msg_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#self.data_sock.bind( ("127.0.0.1", self.server_port) ) self.msg_sock.connect((self.server, self.server_port))
thread.start_new_thread(self.message_socket_mgr,(self.msg_sock,))
#self.sock.connect( ("192.168.0.8", 6543) ) #self.sock.connect( ("192.168.0.8", 6543) )
self.connected = False self.connected = False
@ -52,19 +56,6 @@ class MythBackendConnection(threading.Thread):
sock.send(cmd) sock.send(cmd)
#print "write-->" + cmd #print "write-->" + cmd
"""def send_datagram(self, sock, base_cmd):
cmd = str(len(base_cmd)).ljust(8) + base_cmd
#sock.sendto(cmd, self.addr)
sock.sendto(cmd, ("192.168.0.8", 6543) )
def receive_datagram(self, sock):
ret = ""
data, addr = sock.recvfrom(8)
count = int(data)
#debug("REPLY LEN: %d" % count)
ret, addr = sock.recvfrom(count)
return ret
"""
def connect(self, host, port): def connect(self, host, port):
self.sock.connect((host, port)) self.sock.connect((host, port))
@ -138,6 +129,8 @@ class MythBackendConnection(threading.Thread):
#This is just a hack to make sure the channel has locked, I'll fix it later #This is just a hack to make sure the channel has locked, I'll fix it later
time.sleep(5) time.sleep(5)
#while not self.lock:
# pass
#Get the recording filename #Get the recording filename
filename_string = "QUERY_RECORDER "+str(self.recorder)+"[]:[]GET_CURRENT_RECORDING" filename_string = "QUERY_RECORDER "+str(self.recorder)+"[]:[]GET_CURRENT_RECORDING"
@ -155,8 +148,8 @@ class MythBackendConnection(threading.Thread):
result = self.receive_reply(self.data_sock) result = self.receive_reply(self.data_sock)
#result = self.receive_datagram(self.data_sock) #result = self.receive_datagram(self.data_sock)
result_list = result.rsplit("[]:[]") result_list = result.rsplit("[]:[]")
data_socket_id = result_list[1] self.data_socket_id = result_list[1]
print "Socket ID: " + str(data_socket_id) #print "Socket ID: " + str(data_socket_id)
#Do some housekeeping #Do some housekeeping
frontend_ready_cmd = "QUERY_RECORDER "+str(self.recorder) +"[]:[]FRONTEND_READY" frontend_ready_cmd = "QUERY_RECORDER "+str(self.recorder) +"[]:[]FRONTEND_READY"
@ -170,16 +163,12 @@ class MythBackendConnection(threading.Thread):
result = self.receive_reply(self.sock) result = self.receive_reply(self.sock)
#Start a recording thread #Start a recording thread
self.buffer_live(self.sock, self.data_sock, data_socket_id) self.buffer_live(self.sock, self.data_sock, self.data_socket_id)
def buffer_live(self, cmd_sock, data_sock, socket_id): def buffer_live(self, cmd_sock, data_sock, socket_id):
#Create a buffer file #Create a buffer file
self.buffer_file = open("test.mpg","w") self.buffer_file = open("test.mpg","w")
request_size = 32768
#read some data
request_size = 32768
#Need to create a bit of a buffer so playback will begin #Need to create a bit of a buffer so playback will begin
x=0 x=0
@ -190,7 +179,7 @@ class MythBackendConnection(threading.Thread):
data = data_sock.recv(num_bytes) data = data_sock.recv(num_bytes)
self.buffer_file.write(data) self.buffer_file.write(data)
x=x+1 x=x+1
self.buffer_file.flush()
self.buffer_file_reader = open("test.mpg","r") self.buffer_file_reader = open("test.mpg","r")
self.videoPlayer.begin_playback(self.buffer_file_reader.fileno()) self.videoPlayer.begin_playback(self.buffer_file_reader.fileno())
#self.videoPlayer.begin_playback(self.data_sock.fileno()) #self.videoPlayer.begin_playback(self.data_sock.fileno())
@ -206,6 +195,40 @@ class MythBackendConnection(threading.Thread):
print "Ending playback" print "Ending playback"
self.buffer_file.close() self.buffer_file.close()
def message_socket_mgr(self, msg_socket):
#Do the protocol version check
print "Starting the msg thread"
protString = "MYTH_PROTO_VERSION "+ str(self.protocolVersion)
self.send_cmd(self.msg_sock, protString)
protRecvString = "ACCEPT[]:[]" + str(self.protocolVersion)
result = self.receive_reply(self.msg_sock)
print result
if not result == protRecvString:
#Protocol Version check failed
raise RuntimeError, "Myth Protocol version failure. Aborting."
#Perform the mandatory ANN (The 1 at the end says that we want to receive all messages from the server)
ANNstring = "ANN Monitor " + self.localhost_name + " 1"
self.send_cmd(self.msg_sock, ANNstring)
ANN_recv_string = "OK" #What a successful return should be
result = self.receive_reply(self.msg_sock)
if not result == ANN_recv_string:
raise RuntimeError, "Myth: ANN connection failed"
while not self.lock:
#ANN_recv_string = "OK" #What a successful return should be
result = self.receive_reply(self.msg_sock)
result_list = result.rsplit("[]:[]")
print result
if result_list[1] == "RECORDING_LIST_CHANGE":
#print resul
self.lock = True
def change_channel(self):
if self.Playing:
pass #self.Playing = False
def end_stream(self): def end_stream(self):
self.stream = False self.stream = False
@ -213,3 +236,10 @@ class MythBackendConnection(threading.Thread):
def stop(self): def stop(self):
self.Playing = False self.Playing = False
stop_cmd = "QUERY_RECORDER "+str(self.recorder) +"[]:[]STOP_LIVETV"
self.send_cmd(self.sock, stop_cmd)
result = self.receive_reply(self.sock)
end_transfer_cmd = "QUERY_FILETRANSFER "+str(self.data_socket_id) +"[]:[]DONE"
self.send_cmd(self.sock, end_transfer_cmd)
result = self.receive_reply(self.sock)

Binary file not shown.