Jump to content

How can I update video canvas after setting `videoEl.currentTime`?


trsh
 Share

Recommended Posts

I do something like this to loop trough video frame by frame:

frameEl.onchange = function(e){
                const frame = parseInt(e.target.value);
                videoEl.currentTime = e.target.value/fps;
            };

But the PIXI canvas is not updating. It updated only on `play`. Are there options?

Link to comment
Share on other sites

according to https://github.com/pixijs/pixi.js/blob/dev/packages/core/src/textures/resources/VideoResource.ts#L154  , every frame several operations are performed

1. video texture update

2. super update (BaseImageResource)

3. super-super (Resource)

and without 3. it wont work because it wont raise dirty update id that TextureSystem  will read later

I think regular "texture.update()" should work the same way for you. Whatever you do - 

1. debug whether baseTexture update id will raise

2. make sure your app structure is fine. https://github.com/pixijs/pixi.js/wiki/v5-Custom-Application-GameLoop

 

Link to comment
Share on other sites

7 minutes ago, ivan.popelyshev said:

according to https://github.com/pixijs/pixi.js/blob/dev/packages/core/src/textures/resources/VideoResource.ts#L154  , every frame several operations are performed

1. video texture update

2. super update (BaseImageResource)

3. super-super (Resource)

and without 3. it wont work because it wont raise dirty update id that TextureSystem  will read later

I think regular "texture.update()" should work the same way for you. Whatever you do - 

1. debug whether baseTexture update id will raise

2. make sure your app structure is fine. https://github.com/pixijs/pixi.js/wiki/v5-Custom-Application-GameLoop

 

My setup is like

const videoResource = new PIXI.resources.VideoResource(videoEl, {
                autoPlay: false,
                autoLoad: true,
                crossorigin: true
            });

            const baseTexture = new PIXI.BaseTexture(videoResource, { mipmap: false });
            const mediaTexture = new PIXI.Texture(baseTexture);
            const mediaSprite = new PIXI.Sprite(mediaTexture);

            
            app.stage.addChild(mediaSprite);

What then I try todo is :

frameEl.onchange = function(e){
                const frame = parseInt(e.target.value);
                videoEl.currentTime = e.target.value/fps;
                mediaTexture.update();
            };

But it doesn't work :( . I got lot's of black screens.

Link to comment
Share on other sites

2 hours ago, ivan.popelyshev said:

Strange, it should work. Wanna make a demo?

Alternatively can paste the below code in "https://pixijs.io/examples/#/sprite/video.js" and crank the numbers up in input. Only some frames will appear

const app = new PIXI.Application();
document.body.appendChild(app.view);

const fs = document.createElement('input');
fs.type = 'number';
fs.style.position = 'absolute';
fs.style.top = '0px';
fs.style.left = '0px';

document.body.appendChild(fs);

const videoEl = document.createElement('video');
videoEl.preload = "auto";
videoEl.controls = true;

videoEl.addEventListener("canplaythrough", function() {
  process();
}, {once : true});

videoEl.src = 'examples/assets/video.mp4';

function process(){  
   const videoResource = new PIXI.resources.VideoResource(videoEl, {
     autoPlay: false,
     autoLoad: true,
     crossorigin: true
   });

  const baseTexture = new PIXI.BaseTexture(videoResource, { mipmap: false });
  const mediaTexture = new PIXI.Texture(baseTexture);
  const mediaSprite = new PIXI.Sprite(mediaTexture);
 
  app.stage.addChild(mediaSprite);
 
  fs.onchange = function(e){
    videoEl.currentTime = e.target.value;
    console.log(videoEl.currentTime);
    mediaTexture.update();
  }
}

 

Link to comment
Share on other sites

8 hours ago, ivan.popelyshev said:

No idea so far, looks like some kind of async stuff, bideo cant just update frame fast.

Also, I'm on vacation from pixies, and I want to see how fast other people can answer :)

Pity. Not much other help here :(

Link to comment
Share on other sites

Hey trsh, I took a peek.  Verified that the dirty counter is updating properly, tried messing around with starting and stopping the underlying video to see if that would help.  No dice.

The problem seems to be some kind of race condition, where seeking the underlying video results in the data copy failing if performed too quickly.

Change your sample's change handler to:

  fs.onchange = function(e){
    videoEl.fastSeek(e.target.value);
    setTimeout(function() { baseTexture.update(); }, 100);
  }

And it will work as expected.  I'm not sure what the solution would be should you be wanting real-time response times, but at least this should help narrow down the problem.

Link to comment
Share on other sites

13 minutes ago, themoonrat said:

I find that a video needs to be played for seeking to work in updating the video being watched. So try seeking, then a play, then a pause again.

Doing pause right after play results in an error. Or how do u mean it?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...