bugfix
This commit is contained in:
parent
541cd701dc
commit
d1463f7f94
@ -28,6 +28,32 @@ from .utils import *
|
|||||||
from .pagescontainer import PageContainer
|
from .pagescontainer import PageContainer
|
||||||
from .widgetExt.messager import Messager
|
from .widgetExt.messager import Messager
|
||||||
from .blocks import Blocks
|
from .blocks import Blocks
|
||||||
|
from appPublic.rsa import RSA
|
||||||
|
|
||||||
|
class ServerInfo:
|
||||||
|
def __init__(self):
|
||||||
|
self.rsaEngine = RSA()
|
||||||
|
self.publickey = None
|
||||||
|
self.authCode = None
|
||||||
|
|
||||||
|
def getServerPK(self):
|
||||||
|
config = getConfig()
|
||||||
|
url = '%s%s' % (config.uihome, config.publickey_url)
|
||||||
|
hc = App.get_running_app().hc
|
||||||
|
d = hc.get(url)
|
||||||
|
self.publickey = self.rsaEngine. publickeyFromText(d)
|
||||||
|
|
||||||
|
def encode(self,uinfo):
|
||||||
|
if self.publickey is None:
|
||||||
|
self.getServerPK()
|
||||||
|
|
||||||
|
if uinfo['authmethod'] == 'password':
|
||||||
|
authinfo = '%s::%s::%s' % (uinfo['authmethod'], uinfo['userid'], uinfo['passwd'])
|
||||||
|
x = self.rsaEngine.encode(self.publickey, authinfo)
|
||||||
|
self.authCode = x
|
||||||
|
return x
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def signal_handler(signal, frame):
|
def signal_handler(signal, frame):
|
||||||
app = App.get_running_app()
|
app = App.get_running_app()
|
||||||
@ -42,7 +68,7 @@ class BlocksApp(App):
|
|||||||
def build(self):
|
def build(self):
|
||||||
config = getConfig()
|
config = getConfig()
|
||||||
self.config = config
|
self.config = config
|
||||||
self.userinfo = {}
|
self.serverinfo = ServerInfo()
|
||||||
self.title = 'Test Title'
|
self.title = 'Test Title'
|
||||||
self.blocks = Blocks()
|
self.blocks = Blocks()
|
||||||
self.workers = Workers(maxworkers=config.maxworkers or 80)
|
self.workers = Workers(maxworkers=config.maxworkers or 80)
|
||||||
@ -55,6 +81,18 @@ class BlocksApp(App):
|
|||||||
print('build() called......')
|
print('build() called......')
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
def getAuthHeader(self):
|
||||||
|
if not hasattr(self,'serverinfo'):
|
||||||
|
print('app serverinfo not found')
|
||||||
|
return {}
|
||||||
|
serverinfo = self.serverinfo
|
||||||
|
if hasattr(serverinfo,'authCode'):
|
||||||
|
return {
|
||||||
|
'authorization':serverinfo.authCode
|
||||||
|
}
|
||||||
|
print('serverinfo authCode not found')
|
||||||
|
return {}
|
||||||
|
|
||||||
def on_start(self):
|
def on_start(self):
|
||||||
print('on_start() called ...')
|
print('on_start() called ...')
|
||||||
|
|
||||||
|
@ -210,6 +210,7 @@ class Form(BoxLayout):
|
|||||||
self.inputwidth = Window.width / self.cols
|
self.inputwidth = Window.width / self.cols
|
||||||
self.inputheight = CSize(self.options.get('inputheight',3))
|
self.inputheight = CSize(self.options.get('inputheight',3))
|
||||||
self.initflag = False
|
self.initflag = False
|
||||||
|
self.register_event_type('on_submit')
|
||||||
self.bind(size=self.on_size,
|
self.bind(size=self.on_size,
|
||||||
pos=self.on_size)
|
pos=self.on_size)
|
||||||
|
|
||||||
@ -224,7 +225,6 @@ class Form(BoxLayout):
|
|||||||
print('box_width=%d,cols=%d' % (self.inputwidth, self.cols))
|
print('box_width=%d,cols=%d' % (self.inputwidth, self.cols))
|
||||||
self.add_widget(self.toolbar)
|
self.add_widget(self.toolbar)
|
||||||
self.add_widget(self.fsc)
|
self.add_widget(self.fsc)
|
||||||
self.register_event_type('on_submit')
|
|
||||||
self.fieldWidgets=[]
|
self.fieldWidgets=[]
|
||||||
for f in self.options['fields']:
|
for f in self.options['fields']:
|
||||||
w = InputBox(self, **f)
|
w = InputBox(self, **f)
|
||||||
@ -232,12 +232,11 @@ class Form(BoxLayout):
|
|||||||
self.fsc.add_widget(w)
|
self.fsc.add_widget(w)
|
||||||
self.fieldWidgets.append(w)
|
self.fieldWidgets.append(w)
|
||||||
blocks = App.get_running_app().blocks
|
blocks = App.get_running_app().blocks
|
||||||
wid = self.widget_ids['__submit']
|
# wid = self.widget_ids['__submit']
|
||||||
# wid = getWidgetById(self,'__submit')
|
wid = blocks.getWidgetByIdPath(self,'__submit')
|
||||||
# print('ids=',self.widget_ids.keys())
|
|
||||||
wid.bind(on_press=self.on_submit_button)
|
wid.bind(on_press=self.on_submit_button)
|
||||||
# wid = getWidgetById(self,'__clear')
|
wid = blocks.getWidgetByIdPath(self,'__clear')
|
||||||
wid = self.widget_ids['__clear']
|
# wid = self.widget_ids['__clear']
|
||||||
wid.bind(on_press=self.on_clear_button)
|
wid.bind(on_press=self.on_clear_button)
|
||||||
self.initflag = True
|
self.initflag = True
|
||||||
|
|
||||||
@ -248,12 +247,13 @@ class Form(BoxLayout):
|
|||||||
d.update(v)
|
d.update(v)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def on_submit(self,o,v=None):
|
def on_submit(self,v=None):
|
||||||
print(o,v)
|
print('Form():on_submit fired ...',v)
|
||||||
|
return False
|
||||||
|
|
||||||
def on_submit_button(self,o,v=None):
|
def on_submit_button(self,o,v=None):
|
||||||
d = self.getData()
|
d = self.getData()
|
||||||
self.dispatch('on_submit',self,d)
|
self.dispatch('on_submit',d)
|
||||||
|
|
||||||
def on_clear_button(self,o,v=None):
|
def on_clear_button(self,o,v=None):
|
||||||
for fw in self.fieldWidgets:
|
for fw in self.fieldWidgets:
|
||||||
@ -291,6 +291,6 @@ class StrSearchForm(BoxLayout):
|
|||||||
}
|
}
|
||||||
self.dispatch('on_submit',d)
|
self.dispatch('on_submit',d)
|
||||||
|
|
||||||
def on_submit(self,o,v=None):
|
def on_submit(self,v=None):
|
||||||
print('StrSearchForm():on_submit fired ..........')
|
print('StrSearchForm():on_submit fired ..........')
|
||||||
|
|
||||||
|
@ -2,34 +2,15 @@ from kivy.app import App
|
|||||||
from kivy.core.window import Window
|
from kivy.core.window import Window
|
||||||
from kivy.uix.popup import Popup
|
from kivy.uix.popup import Popup
|
||||||
from appPublic.Singleton import SingletonDecorator
|
from appPublic.Singleton import SingletonDecorator
|
||||||
|
from appPublic.jsonConfig import getConfig
|
||||||
from appPublic.registerfunction import RegisterFunction
|
from appPublic.registerfunction import RegisterFunction
|
||||||
from appPublic.rsa import RSA
|
|
||||||
# from .form import Form
|
|
||||||
|
|
||||||
class ServerInfo:
|
|
||||||
def __init__(self):
|
|
||||||
self.rsaEngine = RSA()
|
|
||||||
config = getConfig()
|
|
||||||
url = '%s%s' % (config.uihome, config.publickey_url)
|
|
||||||
hc = App.get_running_app().hc
|
|
||||||
d = hc.get(url)
|
|
||||||
self.publickey = self.rsaEngine. publickeyFromText(d)
|
|
||||||
|
|
||||||
def encode(self,uinfo):
|
|
||||||
if uinfo['authmethod'] == 'password':
|
|
||||||
authinfo = '%s::%s::%s' % (uinfo['authmethod'], uinfo['userid'], uinfo['password'])
|
|
||||||
txt = self.serverinfo.encode(authinfo)
|
|
||||||
x = self.rsaEngine.encode(self.publickey, txt)
|
|
||||||
return x
|
|
||||||
return None
|
|
||||||
|
|
||||||
logformdesc = {
|
logformdesc = {
|
||||||
"widgettype":"Form",
|
"widgettype":"Form",
|
||||||
"options":{
|
"options":{
|
||||||
"cols":1,
|
"cols":1,
|
||||||
"labelwidth":0.3,
|
"labelwidth":0.4,
|
||||||
"textsize":1,
|
"textsize":1,
|
||||||
"inputheight":3,
|
"inputheight":4,
|
||||||
"fields":[
|
"fields":[
|
||||||
{
|
{
|
||||||
"name":"userid",
|
"name":"userid",
|
||||||
@ -44,61 +25,43 @@ logformdesc = {
|
|||||||
"uitype":"password"
|
"uitype":"password"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
"binds":[
|
|
||||||
{
|
|
||||||
"wid":"self",
|
|
||||||
"event":"on_submit",
|
|
||||||
"datawidegt":"self",
|
|
||||||
"actiontype":"registedfunction",
|
|
||||||
"rfname":"setupUserInfo"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SingletonDecorator
|
@SingletonDecorator
|
||||||
class LoginForm(Popup):
|
class LoginForm(Popup):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(size_hint=(0.8,0.8))
|
super().__init__(size_hint=(0.8,0.8))
|
||||||
|
|
||||||
app = App.get_running_app()
|
|
||||||
print('here ..1............')
|
|
||||||
self.content = app.blocks.widgetBuild(logformdesc)
|
|
||||||
# self.content.bind(on_submit=setipUserInfo)
|
|
||||||
print('here ..2............',self.content)
|
|
||||||
self.title = 'login'
|
self.title = 'login'
|
||||||
self.blockCalls = []
|
self.initflag = False
|
||||||
self.open_status = False
|
self.bind(size=self.buildContent,
|
||||||
print('here ..3............')
|
pos=self.buildContent)
|
||||||
|
|
||||||
|
def buildContent(self,o,size):
|
||||||
|
print('build Content. ....')
|
||||||
|
if self.initflag:
|
||||||
|
return
|
||||||
|
print('build Content ....... ....')
|
||||||
|
self.initflag = True
|
||||||
|
app = App.get_running_app()
|
||||||
|
self.content = app.blocks.widgetBuild(logformdesc)
|
||||||
self.content.bind(on_submit=self.on_submit)
|
self.content.bind(on_submit=self.on_submit)
|
||||||
self.content.bind(on_cancel=self.on_submit)
|
|
||||||
print('here ..4............')
|
|
||||||
self.open()
|
|
||||||
|
|
||||||
def close(self):
|
def on_submit(self,o,userinfo):
|
||||||
self.open_status = False
|
print('login(),on_submit fired ....')
|
||||||
self.dismiss()
|
self.dismiss()
|
||||||
|
print('userinfo=',userinfo)
|
||||||
|
app = App.get_running_app()
|
||||||
|
|
||||||
def on_submit(self,o,v):
|
if userinfo.get('passwd',False):
|
||||||
self.dismiss()
|
userinfo['authmethod'] = 'password'
|
||||||
|
authinfo = app.serverinfo.encode(userinfo)
|
||||||
|
login_url = '%s%s' % (app.config.uihome, app.config.login_url)
|
||||||
|
x = app.hc.get(login_url)
|
||||||
|
print('login return=', x, login_url, authinfo)
|
||||||
|
|
||||||
def on_cancel(self,o,v):
|
def on_cancel(self,o,v):
|
||||||
|
print('login() on_cancel fired .....')
|
||||||
self.dismiss()
|
self.dismiss()
|
||||||
|
|
||||||
def setupUserInfo(obj, userinfo):
|
|
||||||
app = App.get_running_app()
|
|
||||||
if not hasattr(app, 'serverinfo'):
|
|
||||||
app.serverinfo = ServerInfo()
|
|
||||||
|
|
||||||
if userinfo.get('password',False):
|
|
||||||
userinfo['authmethod'] = 'password'
|
|
||||||
authinfo = app.serverinfo.encode(userinfo)
|
|
||||||
headers = {
|
|
||||||
"authorization":authinfo
|
|
||||||
}
|
|
||||||
login_url = '%s%s' % (app.config.uihome, app.config.login_url)
|
|
||||||
app.hc.get(login_url,headers=headers)
|
|
||||||
|
|
||||||
rf = RegisterFunction()
|
|
||||||
rf.register('setupUserInfo',setupUserInfo)
|
|
||||||
|
|
||||||
|
@ -51,7 +51,11 @@ class VResponsiveLayout(ScrollView):
|
|||||||
|
|
||||||
def setCols(self,t=None):
|
def setCols(self,t=None):
|
||||||
self.box_width = self.org_box_width
|
self.box_width = self.org_box_width
|
||||||
self.cols = int(self.width / self.box_width)
|
if self.width < self.box_width:
|
||||||
|
self.cols = self.org_cols
|
||||||
|
else:
|
||||||
|
self.cols = int(self.width / self.box_width)
|
||||||
|
print('VResponsiveLayout()::setCols():self.cols=',self.cols, 'self.box_width=',self.box_width,'self.org_cols=',self.org_cols)
|
||||||
if isHandHold():
|
if isHandHold():
|
||||||
w,h = self.size
|
w,h = self.size
|
||||||
if w < h:
|
if w < h:
|
||||||
|
@ -42,7 +42,7 @@ class ThreadCall(Thread,EventDispatcher):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def checkStop(self,timestamp):
|
def checkStop(self,timestamp):
|
||||||
x = self.join(timeout=0.0001)
|
x = self.join(timeout=0.001)
|
||||||
if self.is_alive():
|
if self.is_alive():
|
||||||
self.timing = Clock.schedule_once(self.checkStop,0)
|
self.timing = Clock.schedule_once(self.checkStop,0)
|
||||||
return
|
return
|
||||||
@ -79,12 +79,28 @@ class Workers(Thread):
|
|||||||
with self.lock:
|
with self.lock:
|
||||||
self.tasks.insert(0,[callee,callback,errback,kwargs])
|
self.tasks.insert(0,[callee,callback,errback,kwargs])
|
||||||
|
|
||||||
|
hostsessions = {}
|
||||||
|
|
||||||
class HttpClient:
|
class HttpClient:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.s = requests.Session()
|
self.s = requests.Session()
|
||||||
self.workers = App.get_running_app().workers
|
self.workers = App.get_running_app().workers
|
||||||
|
|
||||||
|
def url2domain(self,url):
|
||||||
|
parts = url.split('/')[:3]
|
||||||
|
pre = '/'.join(parts)
|
||||||
|
return pre
|
||||||
|
|
||||||
def webcall(self,url,method="GET",params={},files={},headers={}):
|
def webcall(self,url,method="GET",params={},files={},headers={}):
|
||||||
|
app = App.get_running_app()
|
||||||
|
domain = self.url2domain(url)
|
||||||
|
sessionid = hostsessions.get(domain,None)
|
||||||
|
print('hostsessions=', hostsessions, 'sessionid=',sessionid, 'domain=',domain)
|
||||||
|
if sessionid:
|
||||||
|
headers.update({'session':sessionid})
|
||||||
|
elif app.getAuthHeader():
|
||||||
|
headers.update(app.getAuthHeader())
|
||||||
|
print('headers=',headers)
|
||||||
if method in ['GET']:
|
if method in ['GET']:
|
||||||
req = requests.Request(method,url,
|
req = requests.Request(method,url,
|
||||||
params=params,headers=headers)
|
params=params,headers=headers)
|
||||||
@ -94,6 +110,11 @@ class HttpClient:
|
|||||||
prepped = self.s.prepare_request(req)
|
prepped = self.s.prepare_request(req)
|
||||||
resp = self.s.send(prepped)
|
resp = self.s.send(prepped)
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
|
h = resp.headers.get('Set-Cookie',None)
|
||||||
|
if h:
|
||||||
|
print('*************set-Cookie=',h,'domain=',domain)
|
||||||
|
sessionid = h.split(';')[0]
|
||||||
|
hostsessions[domain] = sessionid
|
||||||
try:
|
try:
|
||||||
data = resp.json()
|
data = resp.json()
|
||||||
if type(data) != type({}):
|
if type(data) != type({}):
|
||||||
@ -128,7 +149,7 @@ class HttpClient:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
if errback is not None:
|
if errback is not None:
|
||||||
errback(e)
|
errback(e)
|
||||||
|
return None
|
||||||
kwargs = {
|
kwargs = {
|
||||||
"url":url,
|
"url":url,
|
||||||
"method":method,
|
"method":method,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import time
|
||||||
from kivy.utils import platform
|
from kivy.utils import platform
|
||||||
from traceback import print_exc
|
from traceback import print_exc
|
||||||
from kivy.core.window import Window
|
from kivy.core.window import Window
|
||||||
@ -15,6 +16,7 @@ from kivy.app import App
|
|||||||
from kivy.clock import Clock
|
from kivy.clock import Clock
|
||||||
from kivy.properties import ObjectProperty, StringProperty, BooleanProperty, \
|
from kivy.properties import ObjectProperty, StringProperty, BooleanProperty, \
|
||||||
NumericProperty, DictProperty, OptionProperty
|
NumericProperty, DictProperty, OptionProperty
|
||||||
|
from pythonosc import dispatcher, osc_server
|
||||||
from .utils import *
|
from .utils import *
|
||||||
from .baseWidget import PressableImage
|
from .baseWidget import PressableImage
|
||||||
|
|
||||||
@ -26,79 +28,26 @@ desktopOSs=[
|
|||||||
|
|
||||||
othersplatforms=['ios','android']
|
othersplatforms=['ios','android']
|
||||||
|
|
||||||
class VPlayer(FloatLayout):
|
class BaseVPlayer(FloatLayout):
|
||||||
fullscreen = BooleanProperty(False)
|
fullscreen = BooleanProperty(False)
|
||||||
exit = BooleanProperty(False)
|
def __init__(self,vfile=None):
|
||||||
stoped_play = BooleanProperty(False)
|
|
||||||
paused_play = BooleanProperty(False)
|
|
||||||
|
|
||||||
def __init__(self,vfile=None,
|
|
||||||
playlist=None,
|
|
||||||
loop=False,
|
|
||||||
openfile_img=None,
|
|
||||||
exit_img = None,
|
|
||||||
pause_img = None,
|
|
||||||
play_img = None,
|
|
||||||
mute_img = None,
|
|
||||||
track_img = None,
|
|
||||||
next_img = None,
|
|
||||||
replay_img = None,
|
|
||||||
can_openfile=False,
|
|
||||||
can_cut=False,
|
|
||||||
can_replay=False,
|
|
||||||
can_changevolume=True
|
|
||||||
):
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
Window.allow_screensaver = False
|
Window.allow_screensaver = False
|
||||||
print(self,vfile)
|
|
||||||
self._video = Video(allow_stretch=True,pos_hint={'x': 0, 'y': 0},size_hint=(1,1))
|
self._video = Video(allow_stretch=True,pos_hint={'x': 0, 'y': 0},size_hint=(1,1))
|
||||||
self.add_widget(self._video)
|
self.add_widget(self._video)
|
||||||
self.loop = loop
|
|
||||||
self.openfile_img = openfile_img
|
|
||||||
self.can_openfile = can_openfile
|
|
||||||
self.can_replay = can_replay
|
|
||||||
self.can_cut = can_cut
|
|
||||||
self.can_changevolume = can_changevolume
|
|
||||||
if self.openfile_img:
|
|
||||||
self.can_openfile = True
|
|
||||||
self.exit_img = exit_img
|
|
||||||
self.play_img = play_img
|
|
||||||
self.pause_img = pause_img
|
|
||||||
self.mute_img = mute_img
|
|
||||||
self.track_img = track_img
|
|
||||||
self.next_img = next_img
|
|
||||||
self.replay_img = replay_img
|
|
||||||
self.ffplayer = None
|
self.ffplayer = None
|
||||||
self.menubar = None
|
if type(vfile) == type([]):
|
||||||
self._popup = None
|
self.playlist = vfile
|
||||||
self.menu_status = False
|
|
||||||
self.manualMode = False
|
|
||||||
self.update_task = None
|
|
||||||
self.old_path = os.getcwd()
|
|
||||||
self.pb = None
|
|
||||||
if vfile:
|
|
||||||
if type(vfile) == type([]):
|
|
||||||
self.playlist = vfile
|
|
||||||
else:
|
|
||||||
self.playlist = [vfile]
|
|
||||||
self.curplay = 0
|
|
||||||
self.play()
|
|
||||||
else:
|
else:
|
||||||
self.playlist = []
|
self.playlist = [vfile]
|
||||||
self.curplay = -1
|
self.curplay = 0
|
||||||
|
self.play()
|
||||||
self._video.bind(eos=self.video_end)
|
self._video.bind(eos=self.video_end)
|
||||||
self._video.bind(state=self.on_state)
|
self._video.bind(state=self.on_state)
|
||||||
self._video.bind(loaded=self.createProgressbar)
|
|
||||||
self._video.bind(on_touch_down=self.show_hide_menu)
|
|
||||||
self.register_event_type('on_playend')
|
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
print('********** delete VPlayer instance ********')
|
|
||||||
if self._video is None:
|
if self._video is None:
|
||||||
return
|
return
|
||||||
if self.update_task:
|
|
||||||
self.update_task.cancel()
|
|
||||||
self.update_task = None
|
|
||||||
self._video.state = 'pause'
|
self._video.state = 'pause'
|
||||||
Window.allow_screensaver = True
|
Window.allow_screensaver = True
|
||||||
del self._video
|
del self._video
|
||||||
@ -117,75 +66,10 @@ class VPlayer(FloatLayout):
|
|||||||
|
|
||||||
def video_end(self,t,v):
|
def video_end(self,t,v):
|
||||||
self.curplay += 1
|
self.curplay += 1
|
||||||
if not self.loop and self.curplay >= len(self.playlist):
|
|
||||||
self.dispatch('on_playend')
|
|
||||||
return
|
|
||||||
self.curplay = self.curplay % len(self.playlist)
|
self.curplay = self.curplay % len(self.playlist)
|
||||||
self._video.source = self.playlist[self.curplay]
|
self._video.source = self.playlist[self.curplay]
|
||||||
self._video.state = 'play'
|
self._video.state = 'play'
|
||||||
|
|
||||||
def totime(self,dur):
|
|
||||||
h = dur / 3600
|
|
||||||
m = dur % 3600 / 60
|
|
||||||
s = dur % 60
|
|
||||||
return '%02d:%02d:%02d' % (h,m,s)
|
|
||||||
|
|
||||||
def createProgressbar(self,obj,v):
|
|
||||||
if hasattr(self._video._video, '_ffplayer'):
|
|
||||||
self.ffplayer = self._video._video._ffplayer
|
|
||||||
|
|
||||||
if self.pb is None:
|
|
||||||
self.pb = BoxLayout(orientation='horizontal',
|
|
||||||
size_hint = (0.99,None),height=CSize(1.4))
|
|
||||||
self.curposition = Label(text='0',width=CSize(4),
|
|
||||||
size_hint_x=None)
|
|
||||||
self.curposition.align='right'
|
|
||||||
self.maxposition = Label(text=self.totime(self._video.duration),
|
|
||||||
width=CSize(4),size_hint_x=None)
|
|
||||||
self.maxposition.align = 'left'
|
|
||||||
self.slider = Slider(min=0,
|
|
||||||
max=self._video.duration,
|
|
||||||
value=0,
|
|
||||||
orientation='horizontal',
|
|
||||||
step=0.01)
|
|
||||||
self.slider.bind(on_touch_down=self.enterManualMode)
|
|
||||||
self.slider.bind(on_touch_up=self.endManualMode)
|
|
||||||
self.manual_mode=False
|
|
||||||
|
|
||||||
self.pb.add_widget(self.curposition)
|
|
||||||
self.pb.add_widget(self.slider)
|
|
||||||
self.pb.add_widget(self.maxposition)
|
|
||||||
self.update_task = Clock.schedule_interval(self.update_slider,1)
|
|
||||||
self.buildMenu()
|
|
||||||
|
|
||||||
def enterManualMode(self,obj,touch):
|
|
||||||
if not self.slider.collide_point(*touch.pos):
|
|
||||||
return
|
|
||||||
self.manualMode = True
|
|
||||||
|
|
||||||
def endManualMode(self,obj,touch):
|
|
||||||
if not self.manualMode:
|
|
||||||
return
|
|
||||||
if self._video.duration < 0.0001:
|
|
||||||
return
|
|
||||||
self._video.seek(self.slider.value/self._video.duration)
|
|
||||||
self.manualMode = False
|
|
||||||
|
|
||||||
def update_slider(self,t):
|
|
||||||
self.curposition.text = self.totime(self._video.position)
|
|
||||||
if not self.manualMode:
|
|
||||||
self.slider.value = self._video.position
|
|
||||||
self.slider.max = self._video.duration
|
|
||||||
self.maxposition.text = self.totime(self._video.duration)
|
|
||||||
|
|
||||||
def beforeDestroy(self):
|
|
||||||
try:
|
|
||||||
del self
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print_exc()
|
|
||||||
return True
|
|
||||||
|
|
||||||
def on_state(self,o,v):
|
def on_state(self,o,v):
|
||||||
if self._video.state == 'play':
|
if self._video.state == 'play':
|
||||||
Window.allow_screensaver = False
|
Window.allow_screensaver = False
|
||||||
@ -212,7 +96,6 @@ class VPlayer(FloatLayout):
|
|||||||
if value:
|
if value:
|
||||||
Window.fullscreen = True
|
Window.fullscreen = True
|
||||||
|
|
||||||
print('Window size=',Window.size)
|
|
||||||
self._fullscreen_state = state = {
|
self._fullscreen_state = state = {
|
||||||
'parent': self.parent,
|
'parent': self.parent,
|
||||||
'pos': self.pos,
|
'pos': self.pos,
|
||||||
@ -221,7 +104,6 @@ class VPlayer(FloatLayout):
|
|||||||
'size_hint': self.size_hint,
|
'size_hint': self.size_hint,
|
||||||
'window_children': window.children[:]}
|
'window_children': window.children[:]}
|
||||||
|
|
||||||
print('vplayer fullscreen,platform=',platform,desktopOSs)
|
|
||||||
if platform in desktopOSs:
|
if platform in desktopOSs:
|
||||||
Window.maximize()
|
Window.maximize()
|
||||||
# remove all window children
|
# remove all window children
|
||||||
@ -251,10 +133,182 @@ class VPlayer(FloatLayout):
|
|||||||
self.size = state['size']
|
self.size = state['size']
|
||||||
if state['parent'] is not window:
|
if state['parent'] is not window:
|
||||||
state['parent'].add_widget(self)
|
state['parent'].add_widget(self)
|
||||||
print('vplayer fullscreen,platform=',platform,desktopOSs)
|
|
||||||
if platform in desktopOSs:
|
if platform in desktopOSs:
|
||||||
Window.restore()
|
Window.restore()
|
||||||
|
|
||||||
|
def endplay(self,btn):
|
||||||
|
self._video.seek(1.0,precise=True)
|
||||||
|
|
||||||
|
def replay(self,btn):
|
||||||
|
self._video.seek(0.0,precise=True)
|
||||||
|
|
||||||
|
def audioswitch(self,btn):
|
||||||
|
if self.ffplayer is not None:
|
||||||
|
self.ffplayer.request_channel('audio')
|
||||||
|
|
||||||
|
def setVolume(self,obj,v):
|
||||||
|
self._video.volume = v
|
||||||
|
|
||||||
|
def setPosition(self,obj,v):
|
||||||
|
self._video.seek(v)
|
||||||
|
|
||||||
|
def mute(self,btn):
|
||||||
|
if self._video.volume > 0.001:
|
||||||
|
self.old_volume = self._video.volume
|
||||||
|
self._video.volume = 0.0
|
||||||
|
else:
|
||||||
|
self._video.volume = self.old_volume
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
try:
|
||||||
|
self._video.state = 'stop'
|
||||||
|
except:
|
||||||
|
print_exc()
|
||||||
|
|
||||||
|
def pause(self,t=None):
|
||||||
|
if self._video.state == 'play':
|
||||||
|
self._video.state = 'pause'
|
||||||
|
else:
|
||||||
|
self._video.state = 'play'
|
||||||
|
|
||||||
|
class OSCVPlayer(BaseVPlayer):
|
||||||
|
def __init__(self,ip,port,vfile=None):
|
||||||
|
self.ip = ip
|
||||||
|
self.port = port
|
||||||
|
self.dispatcher = dispatcher.Dispatcher()
|
||||||
|
self.server = osc_server.ThreadingOSCUDPServer( (self.ip, self.port), self.dispatcher)
|
||||||
|
BaseVPlayer.__init__(self,vfile=vfile)
|
||||||
|
self.map('/mute',self.mute)
|
||||||
|
self.map('/pause',self.pause)
|
||||||
|
self.map('/atrack',self.audioswitch)
|
||||||
|
self.map('/endplay',self.endplay)
|
||||||
|
self.map('/replay',self.replay)
|
||||||
|
self.map('/setvalume',self.setVolume)
|
||||||
|
self.map('/setposition',self.setPosition)
|
||||||
|
self.map('/next',self.next)
|
||||||
|
|
||||||
|
self.server.serve_forever()
|
||||||
|
self.fullscreen = True
|
||||||
|
label = Label(text='%s %d' % (self.ip,self.port), font_size=CSize(2))
|
||||||
|
label.size = self.width - label.width, 0
|
||||||
|
self.add_widget(label)
|
||||||
|
|
||||||
|
def next(self,obj):
|
||||||
|
self.source = self.vfile + '?t=%f' % time.time()
|
||||||
|
|
||||||
|
def map(self,p,f):
|
||||||
|
self.dispatcher.map(p,f,None)
|
||||||
|
|
||||||
|
class VPlayer(BaseVPlayer):
|
||||||
|
def __init__(self,vfile=None,
|
||||||
|
playlist=None,
|
||||||
|
loop=False
|
||||||
|
):
|
||||||
|
super().__init__(vfile=vfile)
|
||||||
|
self.loop = loop
|
||||||
|
self.menubar = None
|
||||||
|
self._popup = None
|
||||||
|
self.menu_status = False
|
||||||
|
self.manualMode = False
|
||||||
|
self.update_task = None
|
||||||
|
self.pb = None
|
||||||
|
if vfile:
|
||||||
|
if type(vfile) == type([]):
|
||||||
|
self.playlist = vfile
|
||||||
|
else:
|
||||||
|
self.playlist = [vfile]
|
||||||
|
self.curplay = 0
|
||||||
|
self.play()
|
||||||
|
else:
|
||||||
|
self.playlist = []
|
||||||
|
self.curplay = -1
|
||||||
|
self._video.bind(on_touch_down=self.show_hide_menu)
|
||||||
|
self.register_event_type('on_playend')
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
print('********** delete VPlayer instance ********')
|
||||||
|
if self._video is None:
|
||||||
|
return
|
||||||
|
if self.update_task:
|
||||||
|
self.update_task.cancel()
|
||||||
|
self.update_task = None
|
||||||
|
self._video.state = 'pause'
|
||||||
|
Window.allow_screensaver = True
|
||||||
|
del self._video
|
||||||
|
self._video = None
|
||||||
|
|
||||||
|
|
||||||
|
def video_end(self,t,v):
|
||||||
|
self.curplay += 1
|
||||||
|
if not self.loop and self.curplay >= len(self.playlist):
|
||||||
|
self.dispatch('on_playend')
|
||||||
|
return
|
||||||
|
self.curplay = self.curplay % len(self.playlist)
|
||||||
|
self._video.source = self.playlist[self.curplay]
|
||||||
|
self._video.state = 'play'
|
||||||
|
|
||||||
|
def totime(self,dur):
|
||||||
|
h = dur / 3600
|
||||||
|
m = dur % 3600 / 60
|
||||||
|
s = dur % 60
|
||||||
|
return '%02d:%02d:%02d' % (h,m,s)
|
||||||
|
|
||||||
|
def createProgressBar(self):
|
||||||
|
if hasattr(self._video._video, '_ffplayer'):
|
||||||
|
self.ffplayer = self._video._video._ffplayer
|
||||||
|
|
||||||
|
if self.pb is None:
|
||||||
|
self.pb = BoxLayout(orientation='horizontal',
|
||||||
|
size_hint = (0.99,None),height=CSize(1.4))
|
||||||
|
self.curposition = Label(text='0',width=CSize(4),
|
||||||
|
size_hint_x=None)
|
||||||
|
self.curposition.align='right'
|
||||||
|
self.maxposition = Label(text=self.totime(self._video.duration),
|
||||||
|
width=CSize(4),size_hint_x=None)
|
||||||
|
self.maxposition.align = 'left'
|
||||||
|
self.slider = Slider(min=0,
|
||||||
|
max=self._video.duration,
|
||||||
|
value=0,
|
||||||
|
orientation='horizontal',
|
||||||
|
step=0.01)
|
||||||
|
self.slider.bind(on_touch_down=self.enterManualMode)
|
||||||
|
self.slider.bind(on_touch_up=self.endManualMode)
|
||||||
|
self.manual_mode=False
|
||||||
|
|
||||||
|
self.pb.add_widget(self.curposition)
|
||||||
|
self.pb.add_widget(self.slider)
|
||||||
|
self.pb.add_widget(self.maxposition)
|
||||||
|
self.menubar.add_widget(self.pb)
|
||||||
|
self.update_task = Clock.schedule_interval(self.update_slider,1)
|
||||||
|
|
||||||
|
def enterManualMode(self,obj,touch):
|
||||||
|
if not self.slider.collide_point(*touch.pos):
|
||||||
|
return
|
||||||
|
self.manualMode = True
|
||||||
|
|
||||||
|
def endManualMode(self,obj,touch):
|
||||||
|
if not self.manualMode:
|
||||||
|
return
|
||||||
|
if self._video.duration < 0.0001:
|
||||||
|
return
|
||||||
|
self._video.seek(self.slider.value/self._video.duration)
|
||||||
|
self.manualMode = False
|
||||||
|
|
||||||
|
def update_slider(self,t):
|
||||||
|
self.curposition.text = self.totime(self._video.position)
|
||||||
|
if not self.manualMode:
|
||||||
|
self.slider.value = self._video.position
|
||||||
|
self.slider.max = self._video.duration
|
||||||
|
self.maxposition.text = self.totime(self._video.duration)
|
||||||
|
|
||||||
|
def beforeDestroy(self):
|
||||||
|
try:
|
||||||
|
del self
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print_exc()
|
||||||
|
return True
|
||||||
|
|
||||||
def show_hide_menu(self,obj,touch):
|
def show_hide_menu(self,obj,touch):
|
||||||
if not self.collide_point(*touch.pos):
|
if not self.collide_point(*touch.pos):
|
||||||
print('not inside the player')
|
print('not inside the player')
|
||||||
@ -265,15 +319,16 @@ class VPlayer(FloatLayout):
|
|||||||
print('doube_tap')
|
print('doube_tap')
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.menubar:
|
if not self.menubar:
|
||||||
self.remove_widget(self.menubar)
|
self.buildMenu()
|
||||||
self.menu_status = not self.menu_status
|
|
||||||
if self.menu_status:
|
|
||||||
self.add_widget(self.menubar)
|
|
||||||
else:
|
|
||||||
self.remove_widget(self.menubar)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if self.menu_status:
|
||||||
|
self.remove_widget(self.menubar)
|
||||||
|
else:
|
||||||
|
self.add_widget(self.menubar)
|
||||||
|
self.menu_status = not self.menu_status
|
||||||
|
|
||||||
def buildMenu(self):
|
def buildMenu(self):
|
||||||
self.menubar = BoxLayout(orientation='horizontal',
|
self.menubar = BoxLayout(orientation='horizontal',
|
||||||
size_hint_y=None,height=CSize(1.4))
|
size_hint_y=None,height=CSize(1.4))
|
||||||
@ -291,10 +346,6 @@ class VPlayer(FloatLayout):
|
|||||||
)
|
)
|
||||||
self.btn_mute.bind(on_press=self.mute)
|
self.btn_mute.bind(on_press=self.mute)
|
||||||
self.menubar.add_widget(self.btn_mute)
|
self.menubar.add_widget(self.btn_mute)
|
||||||
if self.can_openfile:
|
|
||||||
btn_open = Button(text='open')
|
|
||||||
btn_open.bind(on_press=self.openfile)
|
|
||||||
self.menubar.add_widget(btn_open)
|
|
||||||
btn_cut = PressableImage(source=blockImage('next.jpg'),
|
btn_cut = PressableImage(source=blockImage('next.jpg'),
|
||||||
size_hint=(None,None),
|
size_hint=(None,None),
|
||||||
size=CSize(3,3)
|
size=CSize(3,3)
|
||||||
@ -326,123 +377,30 @@ class VPlayer(FloatLayout):
|
|||||||
step=0.07)
|
step=0.07)
|
||||||
slider.bind(on_touch_up=self.setVolume)
|
slider.bind(on_touch_up=self.setVolume)
|
||||||
self.menubar.add_widget(slider)
|
self.menubar.add_widget(slider)
|
||||||
self.menubar.add_widget(self.pb)
|
|
||||||
self.menubar.pos = CSize(0,0)
|
self.menubar.pos = CSize(0,0)
|
||||||
|
self.createProgressBar()
|
||||||
self.add_widget(self.menubar)
|
self.add_widget(self.menubar)
|
||||||
self.menu_status = True
|
self.menu_status = True
|
||||||
|
|
||||||
def endplay(self,btn):
|
def setVolume(self,obj,v=None):
|
||||||
self._video.seek(1.0,precise=True)
|
BaseVPlayer.setVolume(self,obj,obj.value)
|
||||||
|
|
||||||
def replay(self,btn):
|
|
||||||
self._video.seek(0.0,precise=True)
|
|
||||||
|
|
||||||
def hideMenu(self):
|
|
||||||
self._popup.dismiss()
|
|
||||||
self.remove_widget(self.menubar)
|
|
||||||
self.menubar = None
|
|
||||||
|
|
||||||
def audioswitch(self,btn):
|
|
||||||
if self.ffplayer is not None:
|
|
||||||
self.ffplayer.request_channel('audio')
|
|
||||||
|
|
||||||
def setVolume(self,obj,touh):
|
|
||||||
self._video.volume = obj.value
|
|
||||||
|
|
||||||
def mute(self,btn):
|
def mute(self,btn):
|
||||||
if self._video.volume > 0.001:
|
BaseVPlayer.mute(self,btn)
|
||||||
self.old_volume = self._video.volume
|
if self.menubar:
|
||||||
self._video.volume = 0.0
|
if self._video.volume < 0.001:
|
||||||
if self.menubar:
|
|
||||||
btn.source = blockImage('volume.jpg')
|
btn.source = blockImage('volume.jpg')
|
||||||
else:
|
else:
|
||||||
self._video.volume = self.old_volume
|
|
||||||
if self.menubar:
|
|
||||||
btn.source = blockImage('mute.jpg')
|
btn.source = blockImage('mute.jpg')
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
try:
|
|
||||||
self._video.state = 'stop'
|
|
||||||
except:
|
|
||||||
print_exc()
|
|
||||||
|
|
||||||
def on_disabled(self,o,v):
|
|
||||||
if self.disabled:
|
|
||||||
self.stop()
|
|
||||||
del self._video
|
|
||||||
|
|
||||||
def pause(self,t=None):
|
def pause(self,t=None):
|
||||||
if self._video.state == 'play':
|
BaseVPlayer.pause(self,t)
|
||||||
self._video.state = 'pause'
|
if self.menubar:
|
||||||
if self.menubar:
|
if self._video.state == 'pause':
|
||||||
self.btn_pause.source = blockImage('play.jpg')
|
self.btn_pause.source = blockImage('play.jpg')
|
||||||
else:
|
else:
|
||||||
self._video.state = 'play'
|
|
||||||
if self.menubar:
|
|
||||||
self.btn_pause.source = blockImage('pause.jpg')
|
self.btn_pause.source = blockImage('pause.jpg')
|
||||||
|
|
||||||
def openfile(self,t):
|
|
||||||
if self._popup is None:
|
|
||||||
def vfilter(path,filename):
|
|
||||||
vexts = ['.avi',
|
|
||||||
'.mpg',
|
|
||||||
'.mpe',
|
|
||||||
'.mpeg',
|
|
||||||
'.mlv',
|
|
||||||
'.dat',
|
|
||||||
'.mp4',
|
|
||||||
'.flv',
|
|
||||||
'.mov',
|
|
||||||
'.rm',
|
|
||||||
'.mkv',
|
|
||||||
'.rmvb',
|
|
||||||
'.asf',
|
|
||||||
'.3gp'
|
|
||||||
]
|
|
||||||
for ext in vexts:
|
|
||||||
if filename.endswith(ext):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
c = BoxLayout(orientation='vertical')
|
|
||||||
self.file_chooser = FileChooserListView()
|
|
||||||
self.file_chooser.filters = [vfilter]
|
|
||||||
self.file_chooser.multiselect = True
|
|
||||||
self.file_chooser.path = self.old_path
|
|
||||||
self.file_chooser.bind(on_submit=self.loadFilepath)
|
|
||||||
c.add_widget(self.file_chooser)
|
|
||||||
b = BoxLayout(size_hint_y=None,height=35)
|
|
||||||
c.add_widget(b)
|
|
||||||
cancel = Button(text='Cancel')
|
|
||||||
cancel.bind(on_press=self.cancelopen)
|
|
||||||
load = Button(text='load')
|
|
||||||
load.bind(on_press=self.playfile)
|
|
||||||
b.add_widget(load)
|
|
||||||
b.add_widget(cancel)
|
|
||||||
self._popup = Popup(title='Open file',content=c,size_hint=(0.9,0.9))
|
|
||||||
self._popup.open()
|
|
||||||
|
|
||||||
def cancelopen(self,obj):
|
|
||||||
self.hideMenu()
|
|
||||||
|
|
||||||
def loadFilepath(self,obj,fpaths,evt):
|
|
||||||
print('fp=',fpaths,type(fpaths),'evt=',evt)
|
|
||||||
self.hideMenu()
|
|
||||||
self.playlist = fpaths
|
|
||||||
self.curplay = 0
|
|
||||||
self._video.source = self.playlist[self.curplay]
|
|
||||||
self._video.state = 'play'
|
|
||||||
|
|
||||||
def playfile(self,obj):
|
|
||||||
print('obj')
|
|
||||||
self.hideMenu()
|
|
||||||
self.playlist = []
|
|
||||||
for f in self.file_chooser.selection:
|
|
||||||
fp = os.path.join(self.file_chooser.path,f)
|
|
||||||
self.playlist.append(fp)
|
|
||||||
self.curplay = 0
|
|
||||||
self._video.source = self.playlist[self.curplay]
|
|
||||||
self._video.state = 'play'
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
class MyApp(App):
|
class MyApp(App):
|
||||||
def build(self):
|
def build(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user