How can I display a video based on an action?

I saw some examples, I read and understood the code example (I think) and I don’t know why my video is not displaying.
I added a mousedown event in which it will show a window in which it’ll be display the video, but at the moment the window shows, my video is not displaying.

Video code

var VideoTest = pc.createScript('videoTest');

VideoTest.attributes.add('screenMaterial', { type: 'asset', assetType: 'material', title: 'Screen material'});
VideoTest.attributes.add('playEventScreen', { title: 'Play Event', type: 'string'});

VideoTest.attributes.add('video', { type: 'asset', title: 'Video' });
VideoTest.attributes.add('playEventVideo', { type: 'string' });

// initialize code called once per entity
VideoTest.prototype.initialize = function() 
{
    this.display = false;
    this.app.on(this.playEventScreen, function (videoTexture)
    {
        var material = this.screenMaterial.resource;
        material.emissiveMap = videoTexture;
        material.update();
    }, this);
    
    var video = document.createElement('Video');
    video.autoplay = false;
    video.crossOrigin = 'anonymous';
    video.loop = true;
    video.muted = true;
    video.src = this.video.getFileUrl();
    
    var style = video.style;
    style.width = '1px';
    style.height = '1px';
    style.position = 'absolute';
    style.opacity = '0';
    style.zIndex = '-100000';
    style.pointerEvents = 'none';
    
    document.body.appendChild(video);
    
    
    /* Create a texture to hold the video frame data */
    this.videoTest = new pc.Texture(this.app.graphicsDevice, 
    {
        format: pc.PIXELFORMAT_R8_G8_B8,
        minFilter: pc.FILTER_LINEAR_MIPMAP_LINEAR,
        magFilter: pc.FILTER_LINEAR,
        addressU: pc.ADDRESS_CLAMP_TO_EDGE,
        addressV: pc.ADDRESS_CLAMP_TO_EDGE,
        mipmaps: true,
        autoMipmap: true
    });
    this.videoTest.setSource(video);
    
    video.addEventListener('canplay', function(e)
    {
        this.app.fire(this.playEventVideo, this.videoTest);
    }.bind(this));
    this.Video = video;
};

// update code called every frame
VideoTest.prototype.update = function(dt) 
{
    if (this.display)
    {
        this.Video.autoplay = true;
        this.videoTest.upload();
    }
};

VideoTest.prototype.active = function(active)
{
    console.log(active);
    this.display = active;
};

Calling the event

this.app.root.findByName(this.actions[name]).enabled = true; //enables the window view
this.app.root.findByName('ScreenDisplay').script.videoTest.active(true); 

It is supposed that my video should be display here, but it didn’t.

The video will display in the grey screen.

image

Is it possible to share the project publicly?

https://playcanvas.com/project/703630/overview/expovr

You’ve to use WASD keys to move and also you have to interact with the first Stand. Sorry I’ll tell my boss to update the build to have the newest updates.

I stripped the whole project down to just the display and script for the video. No issues there:

If there is no issues there, do you have an idea of what could be the problem? Because I have another view with the same video and it works well but when I wanted to added in an interaction, it’s not working. Sorry for my misspelling.

It’s odd that the model for video is under a screen element (which can be causing some issues).

I’ve moved the video model out of screen element and just in the 3D world and it works fine after waiting for the video to load.

If you want the video to be played in the UI element system. Add an image element and assign the video texture (not the material) and it will work fine.

Eg: this.imageElementEntity.element.texture = this.videoTexture;

1 Like

Sorry to bother you! I was able to load the video on a screen , but now I’ve this problem, I add this script to the screen to load the texture and the video and it’'s not working but if I split this script into texture part (Screen material) and video part (video attribute) it works well but in all screens.

In the link above you can see multiple screens with the same video but there is one black screen at the beginning of the project which has this script, and all the other screens has the same script but in to partes:

full script:

var VideoTest = pc.createScript('videoTest');

VideoTest.attributes.add('screenMaterial', { type: 'asset', assetType: 'material', title: 'Screen material'});
VideoTest.attributes.add('playEventScreen', { title: 'Play Event', type: 'string'});

VideoTest.attributes.add('video', { type: 'asset', title: 'Video' });
VideoTest.attributes.add('playEventVideo', { type: 'string' });

// initialize code called once per entity
VideoTest.prototype.initialize = function() 
{
    this.display = true;
    this.app.on(this.playEventScreen, function (videoTexture)
    {
        var material = this.screenMaterial.resource;
        material.emissiveMap = videoTexture;
        material.update();
    }, this);
    
    var video = document.createElement('Video');
    video.autoplay = true;
    video.crossOrigin = 'anonymous';
    video.loop = true;
    video.muted = true;
    video.src = this.video.getFileUrl();
    
    var style = video.style;
    style.width = '1px';
    style.height = '1px';
    style.position = 'absolute';
    style.opacity = '0';
    style.zIndex = '-1000';
    style.pointerEvents = 'none';
    
    document.body.appendChild(video);
    
    
    /* Create a texture to hold the video frame data */
    this.videoTest = new pc.Texture(this.app.graphicsDevice, 
    {
        format: pc.PIXELFORMAT_R8_G8_B8,
        minFilter: pc.FILTER_LINEAR_MIPMAP_LINEAR,
        magFilter: pc.FILTER_LINEAR,
        addressU: pc.ADDRESS_CLAMP_TO_EDGE,
        addressV: pc.ADDRESS_CLAMP_TO_EDGE,
        mipmaps: true,
        autoMipmap: true
    });
    this.videoTest.setSource(video);
    
    video.addEventListener('canplay2', function(e)
    {
        this.app.fire(this.playEventVideo, this.videoTest);
    }.bind(this));
    this.Video = video;
};

// update code called every frame
VideoTest.prototype.update = function(dt) 
{
    if (this.display)
    {
        this.videoTest.upload();
    }
};

VideoTest.prototype.active = function(active, name)
{
    this.display = active;
    //this.Video.autoplay = active;
    if (name !== undefined || name !== null) 
    {
        try {
            this.Video.src = this.app.assets.find(name).getFileUrl();
        } catch (error){
            console.log("Error al encontrar el video");
        }
         
    }
};

Spitted script:
video_screen.js
videoTexture.js

//Those scripts works well in all the screens, but I want to have a different video per screen and when I added the full screen to one screen it’s not working.

I suggest creating a new project with the scripts to try to isolate and reproduce the problem with this.

It will also make it easier for others to debug as well.