Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Постер в тегу video (https://javascript.ru/forum/events/85228-poster-v-tegu-video.html)

Destrifer 19.05.2023 15:05

Постер в тегу video
 
Хочу автоматически ставить постер, на основании содержимого видеофайла.
Как это сделать?

Nexus 19.05.2023 15:11

Google: ffmpeg extract frame from video

upd. или вот варианты, но с буферизацией видео:
https://stackoverflow.com/questions/...in-html5-video

Destrifer 19.05.2023 16:53

Спасибо, но я имел ввиду средствами frontend конечно-же, а не просто ПК.
По идее мне надо для каждого видео делать отдельный постер, а хочется автоматом.

Во второй ссылке про те древние времена, когда первый кадр видео не использовался сейчас как постер.
Но первый кадр часто черный, не подходит.

И да, я пробовал использовать "#t=0.1", у меня не работает :( .

Nexus 19.05.2023 17:29

Destrifer, имхо, лучше выковырять фрейм из видео и сохранить его отдельно, чем каждый раз заставлять клиента подгружать часть видео.
Если на странице будет список записей, то это как лишний трафик для клиента, так и лишняя нагрузка на сервер.

Destrifer 20.05.2023 01:31

Ну это также и лишнее поле и лишний запрос в БД.
А траффик сейчас все-же не как 20 лет назад - скорости выросли значительно.
Да и это больше pet-проект, поэтому мне больше интересна сама реализация механизма.

Вот что пока удалось сделать: http://ilikeike.beget.tech/
Получается мы можем вытянуть любой фрейм и сохранить его как картинку, и, в теории, подставить как постер.

Единственно, вопрос в грамотной реализации последовательности событий.
Получается, сначала нам нужно:
1. Перемотать видео.
2. Сохранить текущий кадр в img.
3. Подставить его как постер, в это же самое видео.

Но постер инициализируется при отрисовке DOM. Его нельзя довставить "потом".

И у меня нет уверености, что мы можем до отрисовки получить фрейм, и вставить как постер и потом отрисовать.

Конечно можно с одного экземляра вытаскивать фрейм, и вставить в тот что увидит пользователь. Просто отложить его загрузку для пользователя.

И мне не совсем понятно как реализовать эту отложенную загрузку.
Создавать эти вторые экземляры через js? Это уже усложнит код. Должно быть более простое решение.

И с вытаскиванием фрейма тоже вопросы. По событию пользователя все работает. А как это сделать в фоне, без участия пользователя?

voraa 20.05.2023 08:37

Цитата:

Сообщение от Destrifer
А как это сделать в фоне, без участия пользователя?

Никак. Видео нельзя запустить без события, инициированного пользователем

Destrifer 20.05.2023 13:45

Как нельзя?
Можно же.
Нельзя со звуком, но если стоит muted то все работает.
А нам для фрейма звук и не нужен.

voraa 20.05.2023 14:22

Ну если можно, то прогоните видео до нужного тайм-кода (fastSeek) и ловите событие seeked. По событию берите картинку из видео.

Но лучше для каждого виде вручную подготовить кадр - картину.

Destrifer 20.05.2023 19:03

Спасибо.
Почти получилось. http://ilikeike.beget.tech/
Получаю картинку и подставляю в постер ко второму видео.
Но оно идет с белым экраном.
window.onload = function () {
var video = document.getElementById('videoId');
var canvas = document.createElement('canvas');
var img = document.createElement('img');
video.currentTime = 5;

	video.onseeked = function () {
		canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
		img.setAttribute('src', canvas.toDataURL());
	};
	
	video.insertAdjacentElement('afterEnd', img);
	document.getElementById('video2').setAttribute('poster', canvas.toDataURL());
};


Думаю надо чуть "задержать" подгрузку html другого видео, чтобы постер был готов. Есть варианты?
Или только createElement?

Destrifer 20.05.2023 23:48

Ещё проблема в том что метод toDataURL, выдает картинку в base64.
Но атрибут poster не поддерживает такие длинные строки и обрезает код.


Часовой пояс GMT +3, время: 18:15.