ccapture.js icon indicating copy to clipboard operation
ccapture.js copied to clipboard

Capture multiple videos

Open henriquemiranda opened this issue 8 years ago • 19 comments

Is it possible to start/stop the capture multiple times using CCapture.js?

Whenever I call capturer.start() I get these errors:

Uncaught Error: Width and height must be set prior to rendering Uncaught TypeError: Cannot redefine property: currentTime

Is there a fix around this?

henriquemiranda avatar Feb 15 '16 07:02 henriquemiranda

There isn't a way to do that right now, you'd have to re-create the capturer. I can look into adding a .reset() method so it cleans up and lets another capture session ready.

spite avatar Feb 17 '16 22:02 spite

Yes that would be great!

henriquemiranda avatar Feb 17 '16 22:02 henriquemiranda

Well, an ugly fix for this would be to use a try catch around:

Object.defineProperty( HTMLVideoElement.prototype, 'currentTime', { get: hookCurrentTime } ) Object.defineProperty( HTMLAudioElement.prototype, 'currentTime', { get: hookCurrentTime } )

Its definitely not the best solution but it seems to work...

henriquemiranda avatar Mar 10 '16 23:03 henriquemiranda

It does work, yes. What I've been toying with is only hooking what's needed, so if you're not using HTMLVideoElement or HTMLAudioElement, it won't be a problem resetting the capturer; and if you're using them ... well, you can't go back without reloading. it looks like it works so far.

spite avatar Mar 11 '16 00:03 spite

How to reset capturer?

tonycaso avatar May 18 '16 11:05 tonycaso

+1 How to reset capturer? I tryed capturer = null, but it not work

TiagoSilvaPereira avatar Jun 17 '16 23:06 TiagoSilvaPereira

Yes, adding a try catch works well for me:

try{ Object.defineProperty( HTMLVideoElement.prototype, 'currentTime', { get: hookCurrentTime } ) Object.defineProperty( HTMLAudioElement.prototype, 'currentTime', { get: hookCurrentTime } ) }catch(e){ console.log(e); }

TiagoSilvaPereira avatar Jun 17 '16 23:06 TiagoSilvaPereira

@TiagoSilvaPereira more exactly? how to use try catch to reset the capturer

aleen42 avatar Sep 21 '16 10:09 aleen42

Oh, @TiagoSilvaPereira I see your way, and just work for me, too. Thx.

aleen42 avatar Sep 21 '16 10:09 aleen42

Hey guys @TiagoSilvaPereira, @aleen42, @spite having a bit of a problem reseting the capturer for a gif capture-download from canvas element. The first time works fine but the second time I call start() I get the "Cannot redefine property: currentTime" error. Tried:

  • Creating a new capturer every time and calling start()
  • Creating a new capturer every time and doing the hook suggested above
  • Keeping the same capturer and calling start()
  • Keeping the same capturer and doing the hook suggested above

Can any of you please explain how to reset the capturer for successive downloads in the same session? Thanks

axaq avatar Dec 06 '16 16:12 axaq

I think the hook solution above is creating a problem for gif captures no matter if you define a new capturer or not. I removed the mentioned hook from the source code and now it works fine.

axaq avatar Dec 06 '16 17:12 axaq

@axaq if you don't need to sync to a video or audio element, you can comment out this whole block: https://github.com/spite/ccapture.js/blob/master/src/CCapture.js#L719

spite avatar Dec 06 '16 18:12 spite

@axaq, I have an application that uses CCapturer to make successive downloads of generated videos and GIFs. The solution I encountered is use the hook above, using the same instance of capturer. The application is: http://app.rapidmockup.net

If you want, I can show my version of the code, but the unique update I remember that I made in the code is the try-catch cited above (and that as I see, is now natively added in the CCapturer.js).

TiagoSilvaPereira avatar Dec 07 '16 11:12 TiagoSilvaPereira

@axaq, firstly, go to the library and find the following snippet in the file CCapture.js:

function _init() {
	_log('Capturer start');

	_startTime = window.Date.now();
	_time = _startTime + _settings.startTime;
	_performanceStartTime = window.performance.now();
	_performanceTime = _performanceStartTime + _settings.startTime;

	window.Date.prototype.getTime = function() {
		return _time;
	};
	window.Date.now = function() {
		return _time;
	};

	window.setTimeout = function(callback, time) {
		var t = {
			callback: callback,
			time: time,
			triggerTime: _time + time
		};
		_timeouts.push(t);
		_log('Timeout set to ' + t.time);
		return t;
	};

	window.clearTimeout = function(id) {
		for (var j = 0; j < _timeouts.length; j++) {
			if (_timeouts[j] == id) {
				_timeouts.splice(j, 1);
				_log('Timeout cleared');
				continue;
			}
		}
	};

	window.setInterval = function(callback, time) {
		var t = {
			callback: callback,
			time: time,
			triggerTime: _time + time
		};
		_intervals.push(t);
		_log('Interval set to ' + t.time);
		return t;
	};

	window.clearInterval = function(id) {
		_log('clear Interval');
		return null;
	};

	window.requestAnimationFrame = function(callback) {
		_requestAnimationFrameCallbacks.push(callback);
	};

	window.performance.now = function() {
		return _performanceTime;
	};

	function hookCurrentTime() {
		if (!this._hooked) {
			this._hooked = true;
			this._hookedTime = this.currentTime || 0;
			this.pause();
			media.push(this);
		}
		return this._hookedTime + _settings.startTime;
	};
}

And then, add additional code in the end of the _init function:

try {
	Object.defineProperty(HTMLVideoElement.prototype, 'currentTime', { get: hookCurrentTime })
	Object.defineProperty(HTMLAudioElement.prototype, 'currentTime', { get: hookCurrentTime })
} catch (err) {
	_log(err);
}

Then, it should work when you init the object.

aleen42 avatar Dec 07 '16 12:12 aleen42

Hey @aleen42 and @TiagoSilvaPereira. Thanks for the responses guys. Actually that hook works great for the video captures but if you do gif capture it encounters the "Cannot redefine property: currentTime" error for the second successive capture (or more specifically when you call start() method for the second time). The solution is to remove that hook if you are not using video or audio element as @spite also mentioned. May be a condition can be added to the base to control this. Again, thanks for all the quick responses.

axaq avatar Dec 07 '16 12:12 axaq

I did add the hook code to the _init of the ccapture.js code.

I'm getting this error:

InvalidStateError: Failed to execute 'stop' on 'MediaRecorder': The MediaRecorder's state is 'inactive'. Error: Failed to execute 'stop' on 'MediaRecorder': The MediaRecorder's state is 'inactive'. at CCStreamEncoder.save (http://localhost:88/Scripts/capturer/CCapture.js:419:28) at Object._save [as save] (http://localhost:88/Scripts/capturer/CCapture.js:907:22) .... ..... What is the reason here?

  1. I'm initializing the capturer once during the session in the browser
  2. I do start the capturer once after I want to start it
  3. during the captures I want to save some captures during the process in my app as a movie video file
  4. this is only possible once.....

Do I have to init the capturer every movie again?

Geoneer avatar Aug 01 '17 13:08 Geoneer

Probably need a setter also for currentTime because when I try to set currentTime after I have initialized capturer I get the following error:

Cannot set property currentTime of #<HTMLVideoElement> which has only a getter

I think this might work to define a set function also, but what would be the right value?

Object.defineProperty( HTMLVideoElement.prototype, 'currentTime', {
    get: hookCurrentTime,
    set: function(value) { /* Need code here */}
} )

Thanks in advance!

jaankoppe avatar Sep 21 '19 14:09 jaankoppe

Is there a solution now? Still getting the error. I'm using CCapture together with p5.js. Recording once works fine.

drmarzipan avatar May 13 '20 22:05 drmarzipan

I'm downloading a tar of png . I've tried commenting out the entire block as @spite & @axaq mentioned. While the undefined currentTime error is gone but nothing is rendered until refresh. I see Timeout set to 250 after calling .start() again on the capturer and nothing happens.

Do we have a solution for this yet?

varyP avatar Feb 07 '22 16:02 varyP