Skip to content
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

Desktop: Support high framerate videos and synchronize video to audio #95

Merged
merged 1 commit into from
Oct 31, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ abstract public class CommonVideoPlayerDesktop extends AbstractVideoPlayer imple
Texture texture;
Music audio;
long startTime = 0;
boolean showAlreadyDecodedFrame = false;
long lastFrameID = 0;
float targetPosition = 0;

boolean paused = false;
boolean looping = false;
boolean isFirstFrame = true;
long timeBeforePause = 0;

int currentVideoWidth, currentVideoHeight;
int videoBufferWidth;
Expand Down Expand Up @@ -157,15 +157,39 @@ public boolean update () {
// Since startTime is 0, this means that we should now display the first frame of the video, and set the
// time.
startTime = System.currentTimeMillis();
targetPosition = 0;
if (audio != null) {
audio.play();
}
}

boolean newFrame = false;
if (!showAlreadyDecodedFrame) {

long currentFrameID = Gdx.graphics.getFrameId();
if (currentFrameID != lastFrameID) {
lastFrameID = Gdx.graphics.getFrameId();
// Update video position
if (audio != null) {
targetPosition = audio.getPosition();
} else {
float delta = Gdx.graphics.getDeltaTime();
if (delta < 0.25f) {
targetPosition += delta;
}
}
}

float currentPosition = isFirstFrame ? -1 : (float)decoder.getCurrentFrameTimestamp();

while (currentPosition <= targetPosition) {
ByteBuffer videoData = decoder.nextVideoFrame();
if (videoData != null) {
float newPosition = (float)decoder.getCurrentFrameTimestamp();
if (newPosition == currentPosition) {
// A frame was repeated (not loaded fast enough)
break;
}
currentPosition = newPosition;
if (texture == null) {
texture = new Texture(getTextureWidth(), getTextureHeight(), Format.RGB888);
texture.setFilter(minFilter, magFilter);
Expand Down Expand Up @@ -196,9 +220,6 @@ public boolean update () {
}

isFirstFrame = false;
long currentVideoTime = System.currentTimeMillis() - startTime;
long millisecondsAhead = (long)getCurrentTimestamp() - currentVideoTime;
showAlreadyDecodedFrame = millisecondsAhead > 20;
return newFrame;
}
return false;
Expand Down Expand Up @@ -244,7 +265,6 @@ public void stop () {
}

startTime = 0;
showAlreadyDecodedFrame = false;
isFirstFrame = true;
}

Expand All @@ -255,11 +275,6 @@ public void pause () {
if (audio != null) {
audio.pause();
}
if (startTime != 0L) {
timeBeforePause = System.currentTimeMillis() - startTime;
} else {
timeBeforePause = 0L;
}
}
}

Expand All @@ -270,7 +285,6 @@ public void resume () {
if (audio != null) {
audio.play();
}
startTime = System.currentTimeMillis() - timeBeforePause;
}
}

Expand Down
Loading