Извлечение кадров из загруженного видео не работает на мобильных устройствах (iOS) из-за проблем совместимости тега <vidIOS

Программируем под IOS
Ответить
Anonymous
 Извлечение кадров из загруженного видео не работает на мобильных устройствах (iOS) из-за проблем совместимости тега <vid

Сообщение Anonymous »

Я разрабатываю простой интерфейс обработки видео, который позволяет пользователям загружать видео, извлекать кадры и просматривать их в элементе холста. Приложение отлично работает на моем ноутбуке, но когда я тестирую его на устройстве iOS, извлечение кадров не работает. В частности, когда пользователь загружает видео, я помещаю его в скрытый элемент и использую метод play() для изменения кадров, отображения их в элементе и сохранения данные. Однако этот подход кажется несовместимым с мобильными устройствами.
Чтобы устранить эту проблему, я попытался удалить метод play() и добавить к видео атрибуты autoplay, playsinline и mute. тег, но, похоже, это не работает на iOS. Видео просто не воспроизводится и не извлекает кадры.
Мой вопрос: существуют ли какие-либо известные проблемы совместимости с тегом и мобильными устройствами, которые могут быть причиной этого? проблема? Существуют ли альтернативные подходы или библиотеки, которые позволили бы мне извлекать кадры из загруженных видео более надежным способом, учитывая мои требования полностью запускать эту функциональность в браузере?
Вот простая реализация который работает на моем ноутбуке:

Код: Выделить всё






Play Video



Select Frame









let frames = [];

// Create a video element, and play the video but do not display it.
async function getVideoElement() {
const video = document.getElementById("video");
const item = document.getElementById("file").files[0];
const reader = new FileReader();
reader.readAsArrayBuffer(item);
reader.onload = function (event) {
const blob = new Blob([event.target.result]);
video.src = URL.createObjectURL(blob);
video.hidden = true;
video.addEventListener("loadedmetadata", function () {
// Adjust the playback rate so all frames can be captured
video.playbackRate = 0.1; //playbackRate; // Set the playback rate
});
video.play();
};
return video;
}

// Frames are graded sequentially from the video, and displayed into a canvas.
// The frames will be resized in dispalyImage and shown in the specified "output"
// canvas.  Frames are saved to an array for use later with the select dropdown.
async function playVideo() {
playing = true;
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const select = document.querySelector("select");
const video = await getVideoElement();
video.addEventListener("canplay", () => {
const drawingLoop = async () => {
const index = frames.length;
select.appendChild(new Option("Frame #" + (index + 1), index));
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
const imageBlob = await new Promise((resolve) =>
canvas.toBlob(resolve, "image/png")
);
const arrayBuffer = await new Response(imageBlob).arrayBuffer();
await displayImage(arrayBuffer);
frames.push(arrayBuffer);
if (!video.ended && playing) {
video.requestVideoFrameCallback(drawingLoop);
}
};
video.requestVideoFrameCallback(drawingLoop);
});
}

// Display a frame from the video into the output canvas.
// The incoming data is an ArrayBuffer.
async function displayImage(data) {
return new Promise((resolve) => {
const image = new Image();
image.onload = async function () {
const canvas = document.getElementById("output");
const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
const scaleFactor = Math.min(
canvas.width / image.width,
canvas.height / image.height
);
const scaledWidth = image.width * scaleFactor;
const scaledHeight = image.height * scaleFactor;
ctx.drawImage(image, 0, 0, scaledWidth, scaledHeight);
const resizedImageData = canvas.toDataURL();
resolve(resizedImageData);
};
image.src = URL.createObjectURL(new Blob([data]));
});
}

// Choose a frame to display after video is processed.
async function selectFrame() {
const select = document.getElementById("frameSelect");
const selectedFrameIndex = parseInt(select.value);
if (selectedFrameIndex >= 0 && selectedFrameIndex < frames.length) {
const selectedFrameData = frames[selectedFrameIndex];
console.log(selectedFrameData);
await displayImage(selectedFrameData);
}
}



Будем очень признательны за любые идеи и предложения по решению этой проблемы!


Подробнее здесь: https://stackoverflow.com/questions/784 ... e-to-video
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»