Снимок WebRTC с веб-камеры и сохранение его на сервере в PHP: iPhone Safari вылетает при разрешении выше 2096
У меня есть РАБОЧИЙ код, чтобы сделать снимок с веб-камеры и сохранить его на PHP через ajax ... но когда я пытаюсь использовать разрешение выше 2000, сафари-мобильный на iPhone вылетает, почему и как это исправить?
здесь, если я сделаюgetUserMedia({ video:{width: { ideal: 2096
=> все в порядке
Но если я будуgetUserMedia({ video:{width: { ideal: 3096
=> вылетает :(
HTML
<video id="precam" playsinline="true" muted autoplay style="max-width:90%;" ></video>
<canvas id="canvax" ></canvas>
<div onclick="sendToServer('ajaxanswer');">SAVE</div>
<div onclick="webcamFRONT();">SWITCH TO FRONT CAM</div>
<div id="ajaxanswer" ></div>
JAVASCRIPT
<script>
const videoPlayer = document.querySelector("#precam");
const canvas = document.querySelector("#canvax");
function webcamREAR () {
navigator.mediaDevices.getUserMedia({ video:{width: { ideal: 2096 },facingMode: "environment"}, audio:false })
.then(stream => videoPlayer.srcObject = stream)
.catch(error => {console.error(error);});
}
function webcamFRONT () {
navigator.mediaDevices.getUserMedia({ video:{width: { ideal: 2096 },facingMode: "user"}, audio:false })
.then(stream => videoPlayer.srcObject = stream)
.catch(error => {console.error(error);});
}
function wcanvasim () {
canvas.width = videoPlayer.videoWidth; canvas.height = videoPlayer.videoHeight;
canvas.getContext("2d").drawImage(videoPlayer, 0, 0, canvas.width, canvas.height);
}
webcamREAR();
function sendToServer (divID) {
var pcache = (Math.floor(Math.random() * 100000000) + 1);
var params = "divID="+encodeURIComponent(divID)+"&canvablob="+encodeURIComponent(canvas.toDataURL());
var xhr = new XMLHttpRequest(); xhr.open("POST", "/file.php?pcache="+pcache, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function(e) { if (xhr.readyState == 4) { $("#"+divID).html(e.currentTarget.responseText) ; } }
xhr.send(params);
}
</script>
PHP
<?php
$whereTOdeBlob = '/path/to/server/'.mt_rand().'.png';
$canvablob = ( $_REQUEST['canvablob'] ?? '' ) ;
$canva64 = explode('base64,',$canvablob)[1] ?? '';
file_put_contents(INCLUDE_PATH_ROOT.$whereTOdeBlob,base64_decode($canva64));
// CONVERT TO JPG
// ADD TO DATABASE
// ANY STUFF YOU WANT ;)
echo '<img src="'.$canvablob.'" />';
?>
******* Возникает вопрос: почему при большом разрешении сафари вылетает?

1 ответ
Ты используешь .toDataURL()
чтобы закодировать это огромное изображение как файл .png без потерь . Это, вероятно, генерирует многомегабайтную строку, которую вы пытаетесь выполнить POST. Где-то по пути Safari, вероятно , исчерпает непрерывную оперативную память и гаки либо при выделении, либо при сборке мусора. Также вероятно, что размер полезной нагрузки вашего POST превышает максимум php .
Пытаться.toDataURL('image/jpeg', 0.3)
чтобы получить изображение JPEG низкого качества, которое будет генерировать гораздо меньшую строку. Если это сработает, увеличьте качество (от 0,3 до 0,4, 0,5 и т. Д.).
Или, лучше, преобразуйте свой холст в двоичный объект Blob и опубликуйте его . Это займет меньше места, чем URL-адрес данных. Что-то вроде этого. Не, повторюсь, не отлажен.
function sendToServer (divID) {
var pcache = (Math.floor(Math.random() * 100000000) + 1)
canvas.toBlob (function (blob) {
var xhr = new XMLHttpRequest()
xhr.open("POST", "/file.php?pcache="+pcache, true);
xhr.onreadystatechange = function (e) {
if (xhr.readyState == 4)
$("#"+divID).html(e.currentTarget.responseText)
}
var fd = new FormData();
fd.append('divID', divID)
fd.append('canvaBlob', blob)
xhr.send(fd)
}, 'image/jpeg', 0.8)
}
Также попробуйте ограничить высоту изображения, а также ширину. Если ваша камера находится в портретном режиме и вы запрашиваете ширину 2K, вы можете получить высоту 4K, если позволите.getUserMedia()
выберите ту высоту, которую пожелает; он подчиняется соотношению сторон по умолчанию.
Наконец, с практической точки зрения изображения с таким высоким разрешением обычно должны быть субдискретизированы перед их использованием. Изображения JPEG с более низким разрешением обычно соответствуют практическим требованиям. Так что просто снимайте изображения с низким разрешением. (Если вы фотограф, делающий фотографии для печати в глянцевых журналах, вы уже знаете об ограничениях камер iPhone.)
Другие вопросы
- Функция клавиатуры работает только один раз для первой буквы ввода2 ответ
У меня есть текстовый ввод, где пользователь вводит желаемое имя страницы<input type='text' id='pageName' name='PageName' class='form-control pageName'> Я пытаюсь использовать функцию keyup для запуска Ajax, чтобы проверить, существует ли страница, однако при вводе чего-то вродеindex Ajax от...
- ajax дважды загружает данные из базы данных с помощью laravel php1 ответ
привет, я пытаюсь загрузить данные из базы данных с помощью ajax. но данные загружаются дважды на страницу html.<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script> $('button').click(function(){ $.ajax({ ...
- отображать другие входы на основе значения другого входа с помощью laravel, ajax1 ответ
Я новичок в laravel, и я пытаюсь создать форму и отправить ее в базу данных. Мне удалось сохранить данные в базе данных, используя следующий код. Мой клинок: <form id="castingform" method="post" action="castingss" enctype="multipart/form-data"> ...
- Передача значения параметра от кнопки Datatables к функции1 ответ
Я пытаюсь передать значение кнопки в таблице данных функции. Однако я просто получаю значение первой строки. Надеюсь, ты сможешь мне помочь. Мне просто нужно предупредить параметр, а обо всем остальном я позабочусь. вот код memberlist.php<?php header('Content-Type: application/json; Charset="...

"Завидую тестировщикам: все хотят с ними дружить."
canvas.toDataURL('image/jpeg', 0.9)
и идеальный 3069, и он работает очень хорошо !!!! Jintor