Ошибки воспроизведения видео

Всем привет. На Ютубе некоторые авторы загружают двух часовые фильмы и там каждые три секунды кадры, то с близи показывает,то с дали и так весь фильм,длина фильма 1.5 — 2 часа. Не реально двух часовые фильмы в ручную редактировать так. Есть ли какой-нибудь плагин или скрипт для автоматического добавления такого эффекта на длинные видео,чтобы не делать этого вручную?Спасибо.Ссылка

Администрация форума не имеет отношения к пользователям форума и к публикуемой ими информации. Пользовательское соглашение

Вы можете столкнуться с одной из следующих проблем при использовании Adobe Flash Player:

  • Видео не отображается.
  • Вместо видео отображается черный или белый квадрат.
  • Пятнистое отображение цветов.
  • Окно проигрывателя разделено зеленой линией.
  • Панель поиска и навигации отсутствует или отображается неправильно.
  • При изменении разрешения (особенно в полноэкранном режиме) воспроизведение видео прекращается.

Flash Player версии 10 и более новых версий может использовать видеокарту вашей системы для ускорения декодирования видео. Flash Player версии 10.2 и более новых версий также может ускорить видеопрезентации на некоторых сайтах, улучшая воспроизведение видео. Если у вас возникли проблемы с воспроизведением видео в Flash Player, возможно, у драйвера вашей видеокарты имеются проблемы совместимости. Следуйте инструкциям в этом документе, чтобы решить эти проблемы и предоставить компании Adobe информацию, которая может быть использована для улучшения Flash Player.

См. следующие видео в браузере, поддерживающем HTML5.

Правовые уведомления   |   Политика конфиденциальности в сети Интернет

aug_kysskpk1yqlni-j2hseregy.jpeg Очень часто видео в онлайн-кинотеатрах имеет соотношение сторон, отличное от соотношения сторон монитора. Поэтому иногда возникает желание сделать общий масштаб чуть крупнее за счет небольшой обрезки по краям. Или вовсе — вписать изображение в размеры экрана по меньшей стороне картинки. Особенно это актуально для маленьких экранов, а также, для старых мониторов 4:3. Я уж молчу о том, что оригинальное видео может быть вообще растянуто по одной из сторон и это необходимо как-то исправить. Для решения данной проблемы я задумал написать браузерное расширение под Chrome и Firefox. Идея такая: при проигрывании любого браузерного видео вызывается экранное меню, которое позволяет произвольно менять масштаб и соотношение сторон картинки.

iframe

Первая проблема, с которой я столкнулся, заключается в том, что видео на сайтах вовсе не обязательно располагается на основной странице, а может быть запрятано глубоко во вложенных iframe. Я решил просканировать все iframe-элементы и найти в каждом из них все элементы video. Кстати, этим решается и другая проблема — никогда не знаешь, где рекламное видео, а где сам фильм. Давайте для начала найдем их всех. Функция getVideos вызывает рекурсивно сама себя до тех пор, пока в последнем iframe не будут найдены все элементы video. Все видео добавляются в массив ap_ext_space.videos. В качестве входного параметра функция getVideos принимает документ текущей страницы. При первом запуске берется главный документ. По ходу еще на каждое видео навешиваются обработчики, но об этом ниже.

getVideos: function (srcDoc) { if (!srcDoc) { srcDoc = document; window.onkeydown = function (event) { var e = event || window.event; ap_ext_space.keyDn(e); }; };  var els = srcDoc.getElementsByTagName('video'); for (var i = 0; i < els.length; i++) { els[i].addEventListener("seeked", function () {ap_ext_space.zoomw(); console.log('seeked'); }, true); els[i].addEventListener("abort", function () {ap_ext_space.zoomw(); console.log('abort'); }, true); els[i].addEventListener("pause", function () {ap_ext_space.zoomw(); console.log('pause'); }, true); els[i].addEventListener("play", function () {ap_ext_space.zoomw(); console.log('play'); }, true); els[i].addEventListener("playing", function () {ap_ext_space.zoomw(); console.log('playing'); }, true); els[i].addEventListener("seeked", function () {ap_ext_space.zoomw(); console.log('seeked'); }, true);  ap_ext_space.videos.push(els[i]); ap_ext_space.menu(els[i], srcDoc); }; console.log('all videos:', ap_ext_space.videos);  var ifrs = srcDoc.getElementsByTagName("iframe"); console.log('iframes:', ifrs);  var ifr; for (var i = 0; i < ifrs.length; i++) { ifr = ifrs[i]; try { var innerDoc = (ifr.contentDocument || ifr.contentWindow.document); var innerWindow = (ifr.contentWindow || ifr); innerWindow.onkeydown = function (event) { var e = event || window.event; ap_ext_space.keyDn(e); }; ap_ext_space.getVideos(innerDoc); } catch (err) { console.log('err', err); }; }; },

Экранное меню

qwmcf7hfxo27rg5x1bk5dodr8me.jpeg Хорошо, список всех видео-элементов у нас есть. Теперь как отобразить экранное меню? Просто добавим его блочный элемент к каждому видео. Да, тогда у нас будет много экранных меню, но в один момент времени все равно отображается только одно видео: один из рекламных роликов либо сам фильм. И меню вместе с ними будет показываться только одно. Видео, как правило, располагается в родительском div-элементе. Добавим к нему в качестве последнего child наш div-элемент меню. Таким образом, экранное меню всегда будет отображаться поверх видео. Изображение экранного меню закодируем в base64 в формате png с прозрачным альфа-каналом и поместим в ap_ext_space.imgUR, так как браузер не позволит нам подгрузить изображение с другого домена. Создание меню для каждого видео:

menu: function(videoEl, doc) {  //ищем все div родительского к video элемента //тем самым определяем, не добавлено ли уже экранное меню (флаг menuInside) var els = videoEl.parentNode.getElementsByTagName('div'); var menuInside = false; for (var j = 0; j < els.length; j++) { if (els[j].id == 'ap_ext_space_container') { menuInside = true; ap_ext_space.menus.push(els[j]); }; };  if (menuInside == false) {  //создадим элемент экранного меню var div = doc.createElement('div'); div.innerHTML = ap_ext_space.html(); videoEl.parentNode.appendChild(div); div.style.width = '520px'; div.style.height = '410px'; div.style.display = 'block'; div.style.position = 'absolute'; div.id = 'ap_ext_space_container'; var url = "url('" + ap_ext_space.imgURL + "')"; div.style.backgroundImage = url; div.style.opacity = 0.95; ap_ext_space.menus.push(div);  //привяжем к нему обработчики div.addEventListener("dblclick", function(e) { e.preventDefault(); e.stopPropagation(); }, true);  div.addEventListener("mouseover", function(e) { e.preventDefault(); e.stopPropagation();  var elem, evt = e ? e : event; if (evt.srcElement) { elem = evt.srcElement; } else if (evt.target) { elem = evt.target; };  //позиции экранных кнопок для наведения мышью var pos = { ap_ext_space_num7: [520 + 134, 82], ap_ext_space_num8: [520 + 134 + 90, 82], ap_ext_space_num9: [520 + 134 + 90 + 90, 82], ap_ext_space_num4: [520 + 134, 82 + 90], ap_ext_space_num5: [520 + 134 + 90, 82 + 90], ap_ext_space_num6: [520 + 134 + 90 + 90, 82 + 90], ap_ext_space_num1: [520 + 134, 82 + 90 + 90], ap_ext_space_num2: [520 + 134 + 90, 82 + 90 + 90], ap_ext_space_num3: [520 + 134 + 90 + 90, 82 + 90 + 90] }; var key, el; for (var j = 1; j < 10; j++) { key = 'ap_ext_space_num' + j; if (elem.id == key) { elem.style.backgroundImage = "url('" + ap_ext_space.imgURL + "')"; elem.style.backgroundPosition = -pos[key][0] + 'px ' + -pos[key][1] + 'px'; }; }; }, true);  div.addEventListener("mouseout", function(e) { e.preventDefault(); e.stopPropagation();  var elem, evt = e ? e : event; if (evt.srcElement) { elem = evt.srcElement; } else if (evt.target) { elem = evt.target; };  var key, el; for (var j = 1; j < 10; j++) { key = 'ap_ext_space_num' + j; if (elem.id == key) { elem.style.backgroundImage = "none"; }; }; }, true);  div.addEventListener("click", function(e) { e.preventDefault(); e.stopPropagation(); var elem, evt = e ? e : event; if (evt.srcElement) { elem = evt.srcElement; } else if (evt.target) { elem = evt.target; }; ap_ext_space.clickHandler(elem); }, true);  div.addEventListener("touchstart", function(e) { e.preventDefault(); e.stopPropagation(); var elem, evt = e ? e : event; if (evt.srcElement) { elem = evt.srcElement; } else if (evt.target) { elem = evt.target; }; ap_ext_space.clickHandler(elem); }, true);  div.addEventListener("touchend", function(e) { e.preventDefault(); }, true);  div.addEventListener("touchmove", function(e) { e.preventDefault(); }, true);  //зададим позицию меню на экране (по центру) ap_ext_space.menuPos();  }; console.log('all menus:', ap_ext_space.menus); }, 

Если добавлять div-элемент экранного меню к видео таким образом: videoEl.parentNode.appendChild(div), то он будет отображаться поверх видео даже в полноэкранном режиме. Осталось только отцентрировать его, а точнее, сделать это со всеми привязанными к видео-элементам блочными элементами меню (они имеют размер 520×410):

menuPos: function() {  if (ap_ext_space.isFullScreen()) {  var sc = ap_ext_space.scale; var iw = window.innerWidth, ih = window.innerHeight; var w = iw * sc; var h = w / 16 * 9;  for (var i = 0; i < ap_ext_space.menus.length; i++) { ap_ext_space.menus[i].style.marginLeft = (iw - 520) / 2 + 'px'; ap_ext_space.menus[i].style.marginTop = (-h - 410) / 2 + 'px'; };  } else {  ap_ext_space.scale = 1;  for (var i = 0; i < ap_ext_space.menus.length; i++) { ap_ext_space.menus[i].style.marginLeft = '0px'; ap_ext_space.menus[i].style.marginTop = '0px'; }; };  },  isFullScreen: function() { return !!(document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement); },

Кстати, в итоге я решил вообще скрыть меню в оконном режиме и разрешить управление размерами видео только в полноэкранном режиме. В оконном в этом нет смысла.

Обработчики

Здесь, думаю, и так все понятно. На каждую кнопку экранного меню навешены обработчики клика, тача и еще — нажатия соответствующего сочетания клавиш, чтобы управлять видео даже при скрытом меню. Кнопки управляют величинами масштабов: ap_ext_space.scale, ap_ext_space.scalew и ap_ext_space.scaleh, увеличивая или уменьшая эти значения, а затем изменяется размер каждого найденного выше видео-элемента следующим образом:

var sc = ap_ext_space.scale; var iw = window.innerWidth, ih = window.innerHeight; var w = iw * sc; var h = w / 16 * 9;  for (var i = 0; i < ap_ext_space.videos.length; i++) { el = ap_ext_space.videos[i]; el.style.position = 'initial'; el.style.width = (w) + 'px'; el.style.height = (h) + 'px'; el.style.marginLeft = -(w - iw) / 2 + 'px'; el.style.marginTop = -(h - ih) / 2 + 'px'; el.style.transform = 'scaleX(' + ap_ext_space.scalew + ') scaleY(' + ap_ext_space.scaleh + ')'; };

Кроме того, я также повесил на обработчики событий видео seeked, abort, pause, play, playing, seeked на каждый video-элемент (в функции getVideos() выше) вызов единственной функции, которая перерисовывает экранное меню с пересчетом его координат, так как иногда оно «уезжает» при некоторых действиях пользователя. То же сделал и для события изменения размеров окна браузера.

Пространство имен

Вообще, что это за ap_ext_space такой? Дело в том, что все функции, которые используются для изменения размера видео, должны быть внедрены в соответствующую страницу (либо в основную, либо — в iframe). Поэтому я просто объединил эти функции, а также, вместе с ними — и фон экранного меню в формате base64 в единое пространстве имен. Инжектируется все это в код текущей вкладки браузера из бэкграунд-скрипта следующим образом:

var codeString = ap_ext_space_f.toString() + '; ap_ext_space_f(); ap_ext_space.init()'; chrome.tabs.executeScript({ code: codeString });  function ap_ext_space_f() {  ap_ext_space = {  init: function() { //... },  //... };  }; 

Ну а внутри ap_ext_space уже срабатывает поиск всех iframe, затем — всех video внутри каждого из них, строится экранное меню с обработчиками и так далее.

Как пользоваться

Запустить видео. Кликнуть на иконку расширения. Развернуть видео на полный экран. Настраивать масштаб и соотношение сторон. Меню можно скрыть сочетанием клавиш ctrl+0.

Итог

Расширение называется Browser Video Tuner, оно бесплатное и в данный момент доступно в магазинах расширений Chrome и Firefox. Также, его, естественно, можно установить и во все Chrome-совместимые браузеры типа Opera, Yandex Browser и так далее. Стоит отметить, что расширение срабатывает не на всех сайтах с видео. Там, где доступ к iframe-элементам извне защищен политикой безопасности, то ни одного видео просто не будет найдено. И в консоли появится соответствующее предупреждение об этом. Меню в этом случае просто не отобразится. Но на Youtube и на многих онлайн-кинотеатрах все работает. С некоторыми браузерами замечены небольшие проблемы. Например, в Yandex Browser выводимое изображение как-то портится и напоминает сильно пережатый jpeg. Но на функциональность это никак не влияет Я искал способ выводить экранное меню в полноэкранном режиме просто поверх всего документа без внедрения его внутрь iframe-ов, чтобы не зависеть от политики безопасности браузера, и попробовать управлять размерами всего документа в целом, но пока мне это не удалось. Думаю, в дальнейшем расширение будет дополняться новыми функциями.

upd

Благодаря комментариям к статье удалось улучшить расширение. Теперь видео распознается практически на всех сайтах. Для этого после клика на иконке расширения происходит встраивание кода не только в основной документ активной вкладки но и во все ее дочерние элементы iframe. Версия 1.4 для Firefox уже доступна. Эта же версия для Chrome в данный момент находится на модерации.Используемые источники:

  • https://zismo.biz/topic/995884-priblizhenieotdalenie/
  • https://helpx.adobe.com/ru/flash-player/kb/video-playback-issues.html
  • https://habr.com/ru/post/528788/

Оцените статью
Рейтинг автора
5
Материал подготовил
Илья Коршунов
Наш эксперт
Написано статей
134
7th-studio.ru
Добавить комментарий