Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 3-2-1 countdown #604

Open
wants to merge 49 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
a4a0e55
Add 3-2-1 countdown
denismosolov Aug 24, 2021
c6610d2
Add an option to remove the "Device" button and ask the for the devic…
denismosolov Aug 24, 2021
0ec7993
Update REC indicator with the recording progress
denismosolov Aug 24, 2021
58a3134
Respect linter
denismosolov Aug 24, 2021
9ebfa7a
Fix tests
denismosolov Aug 24, 2021
37ab95d
Drop everything except the countdown
denismosolov Aug 25, 2021
2180baf
Update examples
denismosolov Aug 25, 2021
144b96e
Add tests
denismosolov Aug 25, 2021
ca39c58
Add docs
denismosolov Aug 26, 2021
e921226
Disable record button while the countdown is running
denismosolov Aug 26, 2021
a6d8114
Rename the example file
denismosolov Aug 26, 2021
f134bd1
Replace countdownOverlay, countdownSteps and countdownTimeBetweenStep…
denismosolov Aug 29, 2021
e81d8c7
Add countdown to changelog
denismosolov Sep 1, 2021
71c0dda
Fix titles, spacing and comments
denismosolov Sep 2, 2021
4227e77
Validate the countdown option
denismosolov Sep 7, 2021
818e7a5
Add a check if firstChild exists
denismosolov Sep 8, 2021
51ab055
Use 4 spaces for indentation
denismosolov Sep 8, 2021
927f3e6
Add PR number
denismosolov Sep 8, 2021
dec0c94
Granular test cases
denismosolov Sep 8, 2021
ef70a8e
Move countdown to Record
denismosolov Sep 10, 2021
d29e86e
Add countdown to image only record type
denismosolov Sep 14, 2021
66d90e2
Tweak CameraButton
denismosolov Oct 8, 2021
60fc028
Abort video pre-recorder
denismosolov Oct 19, 2021
3f239b8
Update record-toggle test
denismosolov Oct 21, 2021
01ac818
Update countdown-overlay test
denismosolov Oct 21, 2021
9e26cae
Rename events
denismosolov Oct 24, 2021
f4ad22c
Restore image-only sample
denismosolov Oct 24, 2021
4bfb0ff
Change handles names
denismosolov Oct 24, 2021
2b2dc98
isPreRecording -> isCountingDown
denismosolov Oct 24, 2021
81b0c2d
_prerecording -> _countingdown
denismosolov Oct 24, 2021
87cf537
showPrerecorder() -> showCountdown()
denismosolov Oct 24, 2021
e17f4ed
abortPrerecording() -> abortCountdown()
denismosolov Oct 24, 2021
4fb848e
prerecorderTimeoutID -> countdownTimeoutID
denismosolov Oct 24, 2021
7cbad0c
Rename pre-recorder to countdown in tests
denismosolov Oct 24, 2021
00f0785
Rename pre-recorder to countdown in inline docs
denismosolov Oct 24, 2021
4e265a8
Update test specs
denismosolov Oct 24, 2021
eec7c44
Tweak tests
denismosolov Oct 24, 2021
8240283
Abort countdown on stop and tweak tests
denismosolov Oct 24, 2021
b1c4c1b
Fix record toggle
denismosolov Oct 24, 2021
d206c8f
Rename CountdownOverlay methods
denismosolov Oct 31, 2021
fd1922a
Tweak docs
denismosolov Oct 31, 2021
daba1fe
Tweak inline comment
denismosolov Oct 31, 2021
114a3f7
Merge branch 'master' into countdown
denismosolov Apr 5, 2024
a09912b
Bump version
denismosolov Apr 7, 2024
12221c2
Dead code
denismosolov Apr 7, 2024
25dcafb
Fix object destructuring
denismosolov Apr 7, 2024
dcf8549
CSS tweaks
denismosolov Apr 7, 2024
08243d7
Merge branch 'master' into countdown
denismosolov Apr 20, 2024
ab1c7f4
Do not add countdown to the default video demo
denismosolov Apr 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
92 changes: 92 additions & 0 deletions docs/demo/countdown.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Audio/Video Example - Record Plugin for Video.js</title>
thijstriemstra marked this conversation as resolved.
Show resolved Hide resolved

<link href="//unpkg.com/video.js@7.14.3/dist/video-js.min.css" rel="stylesheet">
<link href="//unpkg.com/videojs-record/dist/css/videojs.record.min.css" rel="stylesheet">
<link href="assets/examples.css" rel="stylesheet">

<script src="//unpkg.com/video.js@7.14.3/dist/video.min.js"></script>
<script src="//unpkg.com/recordrtc/RecordRTC.js"></script>
<script src="//unpkg.com/webrtc-adapter/out/adapter.js"></script>

<script src="//unpkg.com/videojs-record/dist/videojs.record.min.js"></script>

<script src="browser-workarounds.js"></script>

<style>
/* change player background color */
#myVideo {
background-color: #9ab87a;
}
</style>
</head>
<body>

<video id="myVideo" playsinline class="video-js vjs-default-skin">
<p class="vjs-no-js">
To view this video please enable JavaScript, or consider upgrading to a
web browser that
<a href="https://videojs.com/html5-video-support/" target="_blank">
supports HTML5 video.
</a>
</p>
</video>

<script>
var options = {
controls: true,
bigPlayButton: false,
width: 320,
height: 240,
plugins: {
record: {
audio: true,
video: true,
maxLength: 10,
countdownOverlay: true,
thijstriemstra marked this conversation as resolved.
Show resolved Hide resolved
countdownSteps: 5,
countdownTimeBetweenSteps: 500,
displayMilliseconds: false,
debug: true
}
}
};

// apply some workarounds for certain browsers
applyVideoWorkaround();

var player = videojs('myVideo', options, function() {
// print version information at startup
var msg = 'Using video.js ' + videojs.VERSION +
' with videojs-record ' + videojs.getPluginVersion('record') +
' and recordrtc ' + RecordRTC.version;
videojs.log(msg);
});

// error handling
player.on('deviceError', function() {
console.log('device error:', player.deviceErrorCode);
});

player.on('error', function(element, error) {
console.error(error);
});

// recording is started after 5 seconds
player.on('startRecord', function() {
console.log('started recording!');
});

// user completed recording and stream is available
player.on('finishRecord', function() {
// the blob object contains the recorded data that
// can be downloaded by the user, stored on server etc.
console.log('finished recording: ', player.recordedData);
});
</script>

</body>
</html>
1 change: 1 addition & 0 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ View the examples online:
| [Screen-only](https://collab-project.github.io/videojs-record/demo/screen-only.html) | Basic screen-only example | [example source](https://github.com/collab-project/videojs-record/blob/master/examples/screen-only.html) |
| [Audio/screen](https://collab-project.github.io/videojs-record/demo/audio-screen.html) | Basic audio/screen example | [example source](https://github.com/collab-project/videojs-record/blob/master/examples/audio-screen.html) |
| [Animated GIF](https://collab-project.github.io/videojs-record/demo/animated-gif.html) | Basic animated GIF example | [example source](https://github.com/collab-project/videojs-record/blob/master/examples/animated-gif.html) |
| [Countdown](https://collab-project.github.io/videojs-record/demo/countdown.html) | Basic audio/video example with countdown | [example source](https://github.com/collab-project/videojs-record/blob/master/examples/countdown.html) |
| [Timeslice](https://collab-project.github.io/videojs-record/demo/timeslice.html) | Get data during recording with specific time-intervals | [example source](https://github.com/collab-project/videojs-record/blob/master/examples/timeslice.html) |
| [Hotkeys](https://collab-project.github.io/videojs-record/demo/hot-keys.html) | Control this plugin using a keyboard | [example source](https://github.com/collab-project/videojs-record/blob/master/examples/hot-keys.html) |
| [Multi](https://collab-project.github.io/videojs-record/demo/multi.html) | Using multiple video.js players on a single page | [example source](https://github.com/collab-project/videojs-record/blob/master/examples/multi.html) |
Expand Down
3 changes: 3 additions & 0 deletions docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,7 @@ Additional options for this plugin are:
| `convertOptions` | array | `[]` | List of string options to pass to the convert engine. |
| `convertAuto` | boolean | `true` | By default the converter automatically starts once recording completed. Use `false` to disable this behavior, allowing you to start the converter manually instead. |
| `hotKeys` | boolean or function | `false` | Enable [keyboard hotkeys](hotkeys.md). Disabled by default. |
| `countdownOverlay` | boolean | `false` | Adds the countdown overlay after clicking on the record button. The recording starts once the countdown reaches 0. |
| `countdownSteps` | float | `3` | Amount of countdown steps (Initial value). |
| `countdownTimeBetweenSteps` | float | `1000` | Time interval in milliseconds after which it decreases the countdown value by 1. |
| `pluginLibraryOptions` | object | `{}` | Use this object to specify additional settings for the library used by the plugin. Currently only used for the ffmpeg.wasm, ffmpeg.js, opus-recorder and vmsg plugins. |
1 change: 1 addition & 0 deletions examples/audio-video.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
audio: true,
video: true,
maxLength: 10,
countdownOverlay: true,
thijstriemstra marked this conversation as resolved.
Show resolved Hide resolved
debug: true
}
}
Expand Down
84 changes: 84 additions & 0 deletions examples/countdown.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Countdown Overlay Example - Record Plugin for Video.js</title>

<link href="../node_modules/video.js/dist/video-js.min.css" rel="stylesheet">
<link href="../dist/css/videojs.record.css" rel="stylesheet">
<link href="assets/css/examples.css" rel="stylesheet">

<script src="../node_modules/video.js/dist/video.min.js"></script>
<script src="../node_modules/recordrtc/RecordRTC.js"></script>
<script src="../node_modules/webrtc-adapter/out/adapter.js"></script>

<script src="../dist/videojs.record.js"></script>

<script src="browser-workarounds.js"></script>

<style>
/* change player background color */
#myVideo {
background-color: #9ab87a;
}
</style>
</head>
<body>

<video id="myVideo" playsinline class="video-js vjs-default-skin"></video>

<script>
var options = {
controls: true,
bigPlayButton: false,
width: 320,
height: 240,
fluid: false,
plugins: {
record: {
audio: true,
video: true,
maxLength: 10,
countdownOverlay: true,
countdownSteps: 5,
countdownTimeBetweenSteps: 1000,
debug: true
}
}
};

// apply some workarounds for opera browser
applyVideoWorkaround();

var player = videojs('myVideo', options, function() {
// print version information at startup
var msg = 'Using video.js ' + videojs.VERSION +
' with videojs-record ' + videojs.getPluginVersion('record') +
' and recordrtc ' + RecordRTC.version;
videojs.log(msg);
});

// error handling
player.on('deviceError', function() {
console.log('device error:', player.deviceErrorCode);
});

player.on('error', function(element, error) {
console.error(error);
});

// recording is started after 5 seconds
player.on('startRecord', function() {
console.log('started recording!');
});

// user completed recording and stream is available
player.on('finishRecord', function() {
// the blob object contains the recorded data that
// can be downloaded by the user, stored on server etc.
console.log('finished recording: ', player.recordedData);
});
</script>

</body>
</html>
20 changes: 20 additions & 0 deletions src/css/components/countdown-overlay.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* Countdown Overlay (3-2-1 countdown when start recording)
thijstriemstra marked this conversation as resolved.
Show resolved Hide resolved
--------------------------------------------------------------------------------
*/

.vjs-record-countdown {
position: absolute;
thijstriemstra marked this conversation as resolved.
Show resolved Hide resolved
bottom: 3em;
left: 0;
right: 0;
top: 0;
pointer-events: none;

display: flex;
justify-content: center;
align-items: center;

span {
font-size: 6em;
}
}
1 change: 1 addition & 0 deletions src/css/videojs.record.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
@import "components/camera-button";
@import "components/record-indicator";
@import "components/picture-in-picture-toggle";
@import "components/countdown-overlay";
53 changes: 53 additions & 0 deletions src/js/controls/countdown-overlay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* @file countdown-overlay.js
* @since 4.5.0
thijstriemstra marked this conversation as resolved.
Show resolved Hide resolved
*/

import videojs from 'video.js';

const Component = videojs.getComponent('Component');

/**
* Overlay for displaying the countdown.
*
* @class
* @augments videojs.Component
*/
class CountdownOverlay extends Component {
/**
* Create the `Countdown`s DOM element.
*
* @return {Element}
* The dom element that gets created.
*/
createEl() {
const spanElement = videojs.dom.createEl('span');
const el = super.createEl('div', {
className: 'vjs-record-countdown',
dir: 'ltr'
});
el.appendChild(spanElement);

return el;
}

/**
* Show the `CountdownOverlay` element if it is hidden by removing the
* 'vjs-hidden' class name from it.
*/
show() {
if (this.layoutExclude && this.layoutExclude === true) {
// ignore
return;
}
super.show();
}

setCountdownValue(value) {
this.el().firstChild.innerText = value;
thijstriemstra marked this conversation as resolved.
Show resolved Hide resolved
}
}

Component.registerComponent('CountdownOverlay', CountdownOverlay);

export default CountdownOverlay;
35 changes: 34 additions & 1 deletion src/js/controls/record-toggle.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,45 @@ class RecordToggle extends Button {
handleClick(event) {
let recorder = this.player_.record();
if (!recorder.isRecording()) {
recorder.start();
if (recorder.countdownOverlay) {
// @todo move to recorder
denismosolov marked this conversation as resolved.
Show resolved Hide resolved
this.startWithCountdown(recorder);
} else {
recorder.start();
}
} else {
recorder.stop();
}
}

/**
* Display the countdown and start the recording when 0 is reached
*
* @param {Record} recorder
* Instance of the Record plugin.
*/
startWithCountdown(recorder) {
let currentValue = recorder.countdownSteps;
let interval = recorder.countdownTimeBetweenSteps;
let startOrDown = () => {
if (currentValue <= 0) {
this.player_.countdownOverlay.hide();
this.enable();
recorder.start();
} else {
this.player_.countdownOverlay.setCountdownValue(currentValue);
currentValue--;
setTimeout(startOrDown, interval);
}
};

this.disable();
this.player_.countdownOverlay.show();
this.player_.countdownOverlay.setCountdownValue(currentValue);

startOrDown();
}

/**
* Add the vjs-icon-record-stop class to the element so it can change appearance.
*
Expand Down
6 changes: 6 additions & 0 deletions src/js/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ const pluginDefaultOptions = {
convertAuto: true,
// Enable keyboard hotkeys.
hotKeys: false,
// Enable the 3-2-1 countdown before the recording
countdownOverlay: false,
// Time interval in milliseconds after which it decreases the countdown
countdownTimeBetweenSteps: 1000,
// Countdown start value
countdownSteps: 3,
// Use this object to specify additional settings for the library used by the
// plugin (only used in opus-recorder, ffmpeg.js, ffmpeg.wasm and vmsg plugins).
pluginLibraryOptions: {}
Expand Down
21 changes: 21 additions & 0 deletions src/js/videojs.record.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import RecordCanvas from './controls/record-canvas';
import DeviceButton from './controls/device-button';
import CameraButton from './controls/camera-button';
import RecordToggle from './controls/record-toggle';
import CountdownOverlay from './controls/countdown-overlay';
import RecordIndicator from './controls/record-indicator';
import PictureInPictureToggle from './controls/picture-in-picture-toggle';

Expand Down Expand Up @@ -127,6 +128,13 @@ class Record extends Plugin {
player.recordToggle = new RecordToggle(player, options);
player.recordToggle.hide();

if (this.countdownOverlay) {
// add countdown overlay
player.countdownOverlay = new CountdownOverlay(player, options);
player.addChild(player.countdownOverlay);
player.countdownOverlay.hide();
}

// picture-in-picture
let oldVideoJS = videojs.VERSION === undefined || compareVersion(videojs.VERSION, '7.6.0') === -1;
if (!('pictureInPictureEnabled' in document)) {
Expand All @@ -152,6 +160,9 @@ class Record extends Plugin {
if (player.pipToggle) {
customUIElements.push('pipToggle');
}
if (player.countdownOverlay) {
customUIElements.push('countdownOverlay');
}

customUIElements.forEach((element) => {
if (this.player.options_.controlBar[element] !== undefined) {
Expand Down Expand Up @@ -226,6 +237,11 @@ class Record extends Plugin {
// animation settings
this.animationFrameRate = recordOptions.animationFrameRate;
this.animationQuality = recordOptions.animationQuality;

// countdown settings
this.countdownOverlay = recordOptions.countdownOverlay;
this.countdownTimeBetweenSteps = recordOptions.countdownTimeBetweenSteps;
this.countdownSteps = recordOptions.countdownSteps;
}

/**
Expand Down Expand Up @@ -1466,6 +1482,11 @@ class Record extends Plugin {
this.player.controlBar.playToggle.hide();
}

if (this.player.countdownOverlay) {
// hide countdown overlay
this.player.countdownOverlay.hide();
}

// show device selection button
this.player.deviceButton.show();

Expand Down