-
-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The wrong subtitle is sometimes displayed when "Seek Selection start" is used with the video paused #181
Comments
For what it's worth, I tried a very dumb change to attempt to solve the problem and it doesn't work, even with a delay: diff --git a/gaupol/agents/video.py b/gaupol/agents/video.py
index cd737197..6ce3af80 100644
--- a/gaupol/agents/video.py
+++ b/gaupol/agents/video.py
@@ -309,11 +309,16 @@ class VideoAgent(aeidon.Delegate):
@aeidon.deco.export
def _on_seek_selection_start_activate(self, *args):
"""Seek to the start of selection."""
- page = self.get_current_page()
- rows = page.view.get_selected_rows()
- pos = page.project.subtitles[rows[0]].start_seconds
- offset = gaupol.conf.video_player.context_length
- self.player.seek(max(pos - offset, 0))
+ for i in range(2):
+ import time
+ if i == 1:
+ time.sleep(0.5)
+ print("seeking", i)
+ page = self.get_current_page()
+ rows = page.view.get_selected_rows()
+ pos = page.project.subtitles[rows[0]].start_seconds
+ offset = gaupol.conf.video_player.context_length
+ self.player.seek(max(pos - offset, 0))
def _on_seekbar_change_value(self, seekbar, scroll, value, data=None):
"""Seek to specified position in video.""" |
I have also tried seeking 100 ms later and the problem is still present: diff --git a/gaupol/agents/video.py b/gaupol/agents/video.py
index cd737197..aa46d829 100644
--- a/gaupol/agents/video.py
+++ b/gaupol/agents/video.py
@@ -313,6 +313,7 @@ class VideoAgent(aeidon.Delegate):
rows = page.view.get_selected_rows()
pos = page.project.subtitles[rows[0]].start_seconds
offset = gaupol.conf.video_player.context_length
+ offset = -0.1
self.player.seek(max(pos - offset, 0))
def _on_seekbar_change_value(self, seekbar, scroll, value, data=None): |
I would suggest adding debug prints to |
I added this: diff --git a/gaupol/agents/video.py b/gaupol/agents/video.py
index cd737197..dedb4b4f 100644
--- a/gaupol/agents/video.py
+++ b/gaupol/agents/video.py
@@ -240,14 +240,18 @@ class VideoAgent(aeidon.Delegate):
if not self.player.ready:
return True # to be called again.
pos = self.player.get_position(aeidon.modes.SECONDS)
+ print(f"pos={pos}")
if pos is None:
return True # to be called again.
subtitles = list(filter(lambda x: x[0] <= pos <= x[1], self._cache))
if subtitles:
text = subtitles[-1][2]
+ print("subtitles found", text)
if text != self.player.subtitle_text_raw:
+ print("subtitles need to be updated")
self.player.subtitle_text = text
else:
+ print("no subtitles found")
if self.player.subtitle_text:
self.player.subtitle_text = ""
return True # to be called again. I can see the value of I'm also going to remove the |
I tried updating diff --git a/gaupol/agents/video.py b/gaupol/agents/video.py
index cd737197..ba6d3ae7 100644
--- a/gaupol/agents/video.py
+++ b/gaupol/agents/video.py
@@ -245,8 +245,8 @@ class VideoAgent(aeidon.Delegate):
subtitles = list(filter(lambda x: x[0] <= pos <= x[1], self._cache))
if subtitles:
text = subtitles[-1][2]
- if text != self.player.subtitle_text_raw:
- self.player.subtitle_text = text
+ print("updating text")
+ self.player.subtitle_text = text
else:
if self.player.subtitle_text:
self.player.subtitle_text = "" |
The textoverlay plugin doesn't really have much of an API, just a "text" property, so maybe some more general GStreamer thing is needed. Maybe try something like seeking one frame forwards after changing the text? There might also be something in Playbin or GstPipeline to try, but looking at the API documentation, I don't see anything obvious. |
I don't even need to actually seek to a different frame, seeking to the same position after changing the text fixes the problem: diff --git a/gaupol/agents/video.py b/gaupol/agents/video.py
index cd737197..642a4962 100644
--- a/gaupol/agents/video.py
+++ b/gaupol/agents/video.py
@@ -247,6 +247,7 @@ class VideoAgent(aeidon.Delegate):
text = subtitles[-1][2]
if text != self.player.subtitle_text_raw:
self.player.subtitle_text = text
+ self.player.seek(pos)
else:
if self.player.subtitle_text:
self.player.subtitle_text = "" I have performed a few tests:
My supposition is that I'm attaching a test video and subtitle that you can use to reproduce the problem and test the fix. To reproduce:
I can also see the problem on Archlinux with gaupol 1.9 and gstreamer 1.18.2. |
Running with
|
Thanks, this confirms that it's an update issue in GStreamer, but hopefully as an actual fix we can find something better than the seek. I'll test this soon, when I have the time.
There is the pipeline state. It's currently just used to distinguish between play/pause, but if I remember correctly, the state data that comes from GStreamer is very detailed. https://github.com/otsaloma/gaupol/blob/master/gaupol/player.py#L267 |
Sadly I didn't see much of interest to get from this: diff --git a/gaupol/player.py b/gaupol/player.py
index b9517fd2..f163c011 100644
--- a/gaupol/player.py
+++ b/gaupol/player.py
@@ -267,6 +267,7 @@ class VideoPlayer(aeidon.Observable):
def _on_bus_message_state_changed(self, bus, message):
"""Emit signal if state changed in a relevant manner."""
old, new, pending = message.parse_state_changed()
+ print(old, new, pending)
states = (Gst.State.NULL, Gst.State.PAUSED, Gst.State.PLAYING)
if not new in states: return
if new == self._prev_state: return All I get is this:
|
I found this now, it was the async-done message. It was not the state that was detailed, but the messages and you need to subscribe to them one by one. That did not help though. I tried a bunch of stuff, but didn't find anything better than the seek. It feels a bit silly, but I don't notice any slow-down or glitches. Zero seek with a slightly outdated position is on my computer about a 0.2 ms jump back, but that's less than a frame and probably not noticeable. I'd move the seek to Player, but otherwise the same. If this causes some issues, it's possible to later make it conditional, but I wouldn't complicate this unless there's a reason to. diff --git a/gaupol/player.py b/gaupol/player.py
index 2617c04d..e71afe07 100644
--- a/gaupol/player.py
+++ b/gaupol/player.py
@@ -395,6 +395,10 @@ class VideoPlayer(aeidon.Observable):
text = aeidon.RE_ANY_TAG.sub("", text)
text = GLib.markup_escape_text(text)
self._text_overlay.props.text = text
+ # Do a zero seek to force an update of the overlay.
+ # https://github.com/otsaloma/gaupol/issues/181
+ with aeidon.util.silent(Exception, tb=True):
+ self.seek_relative(0)
@property
def volume(self): Shall we go with this? |
I don't really understand that part. Where do you see that 0.2 ms difference? In the value of the timestamp?
I tried doing it on a few HD videos for which seeking takes some time and I couldn't really check whether it was taking longer than just one seek. But as you said, it can probably be made conditional later if necessary.
Sure :) |
def seek_relative(self, offset):
"""Seek to `offset` relative to current position."""
self._ensure_default_segment()
pos = self.get_position(aeidon.modes.SECONDS)
duration = self.get_duration(aeidon.modes.SECONDS)
if pos is None or duration is None: return
pos = pos + self.calc.to_seconds(offset)
pos = max(0, min(pos, duration))
pos = pos * Gst.SECOND
seek_flags = Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE
self._playbin.seek_simple(Gst.Format.TIME, seek_flags, pos) I mean if the video is playing and I add a second |
If I make it simple, it goes down to 0.07 ms and works just the same. pos = self.get_position(mode=None)
if pos is None: return
seek_flags = Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE
self._playbin.seek_simple(Gst.Format.TIME, seek_flags, pos) |
There it is, thanks for debugging! |
Hi,
I have a video for which subtitles start points match frame timecodes exactly.
I have set
context_length = 0
and I'm using Seek Selection start with the video paused and I noticed that:I don't really know how to reproduce this reliably: if I try to repeatedly seek to one subtitle, then to the previous one, it never fails. However, it happens when I keep seeking to the start of different subtitles sequentially (sub number 1, then number 2, number 3, etc.). Unpausing the video makes the right sub appear.
As a workaround, I now press Ctrl+up twice every time to make sure I get the right subtitle to appear.
I am running gaupol 1.9 and gstreamer 1.16.2 on Gentoo. I haven't yet tried to reproduce on another distro.
The text was updated successfully, but these errors were encountered: