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

added getVideoTrack function to imperative ref. So #68

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions dist/components/Camera/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export interface CameraProps {
aspectRatio?: AspectRatio;
numberOfCamerasCallback?(numberOfCameras: number): void;
videoSourceDeviceId?: string | undefined;
errorMessages: {
errorMessages?: {
noCameraAccessible?: string;
permissionDenied?: string;
switchCamera?: string;
Expand All @@ -20,7 +20,10 @@ export interface CameraProps {
videoReadyCallback?(): void;
}
export declare type CameraType = React.ForwardRefExoticComponent<CameraProps & React.RefAttributes<unknown>> & {
takePhoto(): string;
takePhoto(type?: 'base64url' | 'imgData'): string | ImageData;
switchCamera(): FacingMode;
getNumberOfCameras(): number;
toggleTorch(): boolean;
getVideoTrack(): MediaStreamTrack | null;
torchSupported: boolean;
};
250 changes: 199 additions & 51 deletions dist/index.cjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,43 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */

function __awaiter(thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}

function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}

function __makeTemplateObject(cooked, raw) {
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
return cooked;
Expand Down Expand Up @@ -53,18 +90,64 @@ var Camera = React__default.forwardRef(function (_a, ref) {
} : _f, _g = _a.videoReadyCallback, videoReadyCallback = _g === void 0 ? function () { return null; } : _g;
var player = React.useRef(null);
var canvas = React.useRef(null);
var context = React.useRef(null);
var container = React.useRef(null);
var _h = React.useState(0), numberOfCameras = _h[0], setNumberOfCameras = _h[1];
var _j = React.useState(null), stream = _j[0], setStream = _j[1];
var _k = React.useState(facingMode), currentFacingMode = _k[0], setFacingMode = _k[1];
var _l = React.useState(false), notSupported = _l[0], setNotSupported = _l[1];
var _m = React.useState(false), permissionDenied = _m[0], setPermissionDenied = _m[1];
var _o = React.useState(false), torchSupported = _o[0], setTorchSupported = _o[1];
var _p = React.useState(false), torch = _p[0], setTorch = _p[1];
var mounted = React.useRef(false);
React.useEffect(function () {
mounted.current = true;
return function () {
mounted.current = false;
};
}, []);
React.useEffect(function () {
numberOfCamerasCallback(numberOfCameras);
}, [numberOfCameras]);
var switchTorch = function (on) {
if (on === void 0) { on = false; }
return __awaiter(void 0, void 0, void 0, function () {
var supportedConstraints, track, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!(stream && (navigator === null || navigator === void 0 ? void 0 : navigator.mediaDevices) && !!mounted.current)) return [3 /*break*/, 4];
supportedConstraints = navigator.mediaDevices.getSupportedConstraints();
track = stream.getTracks()[0];
if (!(supportedConstraints && 'torch' in supportedConstraints && track)) return [3 /*break*/, 4];
_b.label = 1;
case 1:
_b.trys.push([1, 3, , 4]);
return [4 /*yield*/, track.applyConstraints({ advanced: [{ torch: on }] })];
case 2:
_b.sent();
return [2 /*return*/, true];
case 3:
_a = _b.sent();
return [2 /*return*/, false];
case 4: return [2 /*return*/, false];
}
});
});
};
var getVideoTrack = function () {
if (stream && (navigator === null || navigator === void 0 ? void 0 : navigator.mediaDevices) && !!mounted.current) {
var track = stream.getTracks()[0];
return track;
}
return null;
};
React.useEffect(function () {
switchTorch(torch);
}, [torch]);
React.useImperativeHandle(ref, function () { return ({
takePhoto: function () {
var _a, _b, _c, _d;
takePhoto: function (type) {
var _a, _b, _c, _d, _e;
if (numberOfCameras < 1) {
throw new Error(errorMessages.noCameraAccessible);
}
Expand All @@ -75,7 +158,7 @@ var Camera = React__default.forwardRef(function (_a, ref) {
var canvasWidth = ((_c = container === null || container === void 0 ? void 0 : container.current) === null || _c === void 0 ? void 0 : _c.offsetWidth) || 1280;
var canvasHeight = ((_d = container === null || container === void 0 ? void 0 : container.current) === null || _d === void 0 ? void 0 : _d.offsetHeight) || 1280;
var canvasAR = canvasWidth / canvasHeight;
var sX = void 0, sY = void 0, sW = void 0, sH = void 0;
var sX = void 0, sY = void 0, sW = void 0, sH = void 0, imgData = void 0;
if (playerAR > canvasAR) {
sH = playerHeight;
sW = playerHeight * canvasAR;
Expand All @@ -90,11 +173,20 @@ var Camera = React__default.forwardRef(function (_a, ref) {
}
canvas.current.width = sW;
canvas.current.height = sH;
var context = canvas.current.getContext('2d');
if (context && (player === null || player === void 0 ? void 0 : player.current)) {
context.drawImage(player.current, sX, sY, sW, sH, 0, 0, sW, sH);
if (!context.current) {
context.current = canvas.current.getContext('2d', { willReadFrequently: true });
}
if (context.current && (player === null || player === void 0 ? void 0 : player.current)) {
context.current.drawImage(player.current, sX, sY, sW, sH, 0, 0, sW, sH);
}
switch (type) {
case 'imgData':
imgData = (_e = context.current) === null || _e === void 0 ? void 0 : _e.getImageData(0, 0, sW, sH);
break;
default: /* base64url */
imgData = canvas.current.toDataURL('image/jpeg');
break;
}
var imgData = canvas.current.toDataURL('image/jpeg');
return imgData;
}
else {
Expand All @@ -115,11 +207,19 @@ var Camera = React__default.forwardRef(function (_a, ref) {
getNumberOfCameras: function () {
return numberOfCameras;
},
getVideoTrack: getVideoTrack,
toggleTorch: function () {
var torchVal = !torch;
setTorch(torchVal);
return torchVal;
},
torchSupported: torchSupported,
}); });
React.useEffect(function () {
initCameraStream(stream, setStream, currentFacingMode, videoSourceDeviceId, setNumberOfCameras, setNotSupported, setPermissionDenied);
initCameraStream(stream, setStream, currentFacingMode, videoSourceDeviceId, setNumberOfCameras, setNotSupported, setPermissionDenied, !!mounted.current);
}, [currentFacingMode, videoSourceDeviceId]);
React.useEffect(function () {
switchTorch(false).then(function (success) { return setTorchSupported(success); });
if (stream && player && player.current) {
player.current.srcObject = stream;
}
Expand All @@ -141,51 +241,99 @@ var Camera = React__default.forwardRef(function (_a, ref) {
React__default.createElement(Canvas, { ref: canvas }))));
});
Camera.displayName = 'Camera';
var initCameraStream = function (stream, setStream, currentFacingMode, videoSourceDeviceId, setNumberOfCameras, setNotSupported, setPermissionDenied) {
var _a;
// stop any active streams in the window
if (stream) {
stream.getTracks().forEach(function (track) {
track.stop();
});
}
var constraints = {
audio: false,
video: {
deviceId: videoSourceDeviceId ? { exact: videoSourceDeviceId } : undefined,
facingMode: currentFacingMode,
width: { ideal: 1920 },
height: { ideal: 1920 },
},
};
if ((_a = navigator === null || navigator === void 0 ? void 0 : navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.getUserMedia) {
navigator.mediaDevices
.getUserMedia(constraints)
.then(function (stream) {
setStream(handleSuccess(stream, setNumberOfCameras));
})
.catch(function (err) {
handleError(err, setNotSupported, setPermissionDenied);
});
}
else {
var getWebcam = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
if (getWebcam) {
getWebcam(constraints, function (stream) {
setStream(handleSuccess(stream, setNumberOfCameras));
}, function (err) {
handleError(err, setNotSupported, setPermissionDenied);
});
var shouldSwitchToCamera = function (currentFacingMode) { return __awaiter(void 0, void 0, void 0, function () {
var cameras;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
cameras = [];
if (!(currentFacingMode === 'environment')) return [3 /*break*/, 2];
return [4 /*yield*/, navigator.mediaDevices.enumerateDevices().then(function (devices) {
var videoDevices = devices.filter(function (i) { return i.kind == 'videoinput'; });
videoDevices.forEach(function (device) {
var capabilities = device.getCapabilities();
if (capabilities.facingMode && capabilities.facingMode.indexOf('environment') >= 0 && capabilities.deviceId) {
cameras.push(capabilities.deviceId);
}
});
})];
case 1:
_a.sent();
_a.label = 2;
case 2:
if (cameras.length > 1) {
return [2 /*return*/, cameras.pop()];
}
return [2 /*return*/, undefined];
}
else {
setNotSupported(true);
});
}); };
var initCameraStream = function (stream, setStream, currentFacingMode, videoSourceDeviceId, setNumberOfCameras, setNotSupported, setPermissionDenied, isMounted) { return __awaiter(void 0, void 0, void 0, function () {
var cameraDeviceId, switchToCamera, constraints, getWebcam;
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
// stop any active streams in the window
if (stream) {
stream.getTracks().forEach(function (track) {
track.stop();
});
}
return [4 /*yield*/, shouldSwitchToCamera(currentFacingMode)];
case 1:
switchToCamera = _b.sent();
if (switchToCamera) {
cameraDeviceId = switchToCamera;
}
else {
cameraDeviceId = videoSourceDeviceId ? { exact: videoSourceDeviceId } : undefined;
}
constraints = {
audio: false,
video: {
deviceId: cameraDeviceId,
facingMode: currentFacingMode,
},
};
if ((_a = navigator === null || navigator === void 0 ? void 0 : navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.getUserMedia) {
navigator.mediaDevices
.getUserMedia(constraints)
.then(function (stream) {
if (isMounted) {
setStream(handleSuccess(stream, setNumberOfCameras));
}
})
.catch(function (err) {
handleError(err, setNotSupported, setPermissionDenied);
});
}
else {
getWebcam = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
if (getWebcam) {
getWebcam(constraints, function (stream) { return __awaiter(void 0, void 0, void 0, function () {
return __generator(this, function (_a) {
if (isMounted) {
setStream(handleSuccess(stream, setNumberOfCameras));
}
return [2 /*return*/];
});
}); }, function (err) {
handleError(err, setNotSupported, setPermissionDenied);
});
}
else {
setNotSupported(true);
}
}
return [2 /*return*/];
}
}
};
});
}); };
var handleSuccess = function (stream, setNumberOfCameras) {
navigator.mediaDevices
.enumerateDevices()
Expand Down
Loading