Is there a video component that contains controls in babylonjs?

if it is, please tell me.
thanks you gus

We have a video texture - Video As A Texture | Babylon.js Documentation, but you will need to implement the controls on your own. You can use the babylon GUI (The Babylon GUI | Babylon.js Documentation) for that :slight_smile:

1 Like

thanks for your reply!
and can i get the play progress and change it ?
i don’t find some like this.

you have full access to the underlying html element, which provides you everything you need:

In this (very silly) demo, every click on the video will play/pause it and will also state where you are in the video:

tv | Babylon.js Playground (babylonjs.com)

1 Like

I have saw it, i’m so excited. thank you very very much.
And is there embed div span tag and so on in Texture?

no, you can’t use div tags when in a 3d scene. you will need to find a different solution for that.

No, there are no any HTML markup elements in 3D space.
You may use HTML over canvas or, if you want to be completely in 3D space, Babylon GUI.

Here is the very simple example with Play/Pause button.

1 Like

it’s regret. But how did it do it?

Somehow I knew we will get to that :slight_smile:
an HTML canvas is still a canvas a div element can be displayed above a canvas. How did they do that? The modified the properties of a div to be on top of a canvas. it is not a part of the 3d scene.
I can only recommend you to stick with suggested solutions if you want to use a certain framework, and not try to hack your way into a feature.
We don’t support this. we support 3d elements in a 3d-enabled canvas.

1 Like

I was just wondering, has anyone ever implemented these controls and shared it?
It feels kind of weird to have no examples at all for something like that, doesn’t it?

I agree with you

I saw the videoTexture’s source code, like this:

        // Testing video texture support
        if (this._videoTextureSupported === undefined) {
            // clear old errors just in case.
            this._gl.getError();
            this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, this._gl.RGBA, this._gl.UNSIGNED_BYTE, video);
            if (this._gl.getError() !== 0) {
                this._videoTextureSupported = false;
            }
            else {
                this._videoTextureSupported = true;
            }
        }
        // Copy video through the current working canvas if video texture is not supported
        if (!this._videoTextureSupported) {
            if (!texture._workingCanvas) {
                texture._workingCanvas = this.createCanvas(texture.width, texture.height);
                var context_1 = texture._workingCanvas.getContext("2d");
                if (!context_1) {
                    throw new Error("Unable to get 2d context");
                }
                texture._workingContext = context_1;
                texture._workingCanvas.width = texture.width;
                texture._workingCanvas.height = texture.height;
            }
            texture._workingContext.clearRect(0, 0, texture.width, texture.height);
            texture._workingContext.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, texture.width, texture.height);
            this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, this._gl.RGBA, this._gl.UNSIGNED_BYTE, texture._workingCanvas);
        }
        else {
            this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, this._gl.RGBA, this._gl.UNSIGNED_BYTE, video);
        }
        if (texture.generateMipMaps) {
            this._gl.generateMipmap(this._gl.TEXTURE_2D);
        }
        if (!wasPreviouslyBound) {
            this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
        }
        //    this.resetTextureCache();
        texture.isReady = true;

can we use it to implement div tag in 3D scene

`   try {
        // Testing video texture support
        if (this._videoTextureSupported === undefined) {
            // clear old errors just in case.
            this._gl.getError();
            this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, this._gl.RGBA, this._gl.UNSIGNED_BYTE, video);
            if (this._gl.getError() !== 0) {
                this._videoTextureSupported = false;
            }
            else {
                this._videoTextureSupported = true;
            }
        }
        const div = document.createElement('div')
        div.style.width ='100px'
        div.style.height ='100px'
        div.style.backgroundColor= 'red'
        div.innerText = 'test'
        console.log("🚀 ~ file: engine.videoTexture.js ~ line 25 ~ div", div)
        // Copy video through the current working canvas if video texture is not supported
        if (!this._videoTextureSupported) {
            if (!texture._workingCanvas) {
                texture._workingCanvas = this.createCanvas(texture.width, texture.height);
                var context_1 = texture._workingCanvas.getContext("2d");
                if (!context_1) {
                    throw new Error("Unable to get 2d context");
                }
                texture._workingContext = context_1;
                texture._workingCanvas.width = texture.width;
                texture._workingCanvas.height = texture.height;
            }

            texture._workingContext.clearRect(0, 0, texture.width, texture.height);
            texture._workingContext.drawImage(div, 0, 0, video.videoWidth, video.videoHeight, 0, 0, texture.width, texture.height);
            this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, this._gl.RGBA, this._gl.UNSIGNED_BYTE, texture._workingCanvas);
        }
        else {
            this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, this._gl.RGBA, this._gl.UNSIGNED_BYTE, div);
            console.log("🚀 ~ file: engine.videoTexture.js ~ line 41 ~ texture", texture)
        }
        if (texture.generateMipMaps) {
            this._gl.generateMipmap(this._gl.TEXTURE_2D);
        }
        if (!wasPreviouslyBound) {
            this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
        }
        //    this.resetTextureCache();
        texture.isReady = true;
    }
    catch (ex) {
        console.log("🚀 ~ file: engine.videoTexture.js ~ line 58 ~ ex", ex)
        // Something unexpected
        // Let's disable the texture
        texture._isDisabled = true;
    }`

I ues div, but error

What are you trying to do is not related to video at all.
It will not work.
To fake HTML elements in 3D space use CSS3DRenderer Youtube videos on a mesh (port of CSS3DRenderer.js) or other similar solutions.

it’s another thing, but i tried to implement like video

You know, from the reading above, I strongly believe this is at first a matter of strategy and project management.

You can choose between having a fully integrated UI with your 3D scene (with limitations) or pilot the 3D scene from a layer of HTML/css/js/… controls (also with limitations and benefits, just different…).
I believe first thing you need is to weigh out the benefits vs limitations for your project needs.

To put this simple: if UX, measuring, lead capture,… is the most important for you, I would recommend to use an external layer. On the other hand, if UI, immersion, integration with the 3D scene, reliability and MX is most important from you, then why not give it a try creating your very own controls using the BJS UI (and versatile capabilities).

Obviously, people in this forum will not allow themselves to take this decision for you. So, my recom would be to first make your choice on this. Next, come back here with your ‘must haves’ and ‘nice to have’ clearly stated… and I’m sure that altogether, we’ll be able to help you find a solution for both or either.

1 Like