purebe Posted November 11, 2015 Share Posted November 11, 2015 Is there any way to pause a video immediately after creating the element with PIXI.Texture.fromVideo or fromVideoUrl? It looks like it might be bugged currently, because under some circumstances the paused flag is set but the video doesn't actually pause. I noticed in the fromVideoUrl function it will call play() before returning, and at one point console.log'ing the baseTexture.source element showed instead of the HTML tag, an object with a pixi_id or something. I'm not sure if that is relevant, but I haven't been able to repeat that, so I'm not sure if it was just a one off (but it makes me suspicious if that object is somehow messing with my .pause() calls? Maybe during the transition .pause() calls don't work properly, so the video keeps playing? I'm not sure how that would work, but I'm not sure what's going on there either.) This is the only code that I have been able to make that works, but I imagine it's fragile due to the bug? where sometimes .paused gets set to true even though the video is still playing. If the timeout is lower than 1000 it doesn't pause the video, but the paused flag gets set so it stops it's setTimeout loop. Also, it means the video plays for ~1 second before pausing which in my case is problematic.var renderer, stage, video, sprite;$(function() { renderer = new PIXI.autoDetectRenderer(1920, 1080); $('body').append(renderer.view); stage = new PIXI.Container(); video = PIXI.Texture.fromVideoUrl('720p_test_web.mp4'); sprite = new PIXI.Sprite(video); stage.addChild(sprite); animate(); pauseVideo(video.baseTexture.source);});function animate() { requestAnimationFrame(animate); renderer.render(stage);}function pauseVideo(el) { console.log(el); if (!el.paused) { el.pause(); setTimeout(pauseVideo, 1000, el); }}I tried passing the video element directly into PIXI.Texture.fromVideo() but the video still doesn't pause and just plays from load.var renderer, stage, video, sprite;$(function() { renderer = new PIXI.autoDetectRenderer(1920, 1080); $('body').append(renderer.view); stage = new PIXI.Container(); video = PIXI.Texture.fromVideo(Util.fromVideoUrl('720p_test_web.mp4')); sprite = new PIXI.Sprite(video); stage.addChild(sprite); animate(); video.baseTexture.source.pause();});function animate() { requestAnimationFrame(animate); renderer.render(stage);}var Util = Util || {};Util.fromVideoUrl = function(src) { var video = document.createElement("video"); video.preload = "auto"; video.loop = true; video.src = src; video.pause(); return video;}Any ideas? Quote Link to comment Share on other sites More sharing options...
xerver Posted November 11, 2015 Share Posted November 11, 2015 This is likely why, the video base texture listens for 'canplay' and 'canplaythrough' and calls .play(): https://github.com/pixijs/pixi.js/blob/master/src/core/textures/VideoBaseTexture.js#L62-L63 https://github.com/pixijs/pixi.js/blob/master/src/core/textures/VideoBaseTexture.js#L132 You will also notice there is a 'loaded' event emitted there. You can listen for that event and call pause there:video = PIXI.Texture.fromVideoUrl('720p_test_web.mp4');sprite = new PIXI.Sprite(video);video.baseTexture.on('loaded', function () { pauseVideo(video.baseTexture.source);}); purebe 1 Quote Link to comment Share on other sites More sharing options...
purebe Posted November 11, 2015 Author Share Posted November 11, 2015 Brilliant, that works perfectly, much appreciated! Quote Link to comment Share on other sites More sharing options...
Rodrigo Posted December 6, 2016 Share Posted December 6, 2016 Hi, Sorry to bring this topic up again, but I'd like to know how to pause the video on the current version. I'm using the loader class to preload the video and I'm passing the resources to the callback and getting the HTML video element there, but using autoplay=false is not working and I'm getting an error when trying to use pauseVideo on the base texture. I found this: https://github.com/pixijs/pixi.js/blob/master/src/core/textures/VideoBaseTexture.js#L73-L74 But those work with the videoBaseTexture class and I'm using a regular texture fromVideo method. When I switch to use the videoBaseTexture I get an error when trying to use it on a Sprite instance: function loaderComplete(){ // now we have the video and we can use it. but first create a reference to it targetVid = videoLoader.resources.testVideo.data; // pause the video THIS IS NOT WORKING targetVid.autoplay = false; targetVid.pause(); targetVid.currentTime = 0; var videoTexture = new PIXI.VideoBaseTexture(targetVid); // pause the video as soon as it's loaded videoTexture.on("loaded", function(){ // videoTexture.baseTexture.autoplay = false; videoTexture.source.pause(); console.log( videoTexture.source ); }); // HERE I GET AN ERROR // now create the sprite var vidSprite = new PIXI.Sprite(videoTexture); vidSprite.width = 500; vidSprite.height = 500; // add the video sprite to the main container stage.addChild(vidSprite); } Here's the error I'm getting, basically because the video base texture doesn't have a baseTexture property, so that returns undefined Uncaught TypeError: Cannot read property 'hasLoaded' of undefined Sprite.js:584 Although the line seems to be this one: https://github.com/pixijs/pixi.js/blob/master/src/core/sprites/Sprite.js#L592 Thanks, Rodrigo. Quote Link to comment Share on other sites More sharing options...
themoonrat Posted December 6, 2016 Share Posted December 6, 2016 When you create a Sprite, it should always be done with a Texture, not a BaseTexture, or a VideoBaseTexture. Think of the base textures as the actual image, or actual video, and a texture as a rectangle describing what part of that actual image / video to use. Thinking that way, you get spritesheets... lots of images on 1 big image. The big image becomes the BaseTexture, each little image is a Texture, which points to where abouts on the BaseTexture to use a smaller image. Doing PIXI.Texture.fromVideo will, behind the scenes, create a BaseVideoTexture for you, and then create a Texture that uses it. Now the science bit is over, there are a couple of things you'll need to change with your code. First of all, don't wait until 'loaded' to set the autoPlay property on your VideoBaseTexture to false; set it to false as soon as you've created it Second, you need to create a Texture from that VideoBaseTexture. A simple case of var texture = new PIXI.Texture(videoTexture); And use that for your sprite Quote Link to comment Share on other sites More sharing options...
Rodrigo Posted December 8, 2016 Share Posted December 8, 2016 Thanks for the advice. Is creating the texture and the sprite correctly, but the video doesn't pause, it keeps running as soon as it's done loading. I tried the following code with no luck: // load complete callback function loaderComplete(){ // now we have the video and we can use it. but first create a reference to it targetVid = videoLoader.resources.testVideo.data; console.log( videoLoader.resources.testVideo.data ); // pause the video targetVid.autoplay = false; targetVid.pause(); targetVid.currentTime = 0; var videoBase = new PIXI.VideoBaseTexture(targetVid); videoBase.on("loaded", function(){ videoBase.source.paused = true; videoBase.source.pause(); videoBase.source.autoplay = false; console.log( "video paused => ", videoBase.source.paused ); console.log( "video autoplay => ", videoBase.source.autoplay ); }); var videoTexture = new PIXI.Texture(videoBase); // now create the sprite var vidSprite = new PIXI.Sprite(videoTexture); vidSprite.width = 500; vidSprite.height = 500; // add the video sprite to the main container stage.addChild(vidSprite); } videoLoader .add('testVideo', 'vid/head-track-small.mp4') .once('complete', function(loader, resources){loaderComplete();}) .load(); I tried to set up a codepen sample but I'm getting CORS errors. So I set up a live sample. The console logs return the expected values, ie, paused is true and autoplay is false, but the video still runs after being loaded Quote Link to comment Share on other sites More sharing options...
Rodrigo Posted December 8, 2016 Share Posted December 8, 2016 Switched to canvas render and was able to use the video. Here's the codepen link: Quote Link to comment Share on other sites More sharing options...
Rodrigo Posted December 9, 2016 Share Posted December 9, 2016 A solution is to add a timeout in the loader complete callback: function loaderComplete(){ // now we have the video and we can use it. but first create a reference to it targetVid = videoLoader.resources.testVideo.data; console.log( videoLoader.resources.testVideo.data ); setTimeout(function(){ // pause the video targetVid.pause(); targetVid.currentTime = 0; },100); var videoBase = new PIXI.VideoBaseTexture(targetVid); var videoTexture = new PIXI.Texture(videoBase); // now create the sprite var vidSprite = new PIXI.Sprite(videoTexture); vidSprite.width = 500; vidSprite.height = 500; // add the video sprite to the main container stage.addChild(vidSprite); } Then after the sprite is added and outside the loader callback, I can control the video (targetVid resides outside the loader callback scope). Hopefully someone can give some insight of what's happening here. Best, Rodrigo. Quote Link to comment Share on other sites More sharing options...
Poryg Posted September 12, 2018 Share Posted September 12, 2018 @Rodrigo A solution that is simpler and I think more elegant is to simply undefine the autoplaying: PIXI.VideoBaseTexture.prototype._onCanPlay = function () { this.hasLoaded = true; if (this.source) { this.source.removeEventListener('canplay', this._onCanPlay); this.source.removeEventListener('canplaythrough', this._onCanPlay); this.width = this.source.videoWidth; this.height = this.source.videoHeight; // prevent multiple loaded dispatches.. if (!this.__loaded) { this.__loaded = true; this.emit('loaded', this); } if (this._isSourcePlaying()) { this._onPlayStart(); } } } var sprite = PIXI.Sprite.from(your url) I tried to set it up via creating a video texture class that extends PIXI.VideoBaseTexture and it should be possible, however you have to do a little bit more shenanigans with it, for example you'd have to redefine fromUrl and fromVideo functions as well. This is simpler and if you need the video to immediately play after loading, you can set that up via spr.texture.baseTexture.on('loaded', function () {spr.texture.baseTexture.source.play()}); immediately (while pausing immediately is impossible), so it's also completely harmless. EDIT: For some reason it deletes the formatting of the text Quote Link to comment Share on other sites More sharing options...
jonforum Posted September 12, 2018 Share Posted September 12, 2018 also related here, pixi don't take the source, so just add source to autoplay. It one line edit! the problem is that pixi forces the autoplay, without take the source parameter. this dont allow to force video to stop. https://github.com/pixijs/pixi.js/pull/5112 Quote Link to comment Share on other sites More sharing options...
virtaras Posted May 25, 2022 Share Posted May 25, 2022 My way to prevent autoplay while creating video in PIXI: this.video = PIXI.Texture.from( "<path_to_video>", { resourceOptions: { autoPlay: false } } ); this.videoSprite = new PIXI.Sprite(this.video); // check pixi documentation if some extra parameters for video resourse need to be passed : https://pixijs.download/dev/docs/PIXI.VideoResource.html Quote Link to comment Share on other sites More sharing options...
bhatisur Posted January 3, 2023 Share Posted January 3, 2023 (edited) What may be happening here is that you could be stacking up multiple click handlers that are all running and fighting with each other, because the "canplaythrough" event can run more than once. SurveyZop applebees Edited January 5, 2023 by bhatisur Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.