Created
December 24, 2009 16:15
-
-
Save Eugeny/263249 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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