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

Videos cannot be loaded without playing #74

Open
Frosty-J opened this issue Mar 24, 2022 · 2 comments
Open

Videos cannot be loaded without playing #74

Frosty-J opened this issue Mar 24, 2022 · 2 comments

Comments

@Frosty-J
Copy link
Contributor

Frosty-J commented Mar 24, 2022

In HTML5 (speaking in general here, not specifically in regards to gdx-video), videos cannot play without prior user interaction (e.g. clicking on the page) unless they are muted, even if they don't have an audio track.

As playing and loading the video is a single method in gdx-video, I cannot preload the video before interaction in order to make playback commence immediately.
(speaking from the future: this might have actually been possible if it wasn't for the resume() bug mentioned later on this page)
(again from the future: doesn't seem immediately is possible - I get blackness for a bit, so I delayed my rendering by 2/30s to make it appear at the same time as my UI)

I don't care about actually playing before interaction, but I did a quick test and concluded that setting the volume to 0 is good enough to achieve that. Whether there's a browser out there that explicitly requires the muted attribute, I'm not sure.

For my project, I added the following method to VideoPlayerGwt. I'd prefer to specify the file on creation (like new Texture("texture.png"), Gdx.audio.newMusic(Gdx.files.internal("music.mp3")) but not sure how that works with reflection and stuff.

@Override
public boolean load (FileHandle file) {
    currentFile = file;
    if (v != null) {
        v.setSrc(((GwtFileHandle)file).getAssetUrl());
        return true;
    }
    return false;
}

I also had to change v.getCurrentTime() > 0 in resume() to v.getCurrentTime() >= 0. At this point I'm not sure there's any point in the check at all, but I left it in there all the same.

Edit: I've now removed that. And also v.getCurrentTime() < v.getDuration() - this was causing playback to fail if I played the video before its duration was known.

While the time it takes to fetch a video will be shorter on other backends due to not going via the internet, I think this still has potential to benefit them, being able to give your video time to buffer before actually playing it. Though I haven't taken the time to understand the Android implementation, and the desktop implementation has bigger things to worry about than this.

@SimonIT
Copy link
Member

SimonIT commented Mar 24, 2022

There is also the load()-method. I agree with you that preloading might be a good idea. The reflection shouldn't be a problem. Will have to look if I get android and desktop seperated. We could integrate that also with the AssetManager, I think

@dasisdormax
Copy link
Contributor

dasisdormax commented Aug 24, 2023

For the resume method, the check
(v.getCurrentTime() == 0 || v.getCurrentTime() < v.getDuration())
seems to get the job done while still making sure that calling pause + resume doesn't restart an already finished video.

(Edited) For the blackness, it seems to me like we don't have an accurate way (yet?) to determine when the first video frame is available for rendering.

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

No branches or pull requests

3 participants