Skip to content

Instantly share code, notes, and snippets.

@Eugeny
Created December 24, 2009 16:15
Show Gist options
  • Save Eugeny/263249 to your computer and use it in GitHub Desktop.
Save Eugeny/263249 to your computer and use it in GitHub Desktop.
import sys, os
import gtk
import commands
import gst
import glut
import time
import thread
import threading
import util
import gl
import pygame
import settings
import log
Xv = None
window = None
movie_window = None
time_format = None
player = None
gtktrd = None
Active = False
AudioStream = 0
TextStream = 0
AudioCount = 0
TextCount = 0
ProgressBar = None
ExitUpdaterThread = False
TimeLabelA = None
TimeLabelB = None
Panel = None
Panel2 = None
PanelY = 0
PanelTime = 0
Volume = 1.0
def Init():
global window, player, time_format, movie_window, ProgressBar, Overlay, Xv
log.info('Video', 'Using ' + gst.version_string())
gtk.rc_parse(settings.Path + 'gtk/gtkrc')
gtk.gdk.threads_init()
log.info('Video', 'Creating output window')
InitWindow()
SetupUI()
xv = gst.element_factory_make('xvimagesink')
Xv = xv
#xv = gst.element_factory_make('sdlvideosink')
log.info('Video', 'Creating pipeline')
player = gst.element_factory_make("playbin2")
player.set_property('video-sink', xv)
player.set_property('audio-sink', gst.element_factory_make('alsasink'))
player.set_property('flags', 7+16)
bus = player.get_bus()
bus.add_signal_watch()
bus.enable_sync_message_emission()
bus.connect("message", on_message)
bus.connect("sync-message::element", on_sync_message)
time_format = gst.Format(gst.FORMAT_TIME)
return
def InitWindow():
global window
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_title("LMC")
window.set_default_size(glut.Width, glut.Height)
window.fullscreen()
return
def SetupUI():
global window, movie_window, ProgressBar, TimeLabelA, TimeLabelB, Panel
vbox = gtk.VBox()
window.add(vbox)
window.connect('key-press-event', on_keypress)
movie_window = gtk.DrawingArea()
vbox.add(movie_window)
vb = gtk.VBox()
ProgressBar = gtk.ProgressBar()
vb.add(ProgressBar)
vbox.pack_start(vb, False)
fx = gtk.Fixed()
fx.set_size_request(glut.Width, 46)
vb.add(fx)
folder = settings.Path + 'skins/' + settings.Skin
BtnStart = gtk.Button()
BtnStart.set_size_request(40, 40)
i = gtk.Image()
i.set_from_file(folder + '/keys/ok_sm.png')
BtnStart.set_image(i)
i.show_all()
BtnRew = gtk.Button()
BtnRew.set_size_request(40, 40)
i = gtk.Image()
i.set_from_file(folder + '/keys/left_sm.png')
BtnRew.set_image(i)
i.show_all()
BtnFwd = gtk.Button()
BtnFwd.set_size_request(40, 40)
i = gtk.Image()
i.set_from_file(folder + '/keys/right_sm.png')
BtnFwd.set_image(i)
i.show_all()
BtnClose = gtk.Button()
BtnClose.set_size_request(40, 40)
i = gtk.Image()
i.set_from_file(folder + '/keys/back_sm.png')
BtnClose.set_image(i)
i.show_all()
b = gtk.Button()
b.set_size_request(30, 30)
i = gtk.Image()
i.set_from_file(folder + '/keys/up_sm.png')
b.set_image(i)
i.show_all()
fx.put(b, 170, 8)
b = gtk.Button()
b.set_size_request(30, 30)
i = gtk.Image()
i.set_from_file(folder + '/keys/sound_sm.png')
b.set_image(i)
i.show_all()
fx.put(b, 200, 8)
b = gtk.Button()
b.set_size_request(30, 30)
i = gtk.Image()
i.set_from_file(folder + '/keys/down_sm.png')
b.set_image(i)
i.show_all()
fx.put(b, 230, 8)
fx.put(BtnStart, 3, 3)
fx.put(BtnRew, 70, 3)
fx.put(BtnFwd, 110, 3)
fx.put(BtnClose, glut.Width - 43, 3)
TimeLabelA = gtk.Label()
TimeLabelB = gtk.Label()
fx.put(TimeLabelA, glut.Width - 300, 13)
fx.put(TimeLabelB, glut.Width - 230, 13)
vbox.modify_bg(gtk.STATE_NORMAL | gtk.STATE_ACTIVE, gtk.gdk.color_parse('#000000'))
movie_window.modify_bg(gtk.STATE_NORMAL | gtk.STATE_ACTIVE, gtk.gdk.color_parse('#000000'))
ProgressBar.modify_bg(gtk.STATE_NORMAL | gtk.STATE_ACTIVE, gtk.gdk.color_parse('#000000'))
window.set_keep_above(True)
window.set_decorated(False)
Panel = fx
return
def Show():
global window, Active
gl.Slowdown = True
window.show_all()
window.fullscreen()
window.present()
Active = True
return
def Hide():
global window, Active, ExitUpdaterThread, Xv
Xv.set_xwindow_id(0)
gl.Slowdown = False
ExitUpdaterThread = False
Stop()
window.hide()
gl.Slowdown = False
Active = False
return
def OpenFile(file):
global player, ExitUpdaterThread
InitWindow()
SetupUI()
Show()
time.sleep(0.5)
player.set_property('uri', 'file://' + file.replace('#','%23'))
player.set_property('subtitle-encoding', 'windows-1251')
s = os.path.splitext(file.replace('#','%23'))[0] + '.srt'
if (os.path.exists(s)):
player.set_property('suburi', 'file://' + s)
s = os.path.splitext(file.replace('#','%23'))[0] + '.ssa'
if (os.path.exists(s)):
player.set_property('suburi', 'file://' + s)
s = os.path.splitext(file.replace('#','%23'))[0] + '.ass'
if (os.path.exists(s)):
player.set_property('suburi', 'file://' + s)
Play()
ExitUpdaterThread = False
thread.start_new_thread(Updater, ())
TriggerPanel()
return
def TriggerPanel():
global PanelTime
PanelTime = 80
return
def TogglePause():
global player
if (gst.STATE_PLAYING in player.get_state()):
player.set_state(gst.STATE_PAUSED)
elif(gst.STATE_PAUSED in player.get_state()):
player.set_state(gst.STATE_PLAYING)
TriggerPanel()
return
def Forward(secs):
global player, time_format
try:
pos_int = player.query_position(time_format, None)[0]
seek_ns = pos_int + (secs * 1000000000)
player.seek_simple(time_format, gst.SEEK_FLAG_FLUSH, seek_ns)
log.info('Video', 'Seeking: ' + str(seek_ns))
TriggerPanel()
except:
pass
return
def Rewind(secs):
global player, time_format
try:
pos_int = player.query_position(time_format, None)[0]
seek_ns = pos_int - (secs * 1000000000)
player.seek_simple(time_format, gst.SEEK_FLAG_FLUSH, seek_ns)
log.info('Video', 'Seeking: ' + str(seek_ns))
TriggerPanel()
except:
pass
return
def Stop():
global player
player.set_state(gst.STATE_NULL)
log.info('Video', 'Stopped')
return
def Pause():
global player
player.set_state(gst.STATE_PAUSED)
log.info('Video', 'Paused')
TriggerPanel()
return
def Play():
global player
player.set_state(gst.STATE_PLAYING)
log.info('Video', 'Playing')
TriggerPanel()
return
def NextAudio():
global player, AudioStream, AudioCount
AudioStream = player.get_property('current-audio') + 1
if (AudioStream == AudioCount):
AudioStream = 0
player.set_property('current-audio', int(AudioStream))
log.info('Video', 'Switched to audio stream #' + str(AudioStream))
Play()
Rewind(0)
return
def NextText():
global player, TextStream, TextCount
TextStream += 1
if (TextStream == TextCount):
TextStream = -1
if (TextStream == -1):
player.set_property('flags', 3+16)
log.info('Video', 'Disabled subtitles')
else:
player.set_property('flags', 7+16)
player.set_property('current-text', TextStream)
log.info('Video', 'Switched to embedded subtitles #' + str(TextStream))
Play()
Rewind(0) # Required for subtitles to be applied
return
def Close():
global ExitUpdaterThread
log.info('Video', 'Closing')
ExitUpdaterThread = True
Stop()
Hide()
return
def VolumeUp():
global Volume, player
if (Volume < 2.0): Volume += 0.1
player.set_property('volume', Volume)
log.info('Video', 'Volume: ' + str(Volume))
return
def VolumeDown():
global Volume, player
if (Volume > 0.2): Volume -= 0.1
player.set_property('volume', Volume)
log.info('Video', 'Volume: ' + str(Volume))
return
def on_message(bus, message):
global player
t = message.type
if t == gst.MESSAGE_ERROR:
err, debug = message.parse_error()
log.err('Video', err)
log.err('Video', debug)
player.set_state(gst.STATE_NULL)
return
def on_sync_message(bus, message):
global gtktrd, window, movie_window, AudioCount, TextCount
if message.structure is None:
return
if message.structure.get_name() == "prepare-xwindow-id":
imagesink = message.src
imagesink.set_property("force-aspect-ratio", True) #TODO: make switchable
imagesink.set_xwindow_id(movie_window.window.xid)
AudioCount = player.get_property('n-audio')
TextCount = player.get_property('n-text')
log.info('Video', 'Attached output to window XID ' + str(movie_window.window.xid))
# Ensure gtk.main() is running
if (gtktrd == None or not gtktrd.isAlive()):
gtktrd = threading.Thread(None, gtk.main, None)
gtktrd.start()
return
#Deprecated
def on_keypress(widget, event):
if (event.keyval == 65293):
HandleKey('ok')
if (event.keyval == 65361):
HandleKey('left')
if (event.keyval == 65363):
HandleKey('right')
if (event.keyval == 65362):
HandleKey('up')
if (event.keyval == 65364):
HandleKey('down')
if (event.keyval == 65288):
HandleKey('back')
if (event.keyval == 97):
HandleKey('a')
if (event.keyval == 116):
HandleKey('text')
return True
def Updater():
global ExitUpdaterThread, ProgressBar, time_format, TimeLabelA, TimeLabelB
global PanelTime, PanelY
i = 0
while (not ExitUpdaterThread):
i += 1
i %= 10
try:
p = player.query_position(time_format, None)[0]
d = player.query_duration(time_format, None)[0]
TimeLabelA.set_text(util.GetTimeString(p))
TimeLabelB.set_text('/ ' + util.GetTimeString(d))
try:
ProgressBar.set_fraction(1.0 * p / d)
except:
pass
except:
pass
if (PanelTime > 0 and PanelY < 46):
PanelY += 6
if (PanelTime > 0):
PanelTime -=1
if (PanelTime == 0 and PanelY > 0):
PanelY -= 8
try:
Panel.set_size_request(glut.Width, PanelY)
except:
pass
time.sleep(0.05)
return
def HandleKey(name):
if (name == 'ok'):
TogglePause()
if (name =='left'):
Rewind(15)
if (name == 'right'):
Forward(15)
if (name == 'back'):
Close()
if (name == 'a'):
NextAudio()
if (name == 'text'):
NextText()
if (name == 'up'):
VolumeUp()
if (name == 'down'):
VolumeDown()
return
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment