This commit is contained in:
yumoqing 2022-11-19 15:47:55 +08:00
parent f380aadf94
commit f4e8d384c5
24 changed files with 97 additions and 54 deletions

0
kivyblocks/baseWidget.py Executable file → Normal file
View File

0
kivyblocks/blocks.py Executable file → Normal file
View File

0
kivyblocks/dg.py Executable file → Normal file
View File

0
kivyblocks/externalwidgetmanager.py Executable file → Normal file
View File

View File

@ -1,4 +1,5 @@
from traceback import print_exc
import time import time
import numpy as np import numpy as np
from ffpyplayer.player import MediaPlayer from ffpyplayer.player import MediaPlayer
@ -16,7 +17,32 @@ from kivy.graphics.texture import Texture
from kivy.graphics import Color, Line from kivy.graphics import Color, Line
from kivyblocks.ready import WidgetReady from kivyblocks.ready import WidgetReady
from kivyblocks.baseWidget import Running from kivyblocks.baseWidget import Running
from kivyblocks.videobehavior import VideoBehavior
vhks = ['v_src',
'play_mode',
'header_callback',
'audio_id',
'duration',
'position',
'volume',
'timeout',
'in_center_focus',
'renderto',
'auto_play',
'repeat'
]
class FFVideo(WidgetReady, VideoBehavior, Widget):
def __init__(self, **kw):
kw1 = {k:v for k,v in kw.items() if k in vhks}
kw1['renderto'] = 'background'
kw2 = {k:v for k,v in kw.items() if k not in vhks}
Widget.__init__(self, **kw2)
VideoBehavior.__init__(self, **kw1)
WidgetReady.__init__(self)
"""
class FFVideo(WidgetReady, Image): class FFVideo(WidgetReady, Image):
v_src = StringProperty(None) v_src = StringProperty(None)
status = OptionProperty('stop', \ status = OptionProperty('stop', \
@ -130,7 +156,8 @@ class FFVideo(WidgetReady, Image):
def on_parent(self, *args): def on_parent(self, *args):
if self.parent: if self.parent:
return return
self._play_stop() # self._play_stop()
print('on_parent() called -----------')
def on_startplay(self, *args): def on_startplay(self, *args):
pass pass
@ -228,7 +255,9 @@ class FFVideo(WidgetReady, Image):
print('ff_opts=', ff_opts) print('ff_opts=', ff_opts)
print('lib_opts=', lib_opts) print('lib_opts=', lib_opts)
# self._player = MediaPlayer(self.v_src) print('EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEe')
print_exc()
print('EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEe')
self._player = MediaPlayer(self.v_src, ff_opts=ff_opts, \ self._player = MediaPlayer(self.v_src, ff_opts=ff_opts, \
lib_opts=lib_opts) lib_opts=lib_opts)
# self._play_start() # self._play_start()
@ -403,3 +432,4 @@ class FFVideo(WidgetReady, Image):
self.vh_task = Clock.schedule_once(self.video_handle, 0) self.vh_task = Clock.schedule_once(self.video_handle, 0)
self.block_task = Clock.schedule_once(self.video_blocked, self.timeout) self.block_task = Clock.schedule_once(self.video_blocked, self.timeout)
"""

0
kivyblocks/imgs/bullet_arrow_down.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 201 B

After

Width:  |  Height:  |  Size: 201 B

0
kivyblocks/imgs/bullet_arrow_right.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 315 B

After

Width:  |  Height:  |  Size: 315 B

0
kivyblocks/imgs/folder.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 537 B

After

Width:  |  Height:  |  Size: 537 B

0
kivyblocks/imgs/picture_empty.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 463 B

After

Width:  |  Height:  |  Size: 463 B

View File

@ -2,9 +2,8 @@
from kivy.uix.floatlayout import FloatLayout from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget from kivy.uix.widget import Widget
from kivyblocks.bgcolorbehavior import BGColorBehavior from kivyblocks.bgcolorbehavior import BGColorBehavior
from kivyblocks.utils import SUPER from kivyblocks.utils import widget_build
from kivyblocks.mixin import get_mixins, filter_mixin from kivyblocks.mixin import get_mixins, filter_mixin
from kivyblocks.register import widget_build
class LandscopeHide(FloatLayout): class LandscopeHide(FloatLayout):
def __init__(self, fix_desc=None, float_desc=None, **kw): def __init__(self, fix_desc=None, float_desc=None, **kw):

View File

@ -47,10 +47,12 @@ from .pyinterpreter import PyInterpreter
from .circle_progress import CircleProgress from .circle_progress import CircleProgress
from .modalbehavior import ModalBehavior from .modalbehavior import ModalBehavior
from .videobehavior import VideoBehavior from .videobehavior import VideoBehavior
from .landscopehide import LandscopeHide
r = Factory.register r = Factory.register
# if kivy.platform in ['win','linux', 'macosx']: # if kivy.platform in ['win','linux', 'macosx']:
# r('ScreenWithMic', ScreenWithMic) # r('ScreenWithMic', ScreenWithMic)
r('LandscopeHide', LandscopeHide)
r('VideoBehavior', VideoBehavior) r('VideoBehavior', VideoBehavior)
r('ModalBehavior', ModalBehavior) r('ModalBehavior', ModalBehavior)
r('CircleProgress', CircleProgress) r('CircleProgress', CircleProgress)
@ -155,8 +157,4 @@ def register_blocks(name, value):
except: except:
Logger.info(f'plugin : register_blocks():{name} register error') Logger.info(f'plugin : register_blocks():{name} register error')
def widget_build(desc):
b = Factory.Blocks()
w = b.widgetBuild(desc)
return w

View File

@ -27,6 +27,8 @@ class Script:
def __init__(self): def __init__(self):
config = getConfig() config = getConfig()
self.root = config.script_root self.root = config.script_root
if sep != '/':
self.root = self.root.replace(sep, '/')
# print('Script.root=', self.root) # print('Script.root=', self.root)
self.env = {} self.env = {}
self.env['uihome'] = config.uihome self.env['uihome'] = config.uihome
@ -38,8 +40,13 @@ class Script:
def url2filepath(self, url): def url2filepath(self, url):
if url.startswith('file://'): if url.startswith('file://'):
url = url[7:] url = url[7:]
ret = join(self.root, *url.split('/')) parts = self.root.split('/')
print('url2filepath():root=', self.root, url, ret) if url[0] == '/':
url = url[1:]
parts += url.split('/')
ret = '/'.join(parts)
# ret = join(self.root, *url.split('/'))
print('url2filepath():root=', self.root, url, parts, ret)
return ret return ret
def show_info(self, env): def show_info(self, env):
@ -67,12 +74,13 @@ class Script:
env['root_path'] = self.root env['root_path'] = self.root
env['url'] = url env['url'] = url
env['filepath'] = filepath env['filepath'] = filepath
h = handler(env) h = handler(self, env)
d = h.render() d = h.render()
try: try:
return json.loads(d) return json.loads(d)
except: except:
return d return d
return filepath
def register(self, suffix, handler): def register(self, suffix, handler):
self.handlers[suffix] = handler self.handlers[suffix] = handler
@ -81,6 +89,10 @@ class Script:
self.env.update({n:v}) self.env.update({n:v})
class BaseHandler: class BaseHandler:
def real_filepath(self, url):
myurl = self.entire_url(url)
return self.script.url2filepath(myurl)
def entire_url(self, url): def entire_url(self, url):
if url.startswith('file://') or \ if url.startswith('file://') or \
url.startswith('http://') or \ url.startswith('http://') or \
@ -89,38 +101,42 @@ class BaseHandler:
tokens = url.split('/') tokens = url.split('/')
if tokens[0] == '': if tokens[0] == '':
root = self.env['uihome'] root = self.env['uihome']
tokens[0] = root if root[-1] == '/':
return '/'.join(tokens) return root + url[1:]
else:
tokens[0] = root
return '/'.join(tokens)
p1 = self.env['url'].split('/')[:-1] p1 = self.env['url'].split('/')[:-1]
ret = '/'.join(p1+tokens) ret = '/'.join(p1+tokens)
"""
print('entire_url(): org_url=', self.env['url'], print('entire_url(): org_url=', self.env['url'],
'url=', url, 'url=', url,
'p1=', p1, 'p1=', p1,
'tokens=', tokens, 'tokens=', tokens,
'ret=', ret) 'ret=', ret)
"""
return ret return ret
def __init__(self, env): def __init__(self, script, env):
self.script = script
self.env = env self.env = env
self.env['entire_url'] = self.entire_url self.env['entire_url'] = self.entire_url
self.env['real_filepath'] = self.real_filepath
class TemplateHandler(BaseHandler): class TemplateHandler(BaseHandler):
def __init__(self, env): def __init__(self, script, env):
super().__init__(env) super().__init__(script, env)
root = env['root_path'] root = env['root_path']
paths = [root] paths = [root]
fp = env['filepath'][len(root):] fp = env['filepath'][len(root)+1:]
plst = fp.split(sep)[:-1] plst = fp.split('/')[:-1]
self.templ_file = basename(env['filepath']) self.templ_file = basename(env['filepath'])
cpath = root cpath = root
for p in plst: for p in plst:
cpath = join(cpath, p) cpath = f'{cpath}/{p}'
paths.append(cpath) paths.append(cpath)
paths.reverse() paths.reverse()
print(f'paths={paths}')
self.engine = MyTemplateEngine(paths) self.engine = MyTemplateEngine(paths)
def render(self): def render(self):
@ -132,8 +148,8 @@ class TemplateHandler(BaseHandler):
traceback.print_exc() traceback.print_exc()
class DspyHandler(BaseHandler): class DspyHandler(BaseHandler):
def __init__(self, env): def __init__(self, script, env):
super().__init__(env) super().__init__(script, env)
def loadScript(self, path): def loadScript(self, path):
data = '' data = ''

0
kivyblocks/ttf/DroidSansFallback.ttf Executable file → Normal file
View File

View File

@ -3,13 +3,14 @@ from traceback import print_exc
from traceback import print_exc from traceback import print_exc
from kivy.app import App from kivy.app import App
from kivy.logger import Logger from kivy.logger import Logger
from appPublic.jsonConfig import getConfig from kivy.factory import Factory
from kivy.uix.popup import Popup from kivy.uix.popup import Popup
from kivy.uix.button import Button from kivy.uix.button import Button
from kivy.uix.label import Label from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout from kivy.uix.boxlayout import BoxLayout
from kivy.uix.modalview import ModalView from kivy.uix.modalview import ModalView
from kivy.uix.image import AsyncImage from kivy.uix.image import AsyncImage
from appPublic.jsonConfig import getConfig
from appPublic.dictObject import DictObject from appPublic.dictObject import DictObject
from .mixin import filter_mixin, get_mixins, mixin_behaviors from .mixin import filter_mixin, get_mixins, mixin_behaviors
@ -244,3 +245,9 @@ def show_widget_info(w, tag='DEBUG'):
id = getattr(w, 'widget_id', 'null') id = getattr(w, 'widget_id', 'null')
msg=f"""{tag}:size_hint={w.size_hint},size={w.size},pos={w.pos},widget_id={id},{w}""" msg=f"""{tag}:size_hint={w.size_hint},size={w.size},pos={w.pos},widget_id={id},{w}"""
Logger.info(msg) Logger.info(msg)
def widget_build(desc):
b = Factory.Blocks()
w = b.widgetBuild(desc)
return w

View File

@ -1,4 +1,5 @@
from traceback import print_exc
import time import time
import numpy as np import numpy as np
from ffpyplayer.player import MediaPlayer from ffpyplayer.player import MediaPlayer
@ -32,10 +33,11 @@ class VideoBehavior(object):
auto_play=BooleanProperty(True) auto_play=BooleanProperty(True)
repeat=BooleanProperty(False) repeat=BooleanProperty(False)
in_center_focus = BooleanProperty(False) in_center_focus = BooleanProperty(False)
render_to = OptionProperty('foreground', options=['background', 'foreground', 'cover']) renderto = OptionProperty('foreground', options=['background', 'foreground', 'cover'])
def __init__(self, **kwargs): def __init__(self, **kwargs):
self._player = None self._player = None
self.change_size_task = None
self._update_task = None self._update_task = None
self.running = None self.running = None
self.vh_task = None self.vh_task = None
@ -56,7 +58,7 @@ class VideoBehavior(object):
self.register_event_type('on_load_success') self.register_event_type('on_load_success')
self.register_event_type('on_startplay') self.register_event_type('on_startplay')
self.bind(size=self.set_video_size) self.bind(size=self.set_video_size)
self.bind(parent=self.stop_when_remove) # self.bind(parent=self.stop_when_remove)
for k, v in kwargs.items(): for k, v in kwargs.items():
setattr(self, k, v) setattr(self, k, v)
@ -142,6 +144,7 @@ class VideoBehavior(object):
pass pass
def on_frame(self, *args): def on_frame(self, *args):
return
w = self.get_root_window() w = self.get_root_window()
if w is None: if w is None:
self.status = 'stop' self.status = 'stop'
@ -149,12 +152,6 @@ class VideoBehavior(object):
if self._player is None: if self._player is None:
return return
if not self.playing:
self.dispatch('on_startplay')
self._player.request_channel( \
'audio', 'open', self.audio_id)
self.seek(self.position)
self.playing = True
def __del__(self): def __del__(self):
self._play_stop() self._play_stop()
@ -205,34 +202,27 @@ class VideoBehavior(object):
self._player.request_channel('audio', action='cycle') self._player.request_channel('audio', action='cycle')
def on_v_src(self, o, src): def on_v_src(self, o, src):
# self.running = Running(self)
self.status = 'stop' self.status = 'stop'
self.playing = False
ff_opts = { ff_opts = {
'pause':False 'pause':False
} }
if self.play_mode == 'preview': if self.play_mode == 'preview':
ff_opts['lowres'] = 2 # 1/4 size ff_opts['lowres'] = 2 # 1/4 size
ff_opts['an'] = True ff_opts['an'] = True
elif self.play_mode == 'audioonly': elif self.play_mode == 'audioonly':
ff_opts['vn'] = True ff_opts['vn'] = True
ff_opts.update(self.ff_opts) ff_opts.update(self.ff_opts)
lib_opts = { lib_opts = {
} }
lib_opts.update(self.lib_opts) lib_opts.update(self.lib_opts)
heads = self._get_spec_headers(self.v_src) heads = self._get_spec_headers(self.v_src)
if heads: if heads:
lib_opts.update({'headers':heads}) lib_opts.update({'headers':heads})
ff_opts.update({'headers':heads}) # ff_opts.update({'headers':heads})
print('ff_opts=', ff_opts)
print('lib_opts=', lib_opts)
# self._player = MediaPlayer(self.v_src)
self._player = MediaPlayer(self.v_src, ff_opts=ff_opts, \ self._player = MediaPlayer(self.v_src, ff_opts=ff_opts, \
lib_opts=lib_opts) lib_opts=lib_opts)
self.playing = False
if self.auto_play: if self.auto_play:
self.play() self.play()
@ -257,13 +247,11 @@ class VideoBehavior(object):
self.status = 'pause' self.status = 'pause'
def _get_video_info(self): def _get_video_info(self):
if not self.playing: meta = self._player.get_metadata()
self.playing = True self.duration = meta['duration']
meta = self._player.get_metadata() self._out_fmt = meta['src_pix_fmt']
self.duration = meta['duration'] self.frame_rate = meta['frame_rate']
self._out_fmt = meta['src_pix_fmt'] self.videosize = meta['src_vid_size']
self.frame_rate = meta['frame_rate']
self.videosize = meta['src_vid_size']
def _play_stop(self): def _play_stop(self):
if self._player: if self._player:
@ -287,6 +275,10 @@ class VideoBehavior(object):
self.videosize = None self.videosize = None
def set_video_size(self, *args): def set_video_size(self, *args):
if self.change_size_task:
self.change_size_task.cancel()
self.change_size_task = Clock.schedule_once(self._set_video_size, 0.1)
def _set_video_size(self, *args):
if self._player is None: if self._player is None:
return return
if self.videosize == None: if self.videosize == None:
@ -294,10 +286,13 @@ class VideoBehavior(object):
w, h = self.videosize w, h = self.videosize
r = w / h r = w / h
r1 = self.width / self.height r1 = self.width / self.height
# position = self.position
if r1 >= r: if r1 >= r:
self._player.set_size(-1, self.height) self._player.set_size(-1, self.height)
else: else:
self._player.set_size(self.width, -1) self._player.set_size(self.width, -1)
# self.seek(position)
# print('_set_video_size():position=', position)
def set_black(self): def set_black(self):
if self.is_black: if self.is_black:
@ -365,7 +360,6 @@ class VideoBehavior(object):
canvas.clear() canvas.clear()
with canvas: with canvas:
Rectangle(texture=texture, pos=pos, size=(w, h)) Rectangle(texture=texture, pos=pos, size=(w, h))
self.canvas.after.clear()
Color(1,1,1,1) Color(1,1,1,1)
Line(points=[0, 1, self.width, 1], width=2) Line(points=[0, 1, self.width, 1], width=2)
Color(1,0,0,1) Color(1,0,0,1)
@ -397,7 +391,6 @@ class VideoBehavior(object):
self.vh_task = Clock.schedule_once(self.video_handle, 0.1) self.vh_task = Clock.schedule_once(self.video_handle, 0.1)
return return
self. _get_video_info()
self.last_frame = frame self.last_frame = frame
self.video_ts = val self.video_ts = val
if self.last_val is None: if self.last_val is None:
@ -416,10 +409,10 @@ class VideoBehavior(object):
self.start_task = None self.start_task = None
if self.block_task: if self.block_task:
self.block_task.cancel() self.block_task.cancel()
# if self.running: if not self.playing:
# print('runnung dismiss ........') self.playing = True
# self.running.dismiss() self._get_video_info()
# self.running = None self.dispatch('on_startplay')
self.position = self._player.get_pts() self.position = self._player.get_pts()
self.volume = self._player.get_volume() self.volume = self._player.get_volume()
img, t = self.last_frame img, t = self.last_frame

0
kivyblocks/widgetExt/__init__.py Executable file → Normal file
View File

0
kivyblocks/widgetExt/androidwebview.py Executable file → Normal file
View File

0
kivyblocks/widgetExt/binstateimage.py Executable file → Normal file
View File

0
kivyblocks/widgetExt/dataloader.py Executable file → Normal file
View File

0
kivyblocks/widgetExt/inputext.py Executable file → Normal file
View File

0
kivyblocks/widgetExt/jsoncodeinput.py Executable file → Normal file
View File

0
kivyblocks/widgetExt/scrollwidget.py Executable file → Normal file
View File

0
kivyblocks/widgetExt/sqldataloadder.py Executable file → Normal file
View File

0
setup.py Executable file → Normal file
View File