Skip to content

Commit 43cf29d

Browse files
author
arch
committed
add video seek bar
1 parent 2dc9c07 commit 43cf29d

File tree

4 files changed

+30
-1
lines changed

4 files changed

+30
-1
lines changed

funscript_editor/ui/funscript_editor_view.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ def setupUi(self, MainWindow):
3838
self.videoLayout.addWidget(self.videoPane)
3939
spacerItem = QtWidgets.QSpacerItem(40, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
4040
self.videoLayout.addItem(spacerItem)
41+
self.seekBar = QtWidgets.QSlider(self.verticalLayoutWidget)
42+
self.seekBar.setOrientation(QtCore.Qt.Horizontal)
43+
self.seekBar.setObjectName("seekBar")
44+
self.videoLayout.addWidget(self.seekBar)
4145
self.settingsLayout = QtWidgets.QGroupBox(self.splitterHorizontal)
4246
self.settingsLayout.setTitle("")
4347
self.settingsLayout.setObjectName("settingsLayout")

funscript_editor/ui/funscript_editor_view.ui

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@
4646
</property>
4747
</spacer>
4848
</item>
49+
<item>
50+
<widget class="QSlider" name="seekBar">
51+
<property name="orientation">
52+
<enum>Qt::Horizontal</enum>
53+
</property>
54+
</widget>
55+
</item>
4956
</layout>
5057
</widget>
5158
<widget class="QGroupBox" name="settingsLayout">

funscript_editor/ui/funscript_editor_window.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ def __setup_modul_bindings(self):
106106
self.video_player.set_frame_changed_callback(self.__frame_changed_handler)
107107

108108
def __frame_changed_handler(self, frame_num):
109+
if not self.ui.seekBar.isSliderDown():
110+
self.ui.seekBar.setValue(frame_num)
109111
self.funscript_visualizer.set_frame(frame_num)
110112
if self.funscript is None: return
111113
self.ui.currentStrokeLabel.setText('{} ms'.format(\
@@ -126,6 +128,7 @@ def __setup_ui_binding(self):
126128
helpMenu.addAction("App Documentation", lambda : webbrowser.open(os.path.join(APP_DOCUMENTATION_DIR, 'index.html')))
127129
helpMenu.addAction("Code Documentation", lambda : webbrowser.open(os.path.join(CODE_DOCUMENTATION_DIR, 'index.html')))
128130
helpMenu.addAction(str('Version '+VERSION))
131+
self.ui.seekBar.sliderReleased.connect(lambda: self.video_player.seek_frame(self.ui.seekBar.value()))
129132

130133
self.__generateFunscript.connect(self.__generate_funscript)
131134

@@ -269,6 +272,8 @@ def __open_video(self):
269272

270273
self.video_player.set_funscript(self.funscript)
271274
self.funscript_visualizer.set_funscript(self.funscript)
275+
self.ui.seekBar.setMaximum(max((0, self.video_player.get_length-1)))
276+
self.ui.seekBar.setValue(0)
272277

273278
def __new_funscript(self):
274279
self.funscript = Funscript(fps=self.video_player.get_fps)

funscript_editor/ui/video_player.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,12 @@ def __init__(self,
5151
self.indicate_bussy = False
5252
self.bussy_indicator_pos = 0
5353
self.funscript = None
54-
self.fps = None
54+
self.fps = 60
5555
self.stroke_indicator_position = UI_CONFIG['player']['stroke_indicator_pos']
5656
self.stroke_indicator_size = UI_CONFIG['player']['stroke_indicator_size']
5757
self.quit = False
5858
self.duration = 0
59+
self.length = 0
5960
self.key_callback = key_callback
6061
self.player.pause = True
6162
self.invert_stroke_indicator = False
@@ -260,6 +261,16 @@ def get_current_timestamp_in_millis(self) -> int:
260261
return int(ts * 1000)
261262

262263

264+
@property
265+
def get_length(self) -> int:
266+
""" Get video length in frames
267+
268+
Returns:
269+
int: number of frames in video
270+
"""
271+
return self.length
272+
273+
263274
@property
264275
def get_current_frame(self) -> int:
265276
""" Get current frame number
@@ -374,6 +385,7 @@ def open(self, video_file :str) -> None:
374385
self.height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
375386
self.width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
376387
self.duration = cap.get(cv2.CAP_PROP_FRAME_COUNT) / self.fps
388+
self.length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
377389
self.player.loadfile(video_file)
378390
self.video_file = video_file
379391

@@ -403,6 +415,7 @@ def seek_frame(self, frame_number :int) -> None:
403415
Args:
404416
frame_number (int): frame number
405417
"""
418+
if self.length < 1: return
406419
self.player.seek(self.frame_to_millisec(frame_number) * 1.0 / 1000, "absolute", "exact")
407420

408421

0 commit comments

Comments
 (0)