kivy / kivy

Open source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS
https://kivy.org
MIT License
17.79k stars 3.07k forks source link

kivy.uix.video.Video.seek(percent): Does not seek to the right frame. #6292

Open andyDoucette opened 5 years ago

andyDoucette commented 5 years ago

Hello. I'm trying use the kivy.uix.video.Video.seek() function to seek to a specific frame in a video. It does not seem to be working as I expect.

Situation

For example, let's try to seek to the last frame of this 900-frame test video.

#!/usr/bin/python3

from kivy.app import App
from kivy.uix.video import Video
import sys

class TestApp(App):
    video = None

    def replay(self, instance, value):
        if value != "play":
            self.video.state = "play"

    def build(self):
        self.video = Video(source="./fCounter.mp4")

        self.video.state="play"

        self.video.bind(loaded=self.on_loaded)

        return self.video

    def on_loaded(s, *args):
        assert s.video.loaded, 'This should only run after video load.'

        seekAmt=1

        print('Video duration: %f' % s.video.duration, file=sys.stderr)

        print('Seeking to %f from 0-1. ' % seekAmt, file=sys.stderr)

        #Seek to the frame for this event:
        s.video.seek(seekAmt, precise=True)

        #This is the Video state:
        s.state="play"

TestApp().run()

seekAmt=.998 does the same thing.

Expectations

The documentation for this function says: "precise: bool, defaults to True Precise seeking is slower, but seeks to exact requested percent", so as long as I select precise to be true, I expect it to seek to that precise frame.

With a seek amount of between .998-1, I expect the video to start somewhere between .998*900=898 and 900. Instead, it seems to start somewhere around frame 870.

Reproducing

To help make sure that we're all on the same page, I've made a docker container with a specific setup and a minimal example. It can be found here. The readme file gives you the two steps needed to reproduce the issue. That fully documents all of the versions and the config used as well.

Request

If the issue seems to be with some external package, can someone provide a suggestion for how to get this example to work as desired before this is closed? I've tried to change video providers but I haven't found where that is documented, so if that is the solution, maybe this issue report can transform to a "improve documentation in this way" issue?

matham commented 5 years ago

Can you please post the log?

Are you using ffpyplayer or gstreamer. I'm not sure the latter supports precise seeking.

To select the video provider you need to set the environment variable KIVY_VIDEO to your desired provider https://kivy.org/doc/stable/guide/environment.html.

andyDoucette commented 5 years ago

Thanks @matham. I am aware of that KIVY_VIDEO environmental variable. Setting that isn't all that's needed though, as far as I understand. Somehow some other video provider and all of its dependencies needs to be installed and I don't think that's documented anywhere. I did provide an entire docker environment that can be used to get the log and to reproduce the problem and the log, but for expediency I can provide the log here as well.

More specifically, this is the console output when the log level is set to debug.

[WARNING] [Config      ] Older configuration version detected (0 instead of 20)
[WARNING] [Config      ] Upgrading configuration in progress.
[INFO   ] [Logger      ] Record log in /root/.kivy/logs/kivy_19-05-05_0.txt
[INFO   ] [Kivy        ] v1.10.1
[INFO   ] [Python      ] v3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0]
[INFO   ] [Factory     ] 194 symbols loaded
[INFO   ] [Image       ] Providers: img_tex, img_dds, img_sdl2, img_pil, img_gif (img_ffpyplayer ignored)
[INFO   ] [VideoGstplayer] Using Gstreamer 1.14.1.0
[INFO   ] [Video       ] Provider: gstplayer
[INFO   ] [Window      ] Provider: sdl2(['window_egl_rpi'] ignored)
libGL error: failed to open drm device: No such file or directory
libGL error: failed to load driver: i965
[INFO   ] [GL          ] Using the "OpenGL" graphics system
[INFO   ] [GL          ] Backend used <gl>
[INFO   ] [GL          ] OpenGL version <b'3.1 Mesa 18.2.8'>
[INFO   ] [GL          ] OpenGL vendor <b'VMware, Inc.'>
[INFO   ] [GL          ] OpenGL renderer <b'llvmpipe (LLVM 7.0, 256 bits)'>
[INFO   ] [GL          ] OpenGL parsed version: 3, 1
[INFO   ] [GL          ] Shading version <b'1.40'>
[INFO   ] [GL          ] Texture max size <8192>
[INFO   ] [GL          ] Texture max units <32>
[INFO   ] [Window      ] auto add sdl2 input provider
[INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
[ERROR  ] [Image       ] Error loading texture ./fCounter.mp4
[INFO   ] [ProbeSysfs  ] device match: /dev/input/event15
[INFO   ] [MTD         ] Read event from </dev/input/event15>
[INFO   ] [ProbeSysfs  ] device match: /dev/input/event5
[INFO   ] [MTD         ] Read event from </dev/input/event5>
[INFO   ] [Base        ] Start application main loop
[INFO   ] [MTD         ] </dev/input/event15> range position X is 0 - 3776
[INFO   ] [MTD         ] </dev/input/event5> range position X is 1242 - 5702
[INFO   ] [MTD         ] </dev/input/event15> range position Y is 0 - 2112
[INFO   ] [MTD         ] </dev/input/event5> range position Y is 1124 - 4730
[INFO   ] [MTD         ] </dev/input/event15> range touch major is 0 - 255
[INFO   ] [MTD         ] </dev/input/event5> range touch major is 0 - 0
[INFO   ] [MTD         ] </dev/input/event5> range touch minor is 0 - 0
[INFO   ] [MTD         ] </dev/input/event15> range touch minor is 0 - 255
[INFO   ] [MTD         ] </dev/input/event15> range pressure is 0 - 255
[INFO   ] [MTD         ] </dev/input/event15> axes invertion: X is 0, Y is 0
[INFO   ] [MTD         ] </dev/input/event15> rotation set to 0
[INFO   ] [MTD         ] </dev/input/event5> range pressure is 0 - 255
[INFO   ] [MTD         ] </dev/input/event5> axes invertion: X is 0, Y is 0
[INFO   ] [MTD         ] </dev/input/event5> rotation set to 0
ALSA lib confmisc.c:767:(parse_card) cannot find card '0'
ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name
ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5007:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM default
AL lib: (EE) ALCplaybackAlsa_open: Could not open playback device 'default': No such file or directory
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
ALSA lib confmisc.c:767:(parse_card) cannot find card '0'
ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name
ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5007:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM default
AL lib: (EE) ALCplaybackAlsa_open: Could not open playback device 'default': No such file or directory
[INFO   ] [GL          ] NPOT texture support is available
 Video duration: 1.000000
 Seeking to 0.998000 from 0-1. 
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
ALSA lib confmisc.c:767:(parse_card) cannot find card '0'
ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name
ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5007:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM default
AL lib: (EE) ALCplaybackAlsa_open: Could not open playback device 'default': No such file or directory
[WARNING] [VideoGstplayer] b'Jack server not found'
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
ALSA lib confmisc.c:767:(parse_card) cannot find card '0'
ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name
ALSA lib conf.c:4528:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5007:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM default
AL lib: (EE) ALCplaybackAlsa_open: Could not open playback device 'default': No such file or directory
matham commented 5 years ago

Kivy supports gstreamer or ffpyplayer, but yeah, we don't include instructions to install ffpyplayer. We can add a reference to it in the docs.

Here's the instructions though https://matham.github.io/ffpyplayer/installation.html. Keep in mind that instructions are for ffpyplayer master, so it will work work for master, but possibly not for the last release.

andyDoucette commented 5 years ago

@matham . Thank you for those instructions! I'll try ffpyplayer and report back.

If we find that to be the solution, can this documentation please be updated to declare which video backends support precise seeking and provide links to documentation for how to enable and use those backends? Since not all video backends have the same behavior, this abstraction is leaking a bit at the moment and so it would be nice to at least document that in the relevant places.

andyDoucette commented 5 years ago

Ah, yes! I remember... I tried this before. Ran into some obstacles:

The first paragraph in the instructions you linked to says we can install using pip:

[user@dg_groundtruth bin]$ pip install ffpyplayer
Collecting ffpyplayer
  Downloading https://files.pythonhosted.org/packages/d6/72/827ee3a519128ba6ea6e6714789435eefbadc03eef92d642f858bd64a313/ffpyplayer-4.1.0.tar.gz (71kB)
    100% |████████████████████████████████| 71kB 223kB/s 
Building wheels for collected packages: ffpyplayer
  Running setup.py bdist_wheel for ffpyplayer ... error
  Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-ybn_9z4t/ffpyplayer/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/pip-wheel-q1ijj2kw --python-tag cp36:
  WARNING: A problem occured while running pkg-config --libs --cflags libavcodec libavdevice libavfilter libavformat libavutil libswscale libswresample libpostproc (code 1)

  b"Package libavdevice was not found in the pkg-config search path.\nPerhaps you should add the directory containing `libavdevice.pc'\nto the PKG_CONFIG_PATH environment variable\nNo package 'libavdevice' found\nPackage libavfilter was not found in the pkg-config search path.\nPerhaps you should add the directory containing `libavfilter.pc'\nto the PKG_CONFIG_PATH environment variable\nNo package 'libavfilter' found\nPackage libpostproc was not found in the pkg-config search path.\nPerhaps you should add the directory containing `libpostproc.pc'\nto the PKG_CONFIG_PATH environment variable\nNo package 'libpostproc' found\n"

  Selecting SDL2 out of (SDL, SDL2)
  Generating ffconfig.h
  Generating ffconfig.pxi
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.linux-x86_64-3.6
  creating build/lib.linux-x86_64-3.6/ffpyplayer
  copying ffpyplayer/__init__.py -> build/lib.linux-x86_64-3.6/ffpyplayer
  creating build/lib.linux-x86_64-3.6/ffpyplayer/player
  copying ffpyplayer/player/__init__.py -> build/lib.linux-x86_64-3.6/ffpyplayer/player
  creating build/lib.linux-x86_64-3.6/ffpyplayer/tests
  copying ffpyplayer/tests/__init__.py -> build/lib.linux-x86_64-3.6/ffpyplayer/tests
  copying ffpyplayer/tests/test_write.py -> build/lib.linux-x86_64-3.6/ffpyplayer/tests
  copying ffpyplayer/tests/test_play.py -> build/lib.linux-x86_64-3.6/ffpyplayer/tests
  copying ffpyplayer/tests/common.py -> build/lib.linux-x86_64-3.6/ffpyplayer/tests
  copying ffpyplayer/tests/test_pic.py -> build/lib.linux-x86_64-3.6/ffpyplayer/tests
  creating build/lib.linux-x86_64-3.6/ffpyplayer/clib
  copying ffpyplayer/clib/misc.h -> build/lib.linux-x86_64-3.6/ffpyplayer/clib
  running build_ext
  building 'ffpyplayer.pic' extension
  creating build/temp.linux-x86_64-3.6
  creating build/temp.linux-x86_64-3.6/ffpyplayer
  creating build/temp.linux-x86_64-3.6/ffpyplayer/clib
  x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/SDL2 -I/tmp/pip-install-ybn_9z4t/ffpyplayer/ffpyplayer -I/tmp/pip-install-ybn_9z4t/ffpyplayer/ffpyplayer/includes -I/usr/include/python3.6m -c ffpyplayer/pic.c -o build/temp.linux-x86_64-3.6/ffpyplayer/pic.o
  x86_64-linux-gnu-gcc: error: ffpyplayer/pic.c: No such file or directory
  x86_64-linux-gnu-gcc: fatal error: no input files
  compilation terminated.
  error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

  ----------------------------------------
  Failed building wheel for ffpyplayer
  Running setup.py clean for ffpyplayer
Failed to build ffpyplayer
Installing collected packages: ffpyplayer
  Running setup.py install for ffpyplayer ... error
    Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-ybn_9z4t/ffpyplayer/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-record-p48lkh06/install-record.txt --single-version-externally-managed --compile:
    WARNING: A problem occured while running pkg-config --libs --cflags libavcodec libavdevice libavfilter libavformat libavutil libswscale libswresample libpostproc (code 1)

    b"Package libavdevice was not found in the pkg-config search path.\nPerhaps you should add the directory containing `libavdevice.pc'\nto the PKG_CONFIG_PATH environment variable\nNo package 'libavdevice' found\nPackage libavfilter was not found in the pkg-config search path.\nPerhaps you should add the directory containing `libavfilter.pc'\nto the PKG_CONFIG_PATH environment variable\nNo package 'libavfilter' found\nPackage libpostproc was not found in the pkg-config search path.\nPerhaps you should add the directory containing `libpostproc.pc'\nto the PKG_CONFIG_PATH environment variable\nNo package 'libpostproc' found\n"

    Selecting SDL2 out of (SDL, SDL2)
    Generating ffconfig.h
    Generating ffconfig.pxi
    running install
    running build
    running build_py
    creating build
    creating build/lib.linux-x86_64-3.6
    creating build/lib.linux-x86_64-3.6/ffpyplayer
    copying ffpyplayer/__init__.py -> build/lib.linux-x86_64-3.6/ffpyplayer
    creating build/lib.linux-x86_64-3.6/ffpyplayer/player
    copying ffpyplayer/player/__init__.py -> build/lib.linux-x86_64-3.6/ffpyplayer/player
    creating build/lib.linux-x86_64-3.6/ffpyplayer/tests
    copying ffpyplayer/tests/__init__.py -> build/lib.linux-x86_64-3.6/ffpyplayer/tests
    copying ffpyplayer/tests/test_write.py -> build/lib.linux-x86_64-3.6/ffpyplayer/tests
    copying ffpyplayer/tests/test_play.py -> build/lib.linux-x86_64-3.6/ffpyplayer/tests
    copying ffpyplayer/tests/common.py -> build/lib.linux-x86_64-3.6/ffpyplayer/tests
    copying ffpyplayer/tests/test_pic.py -> build/lib.linux-x86_64-3.6/ffpyplayer/tests
    creating build/lib.linux-x86_64-3.6/ffpyplayer/clib
    copying ffpyplayer/clib/misc.h -> build/lib.linux-x86_64-3.6/ffpyplayer/clib
    running build_ext
    building 'ffpyplayer.pic' extension
    creating build/temp.linux-x86_64-3.6
    creating build/temp.linux-x86_64-3.6/ffpyplayer
    creating build/temp.linux-x86_64-3.6/ffpyplayer/clib
    x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/SDL2 -I/tmp/pip-install-ybn_9z4t/ffpyplayer/ffpyplayer -I/tmp/pip-install-ybn_9z4t/ffpyplayer/ffpyplayer/includes -I/usr/include/python3.6m -c ffpyplayer/pic.c -o build/temp.linux-x86_64-3.6/ffpyplayer/pic.o
    x86_64-linux-gnu-gcc: error: ffpyplayer/pic.c: No such file or directory
    x86_64-linux-gnu-gcc: fatal error: no input files
    compilation terminated.
    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

    ----------------------------------------
Command "/usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-ybn_9z4t/ffpyplayer/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-record-p48lkh06/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-install-ybn_9z4t/ffpyplayer/
You are using pip version 18.1, however version 19.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

It seems the pip package is calling for some source within ffpyplayer that doesn't exist.

I also tried installing these dependencies, and then running pip, but that didn't really help:

sudo apt install ffmpeg libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev \ libavutil-dev libswscale-dev libswresample-dev libpostproc-dev libsdl2-dev libsdl2-2.0-0 \ libsdl2-mixer-2.0-0 libsdl2-mixer-dev python3-dev

Is this where that thing about it only working on the master branch comes in? Do I need to compile it from source (uhg!)?

andyDoucette commented 5 years ago

Aah! I see it now!

For Ubuntu 18.04:

#Install dependencies for compiling ffpyplayer:
apt-get install -y  ffmpeg libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev \
                        libavutil-dev libswscale-dev libswresample-dev libpostproc-dev libsdl2-dev \
                        libsdl2-2.0-0 libsdl2-mixer-2.0-0 libsdl2-mixer-dev python3-dev

#Install the master branch:
pip install https://github.com/matham/ffpyplayer/archive/master.zip
#Or, if you want the same code, but in a versioned way:
#pip install https://github.com/matham/ffpyplayer/archive/c99913f2317bf3840eeacf1c1c3db3b3d1f78007.zip

#Tell Kivy to use ffpyplayer:
export KIVY_VIDEO=ffpyplayer

That seemed to do the trick! :) Thank you very much! My train is back on it's tracks. Much appreciated. :D

How does the doc changing happen? Is there source in github I should do a pull request around (and will it be accepted?) Or can someone with more kivy knowledge do that part?

andyDoucette commented 5 years ago

@matham : An update. Seeking with ffpyplayer does not seem to be deterministic. I pause the video and then seek to a specific frame and the frame I get changes +-1 every time I run it. Should I submit another ticket here for that or does that belong somewhere else? I have a minimal example, but am not sure if I should clutter this bug report with that yet.

matham commented 5 years ago

How does the doc changing happen?

Please see https://kivy.org/doc/master/contribute.html#documentation-contributions.

Seeking with ffpyplayer does not seem to be deterministic. I pause the video and then seek to a specific frame and the frame I get changes +-1 every time I run it

That would be a ffpyplayer issue, not a kivy issue. However, I doubt this would be fixed in ffpyplayer as seeking is not that precise. In fact it's probably very hard for it to be that precise, unless the seek time you request happens to fall exactly on a frame. In any case, you can open an issue in ffpyplayer if you like, but unless you plan on working on it it likely would not get fixed.

donquibeats commented 5 years ago

Hello

I know it can be considered bad practice to dig out old threads like this, but I don't have much to add so it seems inappropriate to call it a new issue.

I've hit a brick wall with exactly this issue, as @andyDoucette originally posted, and I'm wondering if there is any practical way around it. I really need to get a Python media player working that's capable of frame-accurate seeking. I've made enquiries on the FFmpeg-users forum as well to see if there's any progress on the FFplay side of things.

Whereas the most recent comment from @matham implied that frame accuracy is a frame-number-rounding issue, I am finding problems where the video.seek() function is moving to a position sometimes over 4 seconds earlier than the percentage calculation ought to.

I did wonder whether there was any kind of rounding issue going on in my code, given that I'm working with video file that are several minutes long, so the percentages I'm requesting sometimes have 17 decimal places of precision (e.g. 0.49305478152322807)- but I didn't get anywhere with that thought.

In the meantime, if anyone has any updates related to this issue, or any new suggested workarounds that would really help me out, I would be very grateful for the info!

tshirtman commented 5 years ago

Hello, did yout try with precise=True ?it'll be a bit slower to seek since it has to fast forward from the last keyframe to the frame you ask, but it should work (though result may depend on video provider).

Alternatively if you can reencode the video to have more keyint (ffmpeg should be able to) it should mitigate the issue.

donquibeats commented 5 years ago

Hello

Thanks for the response.

Yes, I have tried this with precise=True (_self.video.seek(targetpercent, True)) and unfortunately it made no difference to the end result.

The 'precise' flag did not make any difference, it would only seek to a frame before the target frame (presumably the previous keyframe) regardless of whether precise was True or False. To me that has the appearance of a bug.

Unfortunately reencoding the video is not a practical option. These are client-sourced videos over which I have no settings control, and reencoding prior to use doesn't fit the required workflow.

If you believe that video.seek ought to be able to navigate to a precise position (as documented), then that's very promising- but @matham's last comment suggested that the underlying ffplay code may be where the problem lies, which of course is more problematic.

If you think it ought to be solvable, I would be able to provide test MOV's and test code to replicate the issue, if that would help?

matham commented 5 years ago

You're correct that this is a bug. When seeking with precise it should get you pretty close to the requested frame.

However, this is not a issue with ffplay because ffpyplayer is a port of ffplay and doesn't use ffplay directly under the hood. But it is true that ffplay didn't have a way to do precise seeking and when I added it I may well have tested it only with videos without audio. Otherwise, I'm not sure the cause of the bug.

I'm not really working on ffpyplayer anymore, but the best workaround I can suggest is to internally call get_frame until it reaches the desired frame and then start displaying it to the user again. This would be slower than if done natively in ffpyplayer, and doesn't work if you have audio. Otherwise, you'd need to look at the ffpyplayer code to see why precise doesn't work.

donquibeats commented 5 years ago

Thanks for getting back to me.

All the videos I'll be working with have embedded audio, so unfortunately that's something I have to live with. I may test it out with a file without audio just to see if that really is the difference, but splitting the audio out isn't something that will work for this particular project.

I will try the looped get_frame method to see what can be accomplished. Unfortunately this scenario will have users who want to be able to step backwards in a file one frame at a time, and if there's a performance hit because the app has to keep jumping back to the previous keyframe then looping forwards, I can foresee that it might not be fast enough. But I will give it a go.

Digging into the ffpyplayer code is above my level of expertise as it stands but if I do end up going there, I'll let you know.

veyron-github commented 3 years ago

I have tried some GUI package to play the video, kivy has no problems to play, but alse has terrible performance in change the position of the video. I think VLC is the best operation to video, which I have try in tkinter, however I don't know how to make it use in kivy.

In tkinter, this can be use : _media.set_hwnd(wmid) . The wm_id is the widget to show the video texture. In tkinter ,the wm_id can be : _widget.winfoid() But I don't know how to get the winfo_id of the kivy widgets. If use vlc, there are no problems in play the media, why not use it rather than gream...ffmpeg... ?