Engine update seems to have affected video playback

With engine 166.3 my video playback seems to work fine and runs at the start of the game however, with engine updates 1.67.2 and 1.67.3 the same video no longer plays back. The sound seems to play fine and all my debug info seems to think there is no issue (no errors)

My code and project is long and complicated so its not easy to simply describe what’s going on. All I know is that this just stopped working today when my engine updated. When I use the older engine 1.66.3 it works fine.

Any ideas how to resolve?

1 Like

Not sure, it could be many things really.

Try to disable antialiasing if using it, see if that makes any difference.

Try and capture a frame in Spector JS to maybe see something.

Anti aliasing didn’t change anything. I did a capture with Spector.js. Ive never used it before though so I have no idea what Im looking at with the results. I went through with it and nothing particularly stands out.

I do see the following warning repeated in the latest engine version:
GL_INVALID_OPERATION: The destination level of the destination texture must be defined

This does not appear in 1.66.3

Could this be related? What does it mean and how can I resolve it?

Cheers

Not sure, our video examples all seem to work fine as far as I can see.
Are you maybe creating a movie texture with mipmaps?

I was, but I set mipmaps to false and I still get the same problem. Currently the texture is like this:

 this.videoTexture = new pc.Texture(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: false
    });

try

 const videoTexture = new pc.Texture(app.graphicsDevice, {
            format: pc.PIXELFORMAT_RGB565,
            mipmaps: false,
            minFilter: pc.FILTER_LINEAR,
            magFilter: pc.FILTER_LINEAR,
            addressU: pc.ADDRESS_CLAMP_TO_EDGE,
            addressV: pc.ADDRESS_CLAMP_TO_EDGE
        });

definitely remove FILTER_LINEAR_MIPMAP_LINEAR as that needs mipmaps

Thanks, unfortunately the video still doesn’t play and I get the long list of warnings when it tries to play:
[.WebGL-00007750046F1C00] GL_INVALID_OPERATION: The destination level of the destination texture must be defined.

1 Like

Strangely, if I add :

this.video.autoplay = true;

…at the start the video displays correctly.

But I want it to play on …

this.video.play();

…which isn’t working in this version of the editor. (but the video sounds play correctly)

Not sure what the problem could be.
Any idea @slimbuck ?

I get the same problem. I used the code from the video texture tutorial with only slight modifications and get the same error about destination.

Here is my code it is attached to the root of the scene.

var VideoTexture = pc.createScript('videoTexture');

VideoTexture.attributes.add('video', {
    title: 'Video',
    description: 'MP4 video asset to play back on this video texture.',
    type: 'asset'
});
VideoTexture.attributes.add('playEvent', {
    title: 'Play Event',
    description: 'Event that is fired as soon as the video texture is ready to play.',
    type: 'string',
    default: ''
});

// initialize code called once per entity
VideoTexture.prototype.initialize = function() {
    var app = this.app;
    
    // Create HTML Video Element to play the video
    var video = document.createElement('video');
    video.autoplay = true;
    video.crossOrigin = 'anonymous';
    //video.loop = true;

    // muted attribute is required for videos to autoplay
    //video.muted = true;

    // critical for iOS or the video won't initially play, and will go fullscreen when playing
    video.playsInline = true;

   
    //console.log(video.src);

    // iOS video texture playback requires that you add the video to the DOMParser
    // with at least 1x1 as the video's dimensions
    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.videoTexture = new pc.Texture(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: false
    });
    this.videoTexture.setSource(video);

    video.addEventListener('canplay', function (e) {
        app.fire(this.playEvent, this.videoTexture);
        console.log("can play fires");
    }.bind(this));

     // set video source
    video.src = this.video.getFileUrl();
    
    this.app.on('button:clicked:PlayButton',function (e) {
        video.play();
    }.bind(this));

    this.app.on('button:clicked:PauseButton',function (e) {
        video.pause();
        //video.currentTime = 0;
    }.bind(this));

    this.app.on('button:clicked:ReplayButton',function (e) {
        console.log(video.currentTime);
        video.currentTime = video.currentTime - 10;
        console.log(video.currentTime);
    }.bind(this));

    this.app.on('button:clicked:GoToTest',function(){
        video.pause();
    
    },this);
};



// update code called every frame
VideoTexture.prototype.update = function(dt) {
    // Transfer the latest video frame to the video texture
    this.videoTexture.upload();


    

        
};

When I changed it to autoplay = true then the video plays, otherwise when I have it wait to play with once the button is pressed I only get sound and I get the WebGL error about destination level.

Here is also the code attached to the entity that is the screen of my scene that plays the video.

var UiElement = pc.createScript('uiElement');

UiElement.attributes.add('playEvent', {
    title: 'Play Event',
    description: 'Set the TV screen material emissive map on this event.',
    type: 'string',
    default: ''
});

// initialize code called once per entity
UiElement.prototype.initialize = function() {
    this.app.on(this.playEvent, function (videoTexture) {
        console.log("plays video");
        this.entity.element.texture = videoTexture;
    }, this);

    
};

Same problems

I am having the same issue, but changing the texture to the above and using “this.video.autoplay = true;” solved here.

If someone can provide a cut-down repro project that would be very helpful. This way we can easily investigate.

@slimbuck Here is a link to a scene that includes the issue.

When you press the play video button only the audio plays

https://playcanvas.com/editor/scene/1837168

This seems to be an issue on Chrome.

With autoplay enabled the video works fine.

With autoplay disabled, Chrome errors with webgl error due to using texSubImage2D while Safari and Firefox work fine.

I’ve added a note to chromium bugs here.

1 Like

Anyone have any idea on a timeframe for Chromium fixes? Or even if they are ever likely to happen? It’s just that my boss is asking me when the videos will be fixed :slight_smile:
Cheers

I wouldn’t hold my breath there. Probably a month to investigate, another to fix. The bug doesn’t seem like a showstopper, so it will take some time.

1 Like