godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

Implement streaming from an URL in VideoPlayer #924

Open shawkes opened 4 years ago

shawkes commented 4 years ago

Previously an issue and was scheduled for a milestone: https://github.com/godotengine/godot/issues/26127

Describe the project you are working on: Group game play with live streaming of host.

Describe the problem or limitation you are having in your project: Videoplayer can only play local files. It cannot directly play videos from a url.

Describe the feature / enhancement and how it helps to overcome the problem or limitation: By being able to connect to a video stream (rather than play a file) I can stream a video.

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:

videoPlayer.set_stream(https://example.com/livevid.mpd)

videoPlayer.play()

If this enhancement will not be used often, can it be worked around with a few lines of script?: There is no workaround for streaming video from a url.

Is there a reason why this should be core and not an add-on in the asset library?: To quote @hpvb

This should be added to the VideoPlayer class, after that GDNative will also get it. I suggest this gets implemented using Godot's internal HTTP client to ensure that we use the same certificates etc for https streams.

@hbina showed interest on working on the feature.

fire commented 4 years ago

It may be possible to use one of the ffmpeg modes to stream video.

https://github.com/kidrigger/godot-videodecoder

shawkes commented 4 years ago

@fire that allows playing videos formats other than webm, but it still uses video.stream which is a class that extends resource, which is local files only. There is nothing in there allowing https streams.

RichardMcAdam commented 4 years ago

This capability would be very useful. It would provide a simple mechanism for providing up to date content within a game.

Calinou commented 4 years ago

@RichardMcAdam Please don't bump issues without contributing significant new information. Use the :+1: reaction button on the first post instead.

fire commented 4 years ago

In ffmpeg there's a filename parameter.

avformat_open_input(&data->format_ctx, "", NULL, NULL)

The api has a "" which can be a url. I'm not sure how to extend the videodecoder_api->godot_videodecoder_file_read api. Maybe name it godot_videodecoder_filename_read?

ajlennon commented 3 years ago

+1 for this. Would really like to be able to export to WebXR and have videos playing. I can do this now from local file but web streamed sources would be fantastic

yunylz commented 3 years ago

This feature is a MUST for rhythm/dance games.

Calinou commented 3 years ago

@heyimyunyl Please don't bump issues without contributing significant new information. Use the :+1: reaction button on the first post instead.

stromperton commented 3 years ago

Is it possible to realize this feature with any waypath? Any crutch, any binding, any plugin. Somebody know? I don`t believe, that nobody tried to make it. I can't waiting official update for years. Sadness, there is no being even WebView, that can help with playback (_the only one realization "not include media playback"_). I just need real time streaming from website with youtube iframe like descripted in this message. WebView might be a beauty answer (like a widgets in OBS, u know). A wrong thread digging, maybe? Somebody can link me to right solve, pleaaase? 😞

ChildLearningClub commented 9 months ago

I'm not sure if this has changed in Godot 4 but a very rough work around for Godot 3 and html5 exports is to utilize the JavaScript Class. Within the html5 export section in the "Head Include" you can add in the appropriate html/css to the url of your video.

Example:

<body>
<div class="videos">
    <div>
        <video class="video" id='GameVideo' onended="videoEnded()" controls preload="none" width="100%"
        poster="https://my-nextcloud/s/e9kbJizPE7CGJSC/preview">
        <source src="https://my-nextcloud/s/JJsBXJp6aYeXzRP/download"
            type="video/mp4">
        </video>
    </div>
 </body>

If hosting your videos from your Nextcloud, like I do, using the /preview /download for images/videos respectively will pull the content directly.

Within Gdscript something like:

var gamevideo_end_callback = JavaScript.create_callback(self, "gamevideo_end")

func _ready():
    var window = JavaScript.get_interface("window")
    window.document.getElementById('GameVideo').addEventListener("ended", gamevideo_end_callback)

func gamevideo_end(args):
    JavaScript.eval("hideAllVideos()")

Which looking at now looks like can just be shortened to something similar to:

func _ready():
    var window = JavaScript.get_interface("window")
    window.document.getElementById('GameVideo').addEventListener("ended", gamevideo_end)

func gamevideo_end(args):
    JavaScript.eval("hideAllVideos()")

Effectively I just start with the video/videos hidden and show them when I want so additionally within the html5 export section in the "Head Include"

 <!-- hide all video at the start -->
<style type='text/css'>
        video {
            visibility: hidden;
            z-index: 0;
        }
    </style>
<!-- REFERENCE: https://linuxhint.com/hide-elements-using-classname-javascript/ -->
<script>
    function hideAllVideos() {
        const allvideos = document.getElementsByClassName('video');
        for (const video of allvideos) {
            video.style.visibility = 'hidden';
        }
    };
</script>

And when you want to show your video in gdscript:

func show_game_video():
    JavaScript.eval("showGameVideo()")

Which would be connected to:

<script>
    function showGameVideo() {
        hideAllVideos()
        document.getElementById('GameVideo').style.visibility = 'visible';
    }
</script>

in your "Head Include". Just make sure you using the same id tags when referencing your video ex: id='GameVideo'.

I know this doesn't fix anything within Godot itself. but for anyone that really wants to stream content and doesn't know how to implement the changes in the engine code to achieve it, like myself, I hope this can help.