UnityPlugin-AVProVideo
UnityPlugin-AVProVideo copied to clipboard
[macOS] Frame duration and seeking not accurate
Unity version
2022.3
Unity editor platform
macOS
AVPro Video edition
Ultra
AVPro Video version
3.2.4
Device hardware
Mac Studio M2 Ultra
Which macOS version are you using?
15.2
Texture format
BGRA
Audio output
System Direct
Any other Media Player component configuration required to reproduce the issue.
No response
Which output component(s) are you using?
No response
Any other component configuration required to reproduce the issue.
No response
The issue
I've found what I think are bugs in BaseMediaPlayer.cs
First we have reading frames from media:
public int GetDurationFrames(float overrideFrameRate = 0f)
{
int result = 0;
float frameRate = (overrideFrameRate > 0f) ? overrideFrameRate : GetVideoFrameRate();
if (frameRate > 0f)
{
result = Helper.ConvertTimeSecondsToFrame(GetDuration(), frameRate);
}
}
which when calls
public static int ConvertTimeSecondsToFrame(double seconds, float frameRate)
{
// NOTE: Generally you should use RountToInt when converting from time to frame number
// but because we're adding a half frame offset (which seems to be the safer thing to do) we need to FloorToInt
seconds = System.Math.Max(0.0, seconds);
frameRate = Mathf.Max(0f, frameRate);
return (int)System.Math.Floor(frameRate * seconds);
}
Now when I pass this a media file (link) which has 100 frames over 1.65 seconds (according to ffmpeg) it does this: GetDuration() returns 1.65166666666667 frame rate is passed in as 59.93821 ConvertTimeSecondsToFrame(1.65166666666667, 59.93821) then calculate 98.999 and floors it to returns 98!
Based on the the comment in your code you say half a frames time should be added before the floor function, but no where in this chain of calls does that happen, leading to being off by 1.
I believe GetDurationFrames() should also just be adding 1, because a video of duration 0 should still have 1 frame. Your code in GetMaxFrameNumber() subtracts 1, which I believe only makes sense if GetDurationFrames() was adding 1.
I hope both of these together makes the library more robust. For now I'm working around them by getting frame count through another method and using time based seek not frame based seek helpers.
Media information
No response
Log output