RenderHeads / UnityPlugin-AVProVideo

AVPro Video is a multi-platform Unity plugin for advanced video playback
https://www.renderheads.com/products/avpro-video/
226 stars 28 forks source link

SeekToFrame not working directly after OpenMedia #860

Open HolgerDurach opened 3 years ago

HolgerDurach commented 3 years ago

Describe the issue doing a SeekToFrame directly after an call to OpenMedia does nothing also GetMaxFrameNumber returns 0... mediaPlayer.OpenMedia(MediaPathType.RelativeToProjectFolder, clip.originalPath); //loading a new media mediaPlayer.Control.SeekToFrame(30); //does nothing because of an early out for framerate <= 0 mediaPlayer.Control.Seek(2.0f); //seems to work fine EDIT: Sorry, my fault, does also not work... so when am I allowed to seek? what I am trying to archive is to start the video not from the beginning, but directly from frame 30... would really be great to maybe even have that as an option for OpenMedia (offset) (in https://github.com/RenderHeads/UnityPlugin-AVProVideo/issues/766#issuecomment-843252311 you said you are working on something like this, so would still be great to get this)

Your Setup (please complete the following information):

it really feels like the frame-based operations a not the prefered way in AvPro, there is also no fastSeek version of it... maybe I should reconsider my design =)

AndrewRH commented 3 years ago

Hi,

We will have to look into this. I thought we had this feature working...

Yes the reason why seeking to a frame doesn't work before the video has loaded is because we need to convert that frame number into a time value, and so we need to know the frame rate of this. If you already know the frame rate yourself, then you can pass this into the SeekToFrame method as an additional parameter and it will just use this to calculate the time and seek to that time.

The reason you can't use SeekFast is because when seeking to a frame you already has specified that you want to seek to an exact frame, so a Seek is needed. SeekFast is approximate and seeks to the nearest keyframe. If your video contains only keyframes then both methods will be the same speed.

Frame based operations are not preferred in most media players because most media can be in all sorts of strange formats, some of which don't have a variable frame rate, so time is always the preferred way to seek in general purpose media players.

We are indeed looking at making better support for starting a video at a specific time or frame, and have a 'clip' feature in the works.

I will get back to you about this issue after some investigation.

Thanks,

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

artoonie commented 2 years ago

A quick workaround, for others who search and find this ticket, is just to wait until the FPS is nonzero:

    bool IsReadyToSeek()
    {       
        return m_MediaPlayer.Info.GetVideoFrameRate() != 0;
    }   

    void SetTime(double seconds)
    {       
        if (IsReadyToSeek())
        {
            m_MediaPlayer.Control.SeekFast(seconds);
        }
        else
        {
            StartCoroutine(SetTimeSoon(seconds));
        }   
    }   

    IEnumerator SetTimeSoon(double seconds)
    {       
        yield return new WaitUntil(IsReadyToSeek);
        SetTime(seconds);
    }
acgourley commented 2 years ago

We listen for "FirstFrameReady" and seek at that point. I worry this is making our playback buffer longer than necessary though, and look forward to seeing an official method for starting at offset second (or frame number).

Note, in a quick test, SeekToFrame doesn't even work. Perhaps just my platform and stream.