@uppy/screen-capture
Advanced tools
Comparing version 3.1.1 to 3.1.2
import { h } from 'preact'; | ||
/** | ||
* Control screen capture recording. Will show record or stop button. | ||
*/ | ||
export default function RecordButton(_ref) { | ||
@@ -13,3 +13,2 @@ let { | ||
} = _ref; | ||
if (recording) { | ||
@@ -37,3 +36,2 @@ return h("button", { | ||
} | ||
return h("button", { | ||
@@ -40,0 +38,0 @@ className: "uppy-u-reset uppy-c-btn uppy-ScreenCapture-button uppy-ScreenCapture-button--video", |
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } | ||
/* eslint-disable react/jsx-props-no-spreading */ | ||
@@ -9,3 +8,2 @@ import { h, Component } from 'preact'; | ||
import StreamStatus from "./StreamStatus.js"; | ||
class RecorderScreen extends Component { | ||
@@ -18,3 +16,2 @@ componentWillUnmount() { | ||
} | ||
render() { | ||
@@ -28,4 +25,5 @@ const { | ||
playsinline: true | ||
}; // show stream | ||
}; | ||
// show stream | ||
if (recording || !recordedVideo && !recording) { | ||
@@ -35,10 +33,11 @@ videoProps.muted = true; | ||
videoProps.srcObject = videoStream; | ||
} // show preview | ||
} | ||
// show preview | ||
if (recordedVideo && !recording) { | ||
videoProps.muted = false; | ||
videoProps.controls = true; | ||
videoProps.src = recordedVideo; // reset srcObject in dom. If not resetted, stream sticks in element | ||
videoProps.src = recordedVideo; | ||
// reset srcObject in dom. If not resetted, stream sticks in element | ||
if (this.videoElement) { | ||
@@ -48,3 +47,2 @@ this.videoElement.srcObject = undefined; | ||
} | ||
return h("div", { | ||
@@ -63,5 +61,3 @@ className: "uppy uppy-ScreenCapture-container" | ||
} | ||
} | ||
export default RecorderScreen; |
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } | ||
import { h } from 'preact'; | ||
@@ -9,27 +8,26 @@ import { UIPlugin } from '@uppy/core'; | ||
const packageJson = { | ||
"version": "3.1.1" | ||
"version": "3.1.2" | ||
}; | ||
import locale from './locale.js'; // Check if screen capturing is supported. | ||
import locale from './locale.js'; | ||
// Check if screen capturing is supported. | ||
// mediaDevices is supprted on mobile Safari, getDisplayMedia is not | ||
function isScreenRecordingSupported() { | ||
var _navigator$mediaDevic; | ||
return window.MediaRecorder && ((_navigator$mediaDevic = navigator.mediaDevices) == null ? void 0 : _navigator$mediaDevic.getDisplayMedia); // eslint-disable-line compat/compat | ||
} // Adapted from: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia | ||
} | ||
// Adapted from: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia | ||
function getMediaDevices() { | ||
return window.MediaRecorder && navigator.mediaDevices; // eslint-disable-line compat/compat | ||
} | ||
/** | ||
* Screen capture | ||
*/ | ||
export default class ScreenCapture extends UIPlugin { | ||
constructor(uppy, opts) { | ||
super(uppy, opts); | ||
this.mediaDevices = getMediaDevices(); // eslint-disable-next-line no-restricted-globals | ||
this.mediaDevices = getMediaDevices(); | ||
// eslint-disable-next-line no-restricted-globals | ||
this.protocol = location.protocol === 'https:' ? 'https' : 'http'; | ||
@@ -40,5 +38,6 @@ this.id = this.opts.id || 'ScreenCapture'; | ||
this.icon = ScreenRecIcon; | ||
this.defaultLocale = locale; // set default options | ||
this.defaultLocale = locale; | ||
// set default options | ||
// https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamConstraints | ||
const defaultOptions = { | ||
@@ -63,14 +62,19 @@ // https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints#Properties_of_shared_screen_tracks | ||
preferredVideoMimeType: 'video/webm' | ||
}; // merge default options with the ones set by user | ||
}; | ||
this.opts = { ...defaultOptions, | ||
// merge default options with the ones set by user | ||
this.opts = { | ||
...defaultOptions, | ||
...opts | ||
}; // i18n | ||
}; | ||
this.i18nInit(); // uppy plugin class related | ||
// i18n | ||
this.i18nInit(); | ||
// uppy plugin class related | ||
this.install = this.install.bind(this); | ||
this.setPluginState = this.setPluginState.bind(this); | ||
this.render = this.render.bind(this); // screen capturer related | ||
this.render = this.render.bind(this); | ||
// screen capturer related | ||
this.start = this.start.bind(this); | ||
@@ -81,8 +85,8 @@ this.stop = this.stop.bind(this); | ||
this.submit = this.submit.bind(this); | ||
this.streamInterrupted = this.streamInactivated.bind(this); // initialize | ||
this.streamInterrupted = this.streamInactivated.bind(this); | ||
// initialize | ||
this.captureActive = false; | ||
this.capturedMediaFile = null; | ||
} | ||
install() { | ||
@@ -93,3 +97,2 @@ if (!isScreenRecordingSupported()) { | ||
} | ||
this.setPluginState({ | ||
@@ -102,10 +105,7 @@ streamActive: false, | ||
} = this.opts; | ||
if (target) { | ||
this.mount(target, this); | ||
} | ||
return undefined; | ||
} | ||
uninstall() { | ||
@@ -115,6 +115,4 @@ if (this.videoStream) { | ||
} | ||
this.unmount(); | ||
} | ||
start() { | ||
@@ -124,3 +122,2 @@ if (!this.mediaDevices) { | ||
} | ||
this.captureActive = true; | ||
@@ -140,3 +137,2 @@ this.selectAudioStreamSource(); | ||
} | ||
selectVideoStreamSource() { | ||
@@ -146,9 +142,10 @@ // if active stream available, return it | ||
return new Promise(resolve => resolve(this.videoStream)); | ||
} // ask user to select source to record and get mediastream from that | ||
} | ||
// ask user to select source to record and get mediastream from that | ||
// eslint-disable-next-line compat/compat | ||
return this.mediaDevices.getDisplayMedia(this.opts.displayMediaConstraints).then(videoStream => { | ||
this.videoStream = videoStream; // add event listener to stop recording if stream is interrupted | ||
this.videoStream = videoStream; | ||
// add event listener to stop recording if stream is interrupted | ||
this.videoStream.addEventListener('inactive', () => { | ||
@@ -172,3 +169,2 @@ this.streamInactivated(); | ||
} | ||
selectAudioStreamSource() { | ||
@@ -178,6 +174,6 @@ // if active stream available, return it | ||
return new Promise(resolve => resolve(this.audioStream)); | ||
} // ask user to select source to record and get mediastream from that | ||
} | ||
// ask user to select source to record and get mediastream from that | ||
// eslint-disable-next-line compat/compat | ||
return this.mediaDevices.getUserMedia(this.opts.userMediaConstraints).then(audioStream => { | ||
@@ -194,7 +190,5 @@ this.audioStream = audioStream; | ||
} | ||
return false; | ||
}); | ||
} | ||
startRecording() { | ||
@@ -212,24 +206,29 @@ const options = {}; | ||
options.mimeType = preferredVideoMimeType; | ||
} // prepare tracks | ||
} | ||
// prepare tracks | ||
const tracks = [videoStream.getVideoTracks()[0]]; | ||
const tracks = [videoStream.getVideoTracks()[0]]; // merge audio if exits | ||
// merge audio if exits | ||
if (this.audioStream) { | ||
tracks.push(this.audioStream.getAudioTracks()[0]); | ||
} // create new stream from video and audio | ||
} | ||
// create new stream from video and audio | ||
// eslint-disable-next-line compat/compat | ||
this.outputStream = new MediaStream(tracks); | ||
this.outputStream = new MediaStream(tracks); // initialize mediarecorder | ||
// initialize mediarecorder | ||
// eslint-disable-next-line compat/compat | ||
this.recorder = new MediaRecorder(this.outputStream, options); | ||
this.recorder = new MediaRecorder(this.outputStream, options); // push data to buffer when data available | ||
// push data to buffer when data available | ||
this.recorder.addEventListener('dataavailable', event => { | ||
this.recordingChunks.push(event.data); | ||
}); // start recording | ||
}); | ||
this.recorder.start(); // set plugin state to recording | ||
// start recording | ||
this.recorder.start(); | ||
// set plugin state to recording | ||
this.setPluginState({ | ||
@@ -242,3 +241,2 @@ recording: true | ||
} | ||
streamInactivated() { | ||
@@ -249,5 +247,5 @@ // get screen recorder state | ||
recording | ||
} = { ...this.getPluginState() | ||
} = { | ||
...this.getPluginState() | ||
}; | ||
if (!recordedVideo && !recording) { | ||
@@ -264,3 +262,2 @@ // Close the Dashboard panel if plugin is installed | ||
} | ||
this.videoStream = null; | ||
@@ -273,3 +270,2 @@ this.audioStream = null; | ||
} | ||
stopRecording() { | ||
@@ -286,9 +282,10 @@ const stopped = new Promise(resolve => { | ||
recording: false | ||
}); // get video file after recorder stopped | ||
}); | ||
// get video file after recorder stopped | ||
return this.getVideo(); | ||
}).then(file => { | ||
// store media file | ||
this.capturedMediaFile = file; // create object url for capture result preview | ||
this.capturedMediaFile = file; | ||
// create object url for capture result preview | ||
this.setPluginState({ | ||
@@ -307,3 +304,2 @@ // eslint-disable-next-line compat/compat | ||
} | ||
submit() { | ||
@@ -322,3 +318,2 @@ try { | ||
} | ||
stop() { | ||
@@ -334,5 +329,5 @@ // flush video stream | ||
this.videoStream = null; | ||
} // flush audio stream | ||
} | ||
// flush audio stream | ||
if (this.audioStream) { | ||
@@ -346,5 +341,5 @@ this.audioStream.getAudioTracks().forEach(track => { | ||
this.audioStream = null; | ||
} // flush output stream | ||
} | ||
// flush output stream | ||
if (this.outputStream) { | ||
@@ -358,5 +353,5 @@ this.outputStream.getAudioTracks().forEach(track => { | ||
this.outputStream = null; | ||
} // remove preview video | ||
} | ||
// remove preview video | ||
this.setPluginState({ | ||
@@ -367,11 +362,8 @@ recordedVideo: null | ||
} | ||
getVideo() { | ||
const mimeType = this.recordingChunks[0].type; | ||
const fileExtension = getFileTypeExtension(mimeType); | ||
if (!fileExtension) { | ||
return Promise.reject(new Error(`Could not retrieve recording: Unsupported media type "${mimeType}"`)); | ||
} | ||
const name = `screencap-${Date.now()}.${fileExtension}`; | ||
@@ -391,11 +383,8 @@ const blob = new Blob(this.recordingChunks, { | ||
} | ||
render() { | ||
// get screen recorder state | ||
const recorderState = this.getPluginState(); | ||
if (!recorderState.streamActive && !this.captureActive && !this.userDenied) { | ||
this.start(); | ||
} | ||
return h(RecorderScreen, _extends({}, recorderState, { | ||
@@ -411,4 +400,3 @@ // eslint-disable-line react/jsx-props-no-spreading | ||
} | ||
} | ||
ScreenCapture.VERSION = packageJson.version; |
import { h, Component } from 'preact'; | ||
class StopWatch extends Component { | ||
@@ -44,3 +43,2 @@ constructor(props) { | ||
} | ||
startTimer() { | ||
@@ -50,3 +48,2 @@ this.timerTick(); | ||
} | ||
resetTimer() { | ||
@@ -59,3 +56,2 @@ clearTimeout(this.timer); | ||
} | ||
timerTick() { | ||
@@ -68,5 +64,5 @@ this.timer = setTimeout(() => { | ||
}, 1000); | ||
} // eslint-disable-next-line class-methods-use-this | ||
} | ||
// eslint-disable-next-line class-methods-use-this | ||
fmtMSS(s) { | ||
@@ -76,3 +72,2 @@ // eslint-disable-next-line no-return-assign, no-param-reassign | ||
} | ||
render() { | ||
@@ -82,18 +77,17 @@ const { | ||
i18n | ||
} = { ...this.props | ||
} = { | ||
...this.props | ||
}; | ||
const { | ||
elapsedTime | ||
} = this.state; // second to minutes and seconds | ||
} = this.state; | ||
// second to minutes and seconds | ||
const minAndSec = this.fmtMSS(elapsedTime); | ||
if (recording && !this.timerRunning) { | ||
this.startTimer(); | ||
} | ||
if (!recording && this.timerRunning) { | ||
this.resetTimer(); | ||
} | ||
if (recording) { | ||
@@ -112,8 +106,5 @@ return h("div", { | ||
} | ||
return null; | ||
} | ||
} | ||
export default StopWatch; |
@@ -7,3 +7,2 @@ import { h } from 'preact'; | ||
} = _ref; | ||
if (streamActive) { | ||
@@ -31,3 +30,2 @@ return h("div", { | ||
} | ||
return h("div", { | ||
@@ -34,0 +32,0 @@ title: i18n('streamPassive'), |
import { h } from 'preact'; | ||
/** | ||
* Submit recorded video to uppy. Enabled when file is available | ||
*/ | ||
export default function SubmitButton(_ref) { | ||
@@ -13,3 +13,2 @@ let { | ||
} = _ref; | ||
if (recordedVideo && !recording) { | ||
@@ -37,4 +36,3 @@ return h("button", { | ||
} | ||
return null; | ||
} |
{ | ||
"name": "@uppy/screen-capture", | ||
"description": "Uppy plugin that captures video from display or application.", | ||
"version": "3.1.1", | ||
"version": "3.1.2", | ||
"license": "MIT", | ||
@@ -28,7 +28,7 @@ "main": "lib/index.js", | ||
"dependencies": { | ||
"@uppy/utils": "^5.3.0", | ||
"@uppy/utils": "^5.4.3", | ||
"preact": "^10.5.13" | ||
}, | ||
"peerDependencies": { | ||
"@uppy/core": "^3.2.0" | ||
"@uppy/core": "^3.4.0" | ||
}, | ||
@@ -35,0 +35,0 @@ "publishConfig": { |
@@ -1,2 +0,2 @@ | ||
import type { PluginOptions, UIPlugin, PluginTarget } from '@uppy/core' | ||
import type { PluginTarget, UIPlugin, UIPluginOptions } from '@uppy/core' | ||
@@ -14,3 +14,3 @@ // https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints#Properties_of_shared_screen_tracks | ||
export interface ScreenCaptureOptions extends PluginOptions { | ||
export interface ScreenCaptureOptions extends UIPluginOptions { | ||
target?: PluginTarget | ||
@@ -17,0 +17,0 @@ displayMediaConstraints?: DisplayMediaStreamConstraints, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
96587
18382
1453
Updated@uppy/utils@^5.4.3