Skip to content

Commit 6f66d35

Browse files
committed
add MPV button and improve layout
1 parent a1eae6a commit 6f66d35

File tree

1 file changed

+63
-13
lines changed

1 file changed

+63
-13
lines changed

examples/download_motions.py

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77

88
import sys
99
import re
10+
import subprocess
1011
from enum import Flag
11-
from PyQt6.QtWidgets import QApplication, QVBoxLayout, QHBoxLayout, QWidget, QTableWidget, QTableWidgetItem, QPushButton, QLabel, QFileDialog, QHeaderView, QStyle, QSlider, QStyleOptionSlider
12+
from PyQt6.QtWidgets import QApplication, QVBoxLayout, QHBoxLayout, QWidget, QTableWidget, QTableWidgetItem, QPushButton, QLabel, QFileDialog, QHeaderView, QStyle, QSlider, QStyleOptionSlider, QSplitter, QToolTip
1213
from PyQt6.QtMultimedia import QMediaPlayer, QAudioOutput
1314
from PyQt6.QtMultimediaWidgets import QVideoWidget
1415
from PyQt6.QtCore import Qt, QUrl, QTimer
@@ -94,7 +95,7 @@ def pixelPosToRangeValue(self, pos):
9495
class VideoPlayer(QWidget):
9596
def __init__(self, video_files):
9697
super().__init__()
97-
self.setWindowTitle("Video Player")
98+
self.setWindowTitle("Reolink Video Review GUI")
9899

99100
# Create media player
100101
self.media_player = QMediaPlayer()
@@ -120,6 +121,9 @@ def __init__(self, video_files):
120121
self.play_button = QPushButton()
121122
self.play_button.setIcon(self.style().standardIcon(QStyle.StandardPixmap.SP_MediaPlay))
122123
self.play_button.clicked.connect(self.play_pause)
124+
125+
self.mpv_button = QPushButton("MPV")
126+
self.mpv_button.clicked.connect(self.open_in_mpv)
123127

124128
# Create seek slider
125129
self.seek_slider = ClickableSlider(Qt.Orientation.Horizontal)
@@ -138,26 +142,43 @@ def __init__(self, video_files):
138142
speed_label = QLabel("Speed: 2.0x")
139143
self.speed_slider.valueChanged.connect(lambda v: speed_label.setText(f"Speed: {v/100:.1f}x"))
140144

141-
# Set up layout
142145
main_layout = QHBoxLayout()
143-
left_layout = QVBoxLayout()
146+
# Create a splitter
147+
splitter = QSplitter(Qt.Orientation.Horizontal)
148+
149+
# Left side (table and open button)
150+
left_widget = QWidget()
151+
left_layout = QVBoxLayout(left_widget)
144152
left_layout.addWidget(self.video_table)
145153
left_layout.addWidget(self.open_button)
146-
main_layout.addLayout(left_layout)
154+
splitter.addWidget(left_widget)
147155

148-
right_layout = QVBoxLayout()
149-
right_layout.addWidget(self.video_widget)
156+
# Right side (video player and controls)
157+
right_widget = QWidget()
158+
right_layout = QVBoxLayout(right_widget)
159+
right_layout.addWidget(self.video_widget, 1)
160+
161+
controls_widget = QWidget()
162+
controls_layout = QVBoxLayout(controls_widget)
163+
150164
control_layout = QHBoxLayout()
151165
control_layout.addWidget(self.play_button)
152166
control_layout.addWidget(self.seek_slider)
153-
right_layout.addLayout(control_layout)
167+
control_layout.addWidget(self.mpv_button)
168+
controls_layout.addLayout(control_layout)
169+
154170
speed_layout = QHBoxLayout()
155171
speed_layout.addWidget(QLabel("Speed:"))
156172
speed_layout.addWidget(self.speed_slider)
157173
speed_layout.addWidget(speed_label)
158-
right_layout.addLayout(speed_layout)
159-
main_layout.addLayout(right_layout)
174+
controls_layout.addLayout(speed_layout)
175+
right_layout.addWidget(controls_widget)
176+
splitter.addWidget(right_widget)
177+
178+
# Set initial sizes
179+
splitter.setSizes([300, 700]) # Adjust these values as needed
160180

181+
main_layout.addWidget(splitter)
161182
self.setLayout(main_layout)
162183
self.add_initial_videos(video_files)
163184

@@ -183,7 +204,14 @@ def add_video(self, video_path):
183204
start_datetime_str = parsed_data['start_datetime'].strftime("%Y-%m-%d %H:%M:%S")
184205
start_datetime_item = QTableWidgetItem(start_datetime_str)
185206
start_datetime_item.setData(Qt.ItemDataRole.UserRole, parsed_data['start_datetime'])
186-
self.video_table.setItem(row_position, 0, QTableWidgetItem(base_file_name))
207+
208+
# Create the item for the first column with the base file name
209+
file_name_item = QTableWidgetItem(base_file_name)
210+
211+
# Set the full path as tooltip
212+
file_name_item.setToolTip(base_file_name)
213+
214+
self.video_table.setItem(row_position, 0, file_name_item)
187215
self.video_table.setItem(row_position, 1, start_datetime_item)
188216
self.video_table.setItem(row_position, 2, QTableWidgetItem(parsed_data['end_time']))
189217
self.video_table.setItem(row_position, 3, QTableWidgetItem(f"{parsed_data['channel']}"))
@@ -196,14 +224,24 @@ def add_video(self, video_path):
196224
self.video_table.setItem(row_position, 8, QTableWidgetItem("✓" if parsed_data['triggers'] & VOD_trigger.TIMER else ""))
197225
self.video_table.setItem(row_position, 9, QTableWidgetItem(parsed_data['unknown_hex']))
198226

227+
# Set smaller default column widths
228+
self.video_table.setColumnWidth(0, 120) # Video Path
229+
self.video_table.setColumnWidth(1, 130) # Start Datetime
230+
self.video_table.setColumnWidth(2, 80) # End Time
231+
self.video_table.setColumnWidth(3, 35) # Channel
232+
self.video_table.setColumnWidth(4, 35) # Person
233+
self.video_table.setColumnWidth(5, 35) # Vehicle
234+
self.video_table.setColumnWidth(6, 35) # Pet
235+
self.video_table.setColumnWidth(7, 35) # Motion
236+
self.video_table.setColumnWidth(8, 30) # Timer
237+
self.video_table.setColumnWidth(9, 20) # Unknown Hex
238+
199239
# Make the fields non-editable
200240
for column in range(self.video_table.columnCount()):
201241
item = self.video_table.item(row_position, column)
202242
item.setFlags(item.flags() & ~Qt.ItemFlag.ItemIsEditable)
203243
else:
204244
print(f"Could not parse file {video_path}")
205-
for i in range(1, self.video_table.columnCount()):
206-
self.video_table.resizeColumnToContents(i)
207245

208246
def play_video(self, row, column):
209247
video_path = self.video_table.item(row, 0).text()
@@ -254,6 +292,18 @@ def update_duration(self, duration):
254292
def set_speed(self, speed):
255293
self.media_player.setPlaybackRate(speed / 100)
256294

295+
def open_in_mpv(self):
296+
current_video = self.media_player.source().toString()
297+
if current_video:
298+
# Remove the 'file://' prefix if present
299+
video_path = current_video.replace('file://', '')
300+
try:
301+
subprocess.Popen(['mpv', video_path])
302+
except FileNotFoundError:
303+
print("Error: MPV player not found. Make sure it's installed and in your system PATH.")
304+
else:
305+
print("No video is currently selected.")
306+
257307
def read_config(props_path: str) -> dict:
258308
"""Reads in a properties file into variables.
259309

0 commit comments

Comments
 (0)