Files
lelong/public/js/marhun-photo-capture.js
T
Afiq Hamzah 82e631a5d1 Fix to be usable to firefox
- Firefox can only detect lower resolution capability of camera, adding the min resolution in the camera constraints enables it to work in firefox
2023-05-25 14:13:52 +08:00

218 lines
8.0 KiB
JavaScript
Vendored

function marhunPhotoCapturerFactory(modal_selector) {
return {
constraints: {
video: true,
},
imageCapturer: null,
captureMedia: function (mediastream) {
let videoTrack = mediastream.getVideoTracks()[0];
let modal = document.querySelector(modal_selector);
let imageTag = modal.querySelector('.image-tag-overallmarhun');
let canvas = document.createElement('canvas');
let captureImage = () => {
let videoTag = modal.querySelector('.video-tag-overallmarhun.video-data');
return new Promise(function (resolve, reject) {
try {
let modal = document.querySelector(modal_selector);
let videoTag = modal.querySelector('.video-tag-overallmarhun.video-data');
canvas.width = 3200;
canvas.height = 1800;
canvas.getContext("2d").drawImage(videoTag, 0, 0, canvas.width, canvas.height)
resolve(canvas);
} catch (error) {
reject(error);
}
});
};
let setMarhunPhotoInputToCapturedPhoto = function (blob) {
const modal = document.querySelector(modal_selector);
const marhunPhotoInput = modal.querySelector('#inputGroupFile04');
const marhunPhotoFile = new File([blob], 'marhun_photo.png', {
type: 'image/png',
lastModified: new Date().getTime(),
});
const dataTransfer = new DataTransfer();
dataTransfer.items.add(marhunPhotoFile);
marhunPhotoInput.files = dataTransfer.files;
};
captureImage()
.then((canvas) => {
canvas.toBlob(function (blob) {
imageTag.src = URL.createObjectURL(blob);
imageTag.classList.add('marhun-uploaded');
modal.querySelector('.video-tag-overallmarhun').classList.add('d-none');
modal.querySelector('.camera-shutter').classList.remove('d-none');
modal.querySelector('.camera-shutter').classList.add('d-flex');
window.setTimeout(() => {
modal.querySelector('.image-tag-overallmarhun').classList.remove('d-none');
modal.querySelector('.camera-shutter').classList.remove('d-flex');
modal.querySelector('.camera-shutter').classList.add('d-none');
modal.querySelector('.camera-button').classList.add('d-none')
}, 1000);
modal.querySelector('button[type="submit"]').disabled = false;
setMarhunPhotoInputToCapturedPhoto(blob)
}, 'image/png');
})
.catch((err) => {
console.error("takePhoto() failed: ", err);
});
},
takePhoto: function () {
if ('mediaDevices' in navigator && navigator.mediaDevices.getUserMedia) {
this.getCamera()
.then(this.captureMedia)
.catch(e => { console.error('getUserMedia() failed: ', e); });
}
},
getCamera: function () {
function getCameraList() {
let getUserMedia = () => navigator.mediaDevices.getUserMedia({ video: {width: 3256, height: 2440} });
let enumerateDevices = () => navigator.mediaDevices.enumerateDevices()
.then(devices => devices.filter(x => x.kind === 'videoinput'))
getUserMedia();
return enumerateDevices();
}
function selectNearWorkingCamera(listOfCameras) {
return listOfCameras.at(0);
}
function selectPriorityCameraIfExist(listOfCameras) {
const available_cameras = listOfCameras.map(camera => {
let altered_label = camera.label.split(" ");
altered_label.splice(-1);
altered_label = altered_label.join(" ");
return {
label: altered_label,
deviceId: camera.deviceId,
};
});
const filteredCameraChrome = available_cameras.filter(camera => {
return marhun_camera_config_chrome.includes(camera.label);
})
const filteredCameraFirefox = available_cameras.filter(camera => {
return marhun_camera_config_firefox.includes(camera.deviceId);
});
let isfirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
if (isfirefox) {
if (filteredCameraFirefox.length > 0) {
return filteredCameraFirefox.splice(-1);
}
const filteredCameraFirefoxLastDevice = available_cameras.splice(-1);
return filteredCameraFirefoxLastDevice;
}
// Get the first available priority referencing to env
return filteredCameraChrome.at(-1);
}
function selectCamera(listOfCameras) {
let priorityCamera = selectPriorityCameraIfExist(listOfCameras);
if (!priorityCamera) {
return selectNearWorkingCamera(listOfCameras)
}
return priorityCamera;
}
function composeConstraint(camera) {
let constraints = {
width: { min: 1280, max: 3200 },
height: { min: 720, max: 1800 },
aspectRatio: {exact: 1.7777777778},
};
if (camera.deviceId !== '') {
constraints.deviceId = { exact: camera.deviceId };
return navigator.mediaDevices.getUserMedia({ video: constraints });
}
if (camera.groupId !== '') {
constraints.groupId = { exact: camera.groudId };
return navigator.mediaDevices.getUserMedia({ video: constraints });
}
}
return getCameraList()
.then(selectCamera)
.then(composeConstraint);
},
initiateTakeMarhunPhoto: function () {
if ('mediaDevices' in navigator && navigator.mediaDevices.getUserMedia) {
function showCaptureMarhunModal() {
let modal = document.querySelector(modal_selector);
modal.querySelector('.video-tag-overallmarhun').classList.remove('d-none');
modal.querySelector('.image-tag-overallmarhun').classList.add('d-none');
modal.querySelector('.camera-shutter').classList.add('d-none');
modal.querySelector('.camera-button').classList.remove('d-none');
modal.querySelector('button[type="submit"]').disabled = true;
$(modal_selector).modal('show');
}
function streamCameraView(stream) {
console.log(stream.getVideoTracks()[0].getSettings())
let modal = document.querySelector(modal_selector);
let videoTagPreview = modal.querySelector('.video-tag-overallmarhun.video-preview');
let videoTagData = modal.querySelector('.video-tag-overallmarhun.video-data');
videoTagPreview.srcObject = stream;
videoTagData.srcObject = stream;
}
this.getCamera()
.then(streamCameraView)
.then(showCaptureMarhunModal);
}
},
}
}