что будет лучше загружать видео создавать постер к нему в php через ffmpeg и сохранять его или лучше все это делать на js и отправлять его в php и там уже сохранять если не учитывать безопасность и если не сложно можно простыми понятными для новичка примерами
В принципе достаточно не сложно получить один кадр прямо на страничке, в сниппете ниже Вы можете выбрать видео с диска, проиграть его до нужного кадра, затем захватить этот кадр кнопкой pick, после чего появится канва, на которой этот кадр нарисован и можно сверху нарисовать линии. После всего этого нажав на кнопку download можно скачать получившуюся картинку.
select.onchange = e => {
if (!video.canPlayType(select.files[0].type))
return
video.src = URL.createObjectURL(select.files[0]);
hideShow([select], [video, pick]);
};
pick.onclick = e => {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext ('2d').drawImage (video, 0, 0);
hideShow([video, pick], [canvas, download]);
}
download.onclick = () => {
var link = document.createElement('a');
link.download = 'frame.png';
link.href = canvas.toDataURL()
link.click();
}
function hideShow(hide, show) {
show.forEach(el => el.style.display = 'block')
hide.forEach(el => el.style.display = 'none')
}
var ctx = canvas.getContext('2d');
var pos = {};
document.addEventListener('mousemove', draw);
document.addEventListener('mousedown', setPosition);
function setPosition(e) {
pos.x = e.layerX;
pos.y = e.layerY;
}
function draw(e) {
if (e.buttons !== 1)
return;
ctx.beginPath();
ctx.lineWidth = 5;
ctx.lineCap = 'round';
ctx.strokeStyle = '#c0392b';
ctx.moveTo(pos.x, pos.y);
setPosition(e);
ctx.lineTo(pos.x, pos.y);
ctx.stroke();
}
<input id="select" type="file" accept="video/*"/>
<button id="pick" style="display:none">pick frame</button>
<button id="download" style="display:none">download</button>
<video id="video" style="display:none" controls></video>
<canvas id="canvas" style="display:none"></canvas>
Вариант в котором сразу на канве появляется средний кадр
select.onchange = e => {
if (!video.canPlayType(select.files[0].type))
return
video.src = URL.createObjectURL(select.files[0]);
chain(100, [
e => video.currentTime = video.duration/2,
e => canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height),
e => canvas.toBlob(blob => fetch('/post/image', {method: 'POST', body: blob})
.then(resp => resp.json())
.then(res => console.log(JSON.stringify(res))))
]);
};
function chain(timeout, funcs) {
funcs.length && setTimeout(e => {
funcs.shift()();
chain(timeout, funcs);
}, timeout);
}
<input id="select" type="file" accept="video/*"/><br>
<video id="video" style="display:none" controls></video>
<canvas id="canvas" width=400 height=300></canvas>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Сайт состоит из 3 частей: header, div#content и footerПри этом, header имеет фиксированную высоту, а footer - нет
Если enum Oper порядка 30 штукЕсть метод класса, которая принимает параметр Oper и работает с полями класса