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

Video/audio out of sync on some platforms #53

Open
anigart opened this issue Feb 16, 2018 · 5 comments
Open

Video/audio out of sync on some platforms #53

anigart opened this issue Feb 16, 2018 · 5 comments

Comments

@anigart
Copy link

anigart commented Feb 16, 2018

Hi,

When playing a video in a Windows VM running on a Mac, everything is fine and video and audio are in sync. On the same machine, not in a VM (so on native MacOS), audio is about one second ahead, breaking lipsync. This also happens on other native Windows machines I tried. The only difference is that the machines where it does not work have a lot more computing power than the VM where it works. Could it be that modern machines introduce a sync issue due to their speed?

I added some debug statements and audio.play() is called less than 10ms before the first frame renders, so it seems they start correctly at about the same moment. I suspect video is playing too slow then and audio runs ahead (audio does sound normal, not too fast).

Is this a known issue?

Thanks for any help.

@anigart
Copy link
Author

anigart commented Jan 1, 2021

Quick update on this issue: this is still a problem with the latest code and natives (although from my perception it seems the severity is reduced compared to an older version).
Audio and video are out of sync, breaking lip sync noticeably. My source video (webm format) plays nicely synced using VLC.

@SimonIT
Copy link
Member

SimonIT commented Jan 1, 2021

The natives didn't change since your first test. I made some optimizations from the java side.
Do you updated your .jar's? If not, it could be that the problem is fixed because it was from the java side

@anigart
Copy link
Author

anigart commented Jan 1, 2021

I used the latest java code. I have no way of measuring it but it seems improved, though it's still very noticeable. Thanks for resuming work on this.

@SimonIT
Copy link
Member

SimonIT commented Jan 1, 2021

Okay, I will make some tests. Maybe I will find the source of the offset

@roiniti
Copy link

roiniti commented Jun 28, 2021

I see that this problem its still unfixed, can i suggest to add some function to sync the audio, like set the audio in order to start 200 miliseconds after the video starts something like this that i aded to CommonVideoPlayerDesktop: (i made it myself and i don't if it works 100% fine)
`

private boolean audioStarted = false;
private boolean videoStarted = false;

private long async = 0;

public void setAudioAsync (long as) {
	async = as;
}

@Override
public boolean update () {
	if (decoder != null && !paused && playing) {
		if (startTime == 0) {
			// Since startTime is 0, this means that we should now display the first frame of the video, and set the
			// time.
			startTime = System.currentTimeMillis();
		}
		//Starts later on positive async and instant on negative or 0 async
		if (!audioStarted && audio != null && System.currentTimeMillis() >= startTime + async) {
			audioStarted = true;
			audio.play();
		}

		//Starts later on negative async and instant on positive or 0 async
		if (videoStarted || System.currentTimeMillis() >= startTime - async) {
			videoStarted = true;
			boolean newFrame = false;
			if (!showAlreadyDecodedFrame) {
				ByteBuffer videoData = decoder.nextVideoFrame();
				if (videoData != null) {
					if (texture == null) texture = new Texture(currentVideoWidth, currentVideoHeight, Format.RGB888);
					texture.bind();
					Gdx.gl.glTexImage2D(GL20.GL_TEXTURE_2D, 0, GL20.GL_RGB, currentVideoWidth, currentVideoHeight, 0, GL20.GL_RGB,
						GL20.GL_UNSIGNED_BYTE, videoData);
					newFrame = true;
				} else {
					playing = false;
					if (completionListener != null) {
						completionListener.onCompletionListener(currentFile);
					}
					return false;
				}
			}

			showAlreadyDecodedFrame = false;
			long currentFrameTimestamp = (long)(decoder.getCurrentFrameTimestamp() * 1000);
			long currentVideoTime = (System.currentTimeMillis() - startTime);
			int difference = (int)(currentFrameTimestamp - currentVideoTime);
			if (difference > 20) {
				// Difference is more than a frame, draw this one twice
				showAlreadyDecodedFrame = true;
			}
			return newFrame;
		}
		return false;
	}
	return false;
}`

also i added in play this:
audioStarted = false;
videoStarted = false;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants