|
|
|
@ -7,135 +7,80 @@ import time
|
|
|
|
|
import genericThread |
|
|
|
|
import config |
|
|
|
|
import fileio |
|
|
|
|
|
|
|
|
|
playState = True; |
|
|
|
|
durationState = 0; |
|
|
|
|
positionState = 0; |
|
|
|
|
import ui |
|
|
|
|
|
|
|
|
|
omx = genericThread.genericThread ( 1, "OMX", 1); |
|
|
|
|
state = genericThread.genericThread ( 2, "State", 2); |
|
|
|
|
stateRun = True; |
|
|
|
|
live=False; |
|
|
|
|
|
|
|
|
|
def startOMX ( argv ): |
|
|
|
|
global stateRun |
|
|
|
|
argv=argv[0]; |
|
|
|
|
argv.insert ( 0, "omxplayer" ) |
|
|
|
|
argv.append ( "--win"); |
|
|
|
|
(x,y,x2,y2) = sizeCalc(); |
|
|
|
|
argv.append( str(x)+","+str(y)+","+str(x2)+","+str(y2) ) |
|
|
|
|
argv.append ( "-o"); |
|
|
|
|
argv.append("local"); |
|
|
|
|
argv.append("--aspect-mode"); |
|
|
|
|
argv.append("letterbox"); |
|
|
|
|
subprocess.run ( argv ); |
|
|
|
|
stateRun = False; |
|
|
|
|
|
|
|
|
|
def callDBus ( param ): |
|
|
|
|
try: |
|
|
|
|
param.insert ( 0, config.dbusconfig ); |
|
|
|
|
param.insert ( 0, "bash" ); |
|
|
|
|
out = subprocess.check_output ( param ) |
|
|
|
|
return out; |
|
|
|
|
except subprocess.CalledProcessError: |
|
|
|
|
return b""; |
|
|
|
|
|
|
|
|
|
def playCb(ptr): |
|
|
|
|
callDBus ( ["pause"] ); |
|
|
|
|
getState( None ); |
|
|
|
|
global playState |
|
|
|
|
global playBtn |
|
|
|
|
if ( playState == True ): |
|
|
|
|
playBtn.label ("@||"); |
|
|
|
|
else : |
|
|
|
|
playBtn.label("@>"); |
|
|
|
|
|
|
|
|
|
def resizeCb (): |
|
|
|
|
(x,y,x2,y2) = sizeCalc() |
|
|
|
|
|
|
|
|
|
status = callDBus ( ["status"] ); |
|
|
|
|
times = 0; |
|
|
|
|
while (status=="" and times < 5) : |
|
|
|
|
status = callDBus ( ["status"] ); |
|
|
|
|
time.sleep ( 0.5 ); |
|
|
|
|
times = times + 1; |
|
|
|
|
stream = argv.pop(); |
|
|
|
|
|
|
|
|
|
if ( times < 5 ): |
|
|
|
|
callDBus (["setvideopos", str(x), str(y), str(x2), str(y2)]); |
|
|
|
|
i = 0; |
|
|
|
|
output = "local" |
|
|
|
|
while ( i < len(argv) ): |
|
|
|
|
if ( argv[i] =="-o"): |
|
|
|
|
if ( argv[i+1] == "local" or argv[i+1] == "hdmi" ): |
|
|
|
|
output=argv[i+1]; |
|
|
|
|
else: |
|
|
|
|
output="local" |
|
|
|
|
i = i + 1 |
|
|
|
|
|
|
|
|
|
(x,y,x2,y2) = ui.sizeCalc(); |
|
|
|
|
argv = [ "omxplayer", "--win", str(x)+","+str(y)+","+str(x2)+","+str(y2), "-o", output, "--aspect-mode", "letterbox", stream ]; |
|
|
|
|
subprocess.run ( argv ); |
|
|
|
|
stateRun = False; |
|
|
|
|
|
|
|
|
|
def sizeCalc ( ): |
|
|
|
|
global window |
|
|
|
|
x = window.x(); |
|
|
|
|
y = window.y(); |
|
|
|
|
w = window.w(); |
|
|
|
|
h = window.h(); |
|
|
|
|
def startOMXLive ( argv ): |
|
|
|
|
global stateRun |
|
|
|
|
quality=argv[1]; |
|
|
|
|
argv=argv[0]; |
|
|
|
|
|
|
|
|
|
#x=x+2; |
|
|
|
|
#y=y+2; |
|
|
|
|
x2 = x + w; |
|
|
|
|
y2 = y + h - 75; |
|
|
|
|
stream = argv.pop(); |
|
|
|
|
|
|
|
|
|
return (x,y,x2,y2); |
|
|
|
|
|
|
|
|
|
def DecodeState ( param ): |
|
|
|
|
global playState; |
|
|
|
|
global durationState; |
|
|
|
|
global positionState; |
|
|
|
|
i=0 |
|
|
|
|
while (i < len(param)) : |
|
|
|
|
m = re.search ( "Duration: ([0-9]+)", param[i] ); |
|
|
|
|
if ( m is None ): |
|
|
|
|
m = re.search ( "Position: ([0-9]+)", param[i] ); |
|
|
|
|
if ( m is None ): |
|
|
|
|
m = re.search ( "Paused: (true|false)", param[i] ); |
|
|
|
|
if ( m is None ) : |
|
|
|
|
pass; |
|
|
|
|
else : |
|
|
|
|
playState = ( m.group(1) == "false"); |
|
|
|
|
i = 0; |
|
|
|
|
output = "local" |
|
|
|
|
while ( i < len(argv) ): |
|
|
|
|
if ( argv[i] =="-o"): |
|
|
|
|
if ( argv[i+1] == "local" or argv[i+1] == "hdmi" ): |
|
|
|
|
output=argv[i+1]; |
|
|
|
|
else: |
|
|
|
|
positionState = int ( m.group(1) ); |
|
|
|
|
else: |
|
|
|
|
durationState = int ( m.group(1) ); |
|
|
|
|
i=i+1 |
|
|
|
|
|
|
|
|
|
def timeOut ( time ) : |
|
|
|
|
time = int(time / 1000000); # mikrosec -> sec |
|
|
|
|
hours = int(time / 3600); |
|
|
|
|
minutes = int((time / 60)) - hours*60; |
|
|
|
|
sec = time - minutes*60 - hours*360; |
|
|
|
|
|
|
|
|
|
return ( str(hours).zfill(2) + ":" + str(minutes).zfill(2) + ":" +str(sec).zfill(2) ); |
|
|
|
|
|
|
|
|
|
def setPosition ( pos ): |
|
|
|
|
callDBus ( ["setposition", str(pos)] ); |
|
|
|
|
getState ( None ); |
|
|
|
|
|
|
|
|
|
def getState ( ptr ) : |
|
|
|
|
status = callDBus ( ["status"] ); |
|
|
|
|
status = status.decode("utf-8").split("\n") |
|
|
|
|
DecodeState ( status ); |
|
|
|
|
output="local" |
|
|
|
|
i = i + 1 |
|
|
|
|
|
|
|
|
|
(x,y,x2,y2) = ui.sizeCalc(); |
|
|
|
|
argv = [ "livestreamer", stream, quality, "-np", |
|
|
|
|
"omxplayer --win "+str(x)+","+str(y)+","+str(x2)+","+str(y2)+" -o "+output+" --aspect-mode letterbox --live" ]; |
|
|
|
|
print (argv); |
|
|
|
|
subprocess.run ( argv ); |
|
|
|
|
stateRun = False; |
|
|
|
|
|
|
|
|
|
statusLabel.value ( timeOut ( positionState ) + " / " + timeOut ( durationState ) ); |
|
|
|
|
if ( durationState == 0): |
|
|
|
|
statusProgress.value(0); |
|
|
|
|
else : |
|
|
|
|
statusProgress.value( positionState / durationState ); |
|
|
|
|
|
|
|
|
|
stateRun = True; |
|
|
|
|
def thread_state ( args ) : |
|
|
|
|
global stateRun; |
|
|
|
|
while ( stateRun == True ): |
|
|
|
|
getState( None ); |
|
|
|
|
time.sleep (1); |
|
|
|
|
global stateRun |
|
|
|
|
global live |
|
|
|
|
beginTime = int(time.time()); |
|
|
|
|
if ( live == False ): |
|
|
|
|
while ( stateRun == True ): |
|
|
|
|
ui.getState( None ); |
|
|
|
|
time.sleep (1); |
|
|
|
|
else : |
|
|
|
|
while ( stateRun == True ): |
|
|
|
|
ui.statusLabel.value ( "Uptime: " + ui.timeOut ( (int(time.time()) - beginTime)*1000000 )) |
|
|
|
|
time.sleep(1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def killAll ( ptr ): |
|
|
|
|
global stateRun; |
|
|
|
|
global cfg |
|
|
|
|
global window |
|
|
|
|
def killAll ( cfg ): |
|
|
|
|
global stateRun |
|
|
|
|
stateRun = False; |
|
|
|
|
callDBus ( ["stop"] ); |
|
|
|
|
cfg["WindowX"] = window.x(); |
|
|
|
|
cfg["WindowY"] = window.y(); |
|
|
|
|
cfg["WindowWidth"] = window.w(); |
|
|
|
|
cfg["WindowHeight"] = window.h(); |
|
|
|
|
ui.callDBus ( ["stop"] ); |
|
|
|
|
cfg["WindowX"] = ui.window.x(); |
|
|
|
|
cfg["WindowY"] = ui.window.y(); |
|
|
|
|
cfg["WindowWidth"] = ui.window.w(); |
|
|
|
|
cfg["WindowHeight"] = ui.window.h(); |
|
|
|
|
|
|
|
|
|
fileio.saveConfig ( config.configfile, cfg ); |
|
|
|
|
|
|
|
|
@ -145,125 +90,59 @@ def killAll ( ptr ):
|
|
|
|
|
|
|
|
|
|
def FLTK_run () : |
|
|
|
|
global stateRun |
|
|
|
|
global window |
|
|
|
|
global statusProgress |
|
|
|
|
x = window.x(); |
|
|
|
|
y = window.y(); |
|
|
|
|
w = window.w(); |
|
|
|
|
h = window.h(); |
|
|
|
|
while (stateRun == True and window.shown()): |
|
|
|
|
x = ui.window.x(); |
|
|
|
|
y = ui.window.y(); |
|
|
|
|
w = ui.window.w(); |
|
|
|
|
h = ui.window.h(); |
|
|
|
|
while (stateRun == True and ui.window.shown()): |
|
|
|
|
Fl.check(); |
|
|
|
|
if ( x != window.x() or y != window.y() or |
|
|
|
|
w != window.w() or h != window.h() ): |
|
|
|
|
resizeWindow (); |
|
|
|
|
if (Fl.event_button1() and Fl.event_inside ( statusProgress.x(), statusProgress.y(), statusProgress.x() + statusProgress.w(), statusProgress.y() + statusProgress.h() ) ): |
|
|
|
|
seekCb (); |
|
|
|
|
if ( x != ui.window.x() or y != ui.window.y() or |
|
|
|
|
w != ui.window.w() or h != ui.window.h() ): |
|
|
|
|
ui.resizeWindow (); |
|
|
|
|
if (Fl.event_button1() and |
|
|
|
|
Fl.event_inside ( ui.statusProgress.x(), |
|
|
|
|
ui.statusProgress.y(), |
|
|
|
|
ui.statusProgress.x() + ui.statusProgress.w(), |
|
|
|
|
ui.statusProgress.y() + ui.statusProgress.h() ) ): |
|
|
|
|
ui.seekCb (); |
|
|
|
|
time.sleep(0.1); # I don't want to burn that much cpu-time |
|
|
|
|
|
|
|
|
|
def resizeWindow ( ): |
|
|
|
|
global window; |
|
|
|
|
global playBtn |
|
|
|
|
global stateBtn |
|
|
|
|
global killBtn |
|
|
|
|
global statusLabel |
|
|
|
|
global statusProgress |
|
|
|
|
global volUp |
|
|
|
|
global volDown |
|
|
|
|
|
|
|
|
|
h = window.h() |
|
|
|
|
w = window.w() |
|
|
|
|
|
|
|
|
|
statusLabel.resize ( w-230, h-50, statusLabel.w(), statusLabel.h() ); |
|
|
|
|
playBtn.position ( 20, h-60 ); |
|
|
|
|
stateBtn.position ( 60, h-60); |
|
|
|
|
killBtn.position ( 100, h-60 ); |
|
|
|
|
|
|
|
|
|
volUp.position ( w - 40, h-50 ); |
|
|
|
|
volDown.position ( w - 60, h-50 ); |
|
|
|
|
statusProgress.position ( 160, h-50 ); |
|
|
|
|
statusProgress.size ( w - 410, 20 ); |
|
|
|
|
|
|
|
|
|
playBtn.redraw(); |
|
|
|
|
stateBtn.redraw(); |
|
|
|
|
killBtn.redraw(); |
|
|
|
|
#statusLabel.redraw(); |
|
|
|
|
statusProgress.redraw(); |
|
|
|
|
window.redraw(); |
|
|
|
|
|
|
|
|
|
resizeCb (); |
|
|
|
|
|
|
|
|
|
def seekCb (): |
|
|
|
|
global statusProgress; |
|
|
|
|
x = Fl.event_x(); |
|
|
|
|
x = x - statusProgress.x(); |
|
|
|
|
dim = x / statusProgress.w(); |
|
|
|
|
positionState = durationState * dim; |
|
|
|
|
setPosition ( positionState ); |
|
|
|
|
|
|
|
|
|
def volUpCb ( ptr ): |
|
|
|
|
callDBus ( ["volumeup"] ); |
|
|
|
|
|
|
|
|
|
def volDownCb ( ptr ): |
|
|
|
|
callDBus ( ["volumedown"] ); |
|
|
|
|
|
|
|
|
|
if ( len ( sys.argv ) <= 1 ): |
|
|
|
|
print ("Usage: " + sys.argv[0] + "[omxplayer-arguments] FILENAME"); |
|
|
|
|
sys.exit(0); |
|
|
|
|
|
|
|
|
|
omx.setFn ( startOMX, [sys.argv[1:]] ); |
|
|
|
|
state.setFn ( thread_state, [] ); |
|
|
|
|
|
|
|
|
|
cfg = fileio.getConfig ( config.configfile ); |
|
|
|
|
|
|
|
|
|
window = Fl_Window( cfg.get("WindowX", 100) , cfg.get("WindowY", 100), cfg.get("WindowWidth", 640), cfg.get("WindowHeight", 480)) |
|
|
|
|
window.label(sys.argv[0]) |
|
|
|
|
window.size_range ( 320, 240, 0, 0); |
|
|
|
|
|
|
|
|
|
# start omx-player |
|
|
|
|
omx.start(); |
|
|
|
|
|
|
|
|
|
playBtn = Fl_Button(20, 420, 40, 40) |
|
|
|
|
playBtn.labeltype(FL_SYMBOL_LABEL) |
|
|
|
|
playBtn.label("@||") |
|
|
|
|
playBtn.callback(playCb) |
|
|
|
|
playBtn.box ( FL_THIN_UP_BOX ); |
|
|
|
|
|
|
|
|
|
stateBtn = Fl_Button ( 60, 420, 40, 40 ); |
|
|
|
|
stateBtn.label("?") |
|
|
|
|
stateBtn.callback(getState) |
|
|
|
|
stateBtn.box ( FL_THIN_UP_BOX ); |
|
|
|
|
|
|
|
|
|
killBtn = Fl_Button ( 100, 420, 40, 40 ); |
|
|
|
|
killBtn.label ("x"); |
|
|
|
|
killBtn.callback ( killAll ); |
|
|
|
|
killBtn.box ( FL_THIN_UP_BOX ); |
|
|
|
|
|
|
|
|
|
statusLabel = Fl_Output ( 410, 430, 150, 20 ); |
|
|
|
|
statusLabel.label (""); |
|
|
|
|
statusLabel.box ( FL_FLAT_BOX ); |
|
|
|
|
|
|
|
|
|
statusProgress = Fl_Progress ( 160, 430, 230, 20 ); |
|
|
|
|
statusProgress.box( FL_FLAT_BOX ); |
|
|
|
|
statusProgress.minimum(0); |
|
|
|
|
statusProgress.maximum(1); |
|
|
|
|
statusProgress.color ( 0xffffffff ); |
|
|
|
|
statusProgress.selection_color( 0x272828ff ); |
|
|
|
|
|
|
|
|
|
volUp = Fl_Button ( 600, 430, 20,20 ); |
|
|
|
|
volUp.label ( "+" ); |
|
|
|
|
volUp.box ( FL_THIN_UP_BOX ); |
|
|
|
|
volUp.callback ( volUpCb ); |
|
|
|
|
|
|
|
|
|
volDown = Fl_Button ( 580, 430, 20,20 ); |
|
|
|
|
volDown.label ( "-" ); |
|
|
|
|
volDown.box ( FL_THIN_UP_BOX ); |
|
|
|
|
volDown.callback ( volDownCb ); |
|
|
|
|
|
|
|
|
|
resizeWindow(); |
|
|
|
|
|
|
|
|
|
window.end() |
|
|
|
|
window.show(len(sys.argv), sys.argv) |
|
|
|
|
|
|
|
|
|
state.start(); |
|
|
|
|
FLTK_run (); |
|
|
|
|
killAll( None ) |
|
|
|
|
def main () : |
|
|
|
|
global live |
|
|
|
|
|
|
|
|
|
if ( len ( sys.argv ) <= 1 ): |
|
|
|
|
print ("Usage: " + sys.argv[0] + " [parameters] FILENAME\n\ |
|
|
|
|
Options:\n\ |
|
|
|
|
* --live - indicate that a livestream is played (i.e. Twitch), will be played using livestreamer"); |
|
|
|
|
sys.exit(0); |
|
|
|
|
|
|
|
|
|
i = 0 |
|
|
|
|
quality = "best" |
|
|
|
|
live = False; |
|
|
|
|
omx.setFn ( startOMX, [sys.argv[1:]] ); |
|
|
|
|
while ( i < len (sys.argv) ): |
|
|
|
|
if (sys.argv[i] == "--live"): |
|
|
|
|
live = True |
|
|
|
|
if (sys.argv[i] == "--quality" or sys.argv[i] =="-q"): |
|
|
|
|
quality=sys.argv[1+i]; |
|
|
|
|
i = i + 1; |
|
|
|
|
|
|
|
|
|
print (quality) |
|
|
|
|
if ( live == True ): |
|
|
|
|
omx.setFn ( startOMXLive, [sys.argv[1:], quality] ); |
|
|
|
|
|
|
|
|
|
state.setFn ( thread_state, [] ); |
|
|
|
|
|
|
|
|
|
cfg = fileio.getConfig ( config.configfile ); |
|
|
|
|
|
|
|
|
|
ui.init( cfg ); |
|
|
|
|
|
|
|
|
|
# start omx-player |
|
|
|
|
omx.start(); |
|
|
|
|
state.start(); |
|
|
|
|
|
|
|
|
|
FLTK_run (); |
|
|
|
|
killAll( cfg ) |
|
|
|
|
|
|
|
|
|
if __name__ == "__main__" : |
|
|
|
|
main() |
|
|
|
|