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

Add a "loop" property to the VideoPlayer node #264

Closed
golddotasksquestions opened this issue Nov 28, 2019 · 18 comments
Closed

Add a "loop" property to the VideoPlayer node #264

golddotasksquestions opened this issue Nov 28, 2019 · 18 comments

Comments

@golddotasksquestions
Copy link

golddotasksquestions commented Nov 28, 2019

Describe the project you are working on:
Project with Level selection, character selection, viewports that are supposed to show looping video.

Describe the problem or limitation you are having in your project:
I would like to play short looping video in my projects at numerous places (think level selection, character selection, character ingame portraits like in Starcraft2), and love how amazingly good the VideoPlayer Node is for playing video, however it does not have a loop bool which is a shame.
So for every single VideoPlayer Node I have to connect the finished signal to a script to play the short video again. It's more than annoying to say the least.

Describe how this feature / enhancement will help you overcome this problem or limitation:
With a loop property I would not have to create and connect a management node/and script for VideoPlayer nodes that does nothing but start the video once it's finished.

Show a mock up screenshots/video or a flow diagram explaining how your proposal will work:
A "loop video"checkbox in the Inspector.

Describe implementation detail for your proposal (in code), if possible:
I can't write C++ code.

If this enhancement will not be used often, can it be worked around with a few lines of script?:
It would be used by anyone who wants to loop video. Since most of us are making games, the VideoPlayer node is actually often used to play short files that need looping, not necessarily movie-length files that don't need looping as much.

Is there a reason why this should be core and not an add-on in the asset library?:
It's a tiny small but very meaningful improvement to an already existing great Node in Godot.

@KoBeWi
Copy link
Member

KoBeWi commented Nov 28, 2019

Both play and finished don't take any arguments, so you can connect them directly without a script.

@Calinou
Copy link
Member

Calinou commented Nov 29, 2019

Related to godotengine/godot#6179.

@golddotasksquestions
Copy link
Author

golddotasksquestions commented Nov 29, 2019

@KoBeWi

Both play and finished don't take any arguments, so you can connect them directly without a script.

I don't follow. Would you mind trying to explain it again? How would I "connect them directly" (whatever that means) to make the video loop?

@KoBeWi
Copy link
Member

KoBeWi commented Nov 29, 2019

IQyQ4mgy35
Basically, you don't even need to attach script.

@golddotasksquestions
Copy link
Author

golddotasksquestions commented Nov 29, 2019

That's a pretty amazing trick @KoBeWi ! Thank you so much for sharing!
While genius simple, it's not exactly self explanatory, or beginner friendly. So even from a purely UX perspective, I would still think there is a need for a "loop video" checkbox.

@erodozer
Copy link

I would prefer to see a consistent way to handle media resources within Godot, and have nodes that operate in a similar manner. Right now VideoPlayer and AudioStreamPlayer are a lot alike, if looping were to be added to VideoPlayer it would make sense to do the same for AudioStreamPlayer.

AudioStream ogg resources have the loop property set on them on import. It would make sense in the current implementation to do the same for video resources. However, it would make more sense to me to manage looping in both AudioStreamPlayer and VideoPlayer so then it's not a responsibility of the resource importer. Having the property on the player instead of the resource would also allow the use of the same resource where in some situations you can have it loop and in others play once.

@girng
Copy link

girng commented Nov 30, 2019

I think I reported this issue years ago lol time flies
edit: Last time I did something similar to Kobe's suggestion, there would be a small hiccup of xxMS when it starts to loop. Could be different nowadays, though

@Calinou
Copy link
Member

Calinou commented Dec 7, 2022

edit: Last time I did something similar to Kobe's suggestion, there would be a small hiccup of xxMS when it starts to loop. Could be different nowadays, though

This can be worked around by taking a screenshot of the first frame, saving it as an image in the project and placing it in a TextureRect drawn behind the VideoPlayer. It will appear while the VideoPlayer has nothing to show.

@sebastianrueckerai
Copy link

This can be worked around by taking a screenshot of the first frame, saving it as an image in the project and placing it in a TextureRect drawn behind the VideoPlayer. It will appear while the VideoPlayer has nothing to show.

This quickly gets clunky when playing different videos and switching between them. It also introduces stutter, especially for short videos.

A building loop would help a lot!

@charles-brun
Copy link

charles-brun commented Mar 28, 2023

It appears that the VideoPlayer doesn't stop reading the current video while it is loading the next one. If the loading starts after the end of the video, you get empty frames.

Following this logic I managed to get seemless looping by restarting the video just before it ends, at the cost of cropping it by a tiny bit.

Problem is I couldn't figure out how to get the video length from inbuilt functions, so had to store it manually in a variable.

Then a timer is started with the video each time.

func _play_video():
	video_player.play()
	play_timer.start(video_length - 0.1)


func _on_PlayTimer_timeout():
	_play_video()

@JonnyTech
Copy link

Problem is I couldn't figure out how to get the video length from inbuilt functions, so had to store it manually in a variable.

Did anyone figure out how to get the duration of the video? Using Godot 4 I am loading external videos to loop so do not know the length in advance.

@YuriSizov
Copy link
Contributor

All 3 PRs addressing this issue have been now merged.

@JonnyTech
Copy link

All 3 PRs addressing this issue have been now merged.

Woohoo! I guess that this is too late for the recently release v4.1 and will be available in v4.2?

@YuriSizov
Copy link
Contributor

That's right!

@Calinou Calinou added this to the 4.2 milestone Jul 12, 2023
@JonnyTech
Copy link

Looks like video looping made it into v4.1.1...

@sebastianrueckerai
Copy link

Connecting the "stop" signal to the "play button" was a hassle and it is nice this update made that easier, but I fear it might not solve the issue a lot of people are having, which is skipped frames / stutter when implementing looping ourselves.

As stated here:

The effect is identical as connecting the signal, the change is only for making the UI more intuitive.

So I fear there will still be at least one frame skipped in the video. This is why me and others had to paste a still image of the first frame of a video behind the video player to make the empty frame from looping less noticeable. If looping was not implemented in the underlying c++ video player I fear that the issue will persist.

@paddy-exe
Copy link

So I fear there will still be at least one frame skipped in the video. This is why me and others had to paste a still image of the first frame of a video behind the video player to make the empty frame from looping less noticeable. If looping was not implemented in the underlying c++ video player I fear that the issue will persist.

The bug was solved separately in this PR: godotengine/godot#77856

It is linked here as well.

@sebastianrueckerai
Copy link

AWESOME! I missed that - thanks!

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

10 participants