ccapture.js
ccapture.js copied to clipboard
Capture multiple videos
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?
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.
Yes that would be great!
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...
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.
How to reset capturer?
+1 How to reset capturer? I tryed capturer = null, but it not work
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 more exactly? how to use try catch to reset the capturer
Oh, @TiagoSilvaPereira I see your way, and just work for me, too. Thx.
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
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 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
@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).
@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.
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.
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?
- I'm initializing the capturer once during the session in the browser
- I do start the capturer once after I want to start it
- during the captures I want to save some captures during the process in my app as a movie video file
- this is only possible once.....
Do I have to init the capturer every movie again?
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!
Is there a solution now? Still getting the error. I'm using CCapture together with p5.js. Recording once works fine.
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?