hello i want to make a functional video timeline that shows keyframes like a video editor using Python
library tkinter here is a picture of the desired target
i tried this Python code snipset here but it doesnt show key frames it shows many frames that i dont need and its not functioning like a video editor
<code>`def show_timeline(self):
self.canvas.delete("all")
self.frame_images.clear() # Clear previous frame references
if self.cap:
interval = 0.1 # Interval in seconds
frame_interval = int(self.fps * interval)
canvas_width = self.canvas.winfo_width()
frame_width = 80
max_frames = canvas_width // frame_width
for i in range(0, self.total_frames, frame_interval):
self.cap.set(cv2.CAP_PROP_POS_FRAMES, i)
ret, frame = self.cap.read()
if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame = cv2.resize(frame, (frame_width, 45)) # Resize frame to fit on the timeline
image = Image.fromarray(frame)
image = ImageTk.PhotoImage(image)
x = (i // frame_interval) * frame_width
self.canvas.create_image(x + frame_width//2, 25, image=image)
time_text = f"{int(i / self.fps // 60)}:{int(i / self.fps % 60):02}"
self.canvas.create_text(x + frame_width//2, 60, text=time_text, fill="white")
self.frame_images.append(image) # Keep a reference to avoid garbage collection
if len(self.frame_images) >= max_frames:
break
def update_timeline(self):
current_frame = int(self.cap.get(cv2.CAP_PROP_POS_FRAMES))
frame_interval = int(self.fps * 0.1)
frame_width = 80
# Calculate the index of the current frame in the timeline
frame_index = current_frame // frame_interval
# Scroll the canvas to keep the current frame in view
x = frame_index * frame_width
self.canvas.xview_moveto(x / self.canvas.winfo_width())
# Highlight the current frame
self.canvas.delete("highlight")
self.canvas.create_rectangle(
x, 0, x + frame_width, 50, outline="red", tag="highlight"
)
def slider_update_frame(self, value):
if not self.slider_update:
frame = int(value)
self.cap.set(cv2.CAP_PROP_POS_FRAMES, frame)
self.update_video_frame()`
</code>
<code>`def show_timeline(self):
self.canvas.delete("all")
self.frame_images.clear() # Clear previous frame references
if self.cap:
interval = 0.1 # Interval in seconds
frame_interval = int(self.fps * interval)
canvas_width = self.canvas.winfo_width()
frame_width = 80
max_frames = canvas_width // frame_width
for i in range(0, self.total_frames, frame_interval):
self.cap.set(cv2.CAP_PROP_POS_FRAMES, i)
ret, frame = self.cap.read()
if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame = cv2.resize(frame, (frame_width, 45)) # Resize frame to fit on the timeline
image = Image.fromarray(frame)
image = ImageTk.PhotoImage(image)
x = (i // frame_interval) * frame_width
self.canvas.create_image(x + frame_width//2, 25, image=image)
time_text = f"{int(i / self.fps // 60)}:{int(i / self.fps % 60):02}"
self.canvas.create_text(x + frame_width//2, 60, text=time_text, fill="white")
self.frame_images.append(image) # Keep a reference to avoid garbage collection
if len(self.frame_images) >= max_frames:
break
def update_timeline(self):
current_frame = int(self.cap.get(cv2.CAP_PROP_POS_FRAMES))
frame_interval = int(self.fps * 0.1)
frame_width = 80
# Calculate the index of the current frame in the timeline
frame_index = current_frame // frame_interval
# Scroll the canvas to keep the current frame in view
x = frame_index * frame_width
self.canvas.xview_moveto(x / self.canvas.winfo_width())
# Highlight the current frame
self.canvas.delete("highlight")
self.canvas.create_rectangle(
x, 0, x + frame_width, 50, outline="red", tag="highlight"
)
def slider_update_frame(self, value):
if not self.slider_update:
frame = int(value)
self.cap.set(cv2.CAP_PROP_POS_FRAMES, frame)
self.update_video_frame()`
</code>
`def show_timeline(self):
self.canvas.delete("all")
self.frame_images.clear() # Clear previous frame references
if self.cap:
interval = 0.1 # Interval in seconds
frame_interval = int(self.fps * interval)
canvas_width = self.canvas.winfo_width()
frame_width = 80
max_frames = canvas_width // frame_width
for i in range(0, self.total_frames, frame_interval):
self.cap.set(cv2.CAP_PROP_POS_FRAMES, i)
ret, frame = self.cap.read()
if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame = cv2.resize(frame, (frame_width, 45)) # Resize frame to fit on the timeline
image = Image.fromarray(frame)
image = ImageTk.PhotoImage(image)
x = (i // frame_interval) * frame_width
self.canvas.create_image(x + frame_width//2, 25, image=image)
time_text = f"{int(i / self.fps // 60)}:{int(i / self.fps % 60):02}"
self.canvas.create_text(x + frame_width//2, 60, text=time_text, fill="white")
self.frame_images.append(image) # Keep a reference to avoid garbage collection
if len(self.frame_images) >= max_frames:
break
def update_timeline(self):
current_frame = int(self.cap.get(cv2.CAP_PROP_POS_FRAMES))
frame_interval = int(self.fps * 0.1)
frame_width = 80
# Calculate the index of the current frame in the timeline
frame_index = current_frame // frame_interval
# Scroll the canvas to keep the current frame in view
x = frame_index * frame_width
self.canvas.xview_moveto(x / self.canvas.winfo_width())
# Highlight the current frame
self.canvas.delete("highlight")
self.canvas.create_rectangle(
x, 0, x + frame_width, 50, outline="red", tag="highlight"
)
def slider_update_frame(self, value):
if not self.slider_update:
frame = int(value)
self.cap.set(cv2.CAP_PROP_POS_FRAMES, frame)
self.update_video_frame()`
here is a picture of the result for this code