Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support higher quality Vimeo thumbnails #57

Merged
merged 10 commits into from Apr 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions codeispoetry.php
Expand Up @@ -4,15 +4,15 @@
* Plugin URI: https://www.kweber.com/lazy-load-videos/
* Description: Lazy Load for Videos speeds up your site by replacing embedded Youtube and Vimeo videos with a clickable preview image. Visitors simply click on the image to play the video.
* Author: Kevin Weber
* Version: 2.14.0
* Version: 2.15.0
* Author URI: https://www.kweber.com/
* License: GPL v3
* Text Domain: lazy-load-for-videos
* Domain Path: /languages/
*/

/*
Copyright (C) 2020 Kevin Weber
Copyright (C) 2021 Kevin Weber

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -33,7 +33,7 @@
}

if (!defined('LL_VERSION'))
define('LL_VERSION', '2.14.0');
define('LL_VERSION', '2.15.0');
if (!defined('LL_VERSION_KEY'))
define('LL_VERSION_KEY', LL_OPTION_KEY.'_version');

Expand Down
29,302 changes: 17,760 additions & 11,542 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions public/js/editor.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/js/lazyload-vimeo.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion readme.txt
Expand Up @@ -5,7 +5,7 @@ Tags: youtube, vimeo, performance, oembed, seo, media, gdpr, admin, plugin, cont
Requires at least: 5.6
Tested up to: 5.7.1
Requires PHP: 7.2
Stable tag: 2.14.0
Stable tag: 2.15.0
License: GPL v3
License URI: https://www.gnu.org/copyleft/gpl.html

Expand Down Expand Up @@ -152,6 +152,11 @@ Note that playlists are not working when you're using the pre-/post-roll feature

== Changelog ==

= 2.15.0 =
* New feature: Set Vimeo thumbnail quality. The thumbnail quality option was previously limited to only Youtube and is now used for both Youtube and Vimeo.
* Increase minimum Vimeo thumbnail width to 640px for a better resolution by default
* Remove legacy "window.showThumb" Vimeo thumbnail fallback

= 2.14.0 =
* New feature: Enable Youtube cookies. This option causes videos to be loaded using "youtube.com" instead of the default "youtube-nocookie.com"
* Disable plugin on AMP pages. Thanks to @mjaschen's [PR](https://github.com/kevinweber/lazy-load-for-videos/pull/54)
Expand Down
66 changes: 36 additions & 30 deletions src/frontend/lazyload-vimeo/lazyloadVimeo.js
Expand Up @@ -12,17 +12,6 @@ import findElements from '../shared-utils/findElements';
* by Kevin Weber (www.kweber.com)
*/

/** Deprecated. Will rework in next major release. */
window.showThumb = (data) => {
const relevantData = data[0];

if (window.llvConfig.vimeo.loadthumbnail) {
findElements(`[id="${relevantData.id}"]`).forEach((domItem) => {
setBackgroundImage(domItem, relevantData.thumbnail_large);
});
}
};

// Classes
const classPreviewVimeo = 'preview-vimeo';

Expand All @@ -31,6 +20,7 @@ const defaultPluginOptions = {
buttonstyle: '',
playercolour: '',
loadthumbnail: true,
thumbnailquality: false,
// callback: null, // <- Currently not supported
};

Expand All @@ -48,8 +38,36 @@ function filterDotHash(variable) {
return filterdothash;
}

function generateVimeoCallbackUrl(thumbnailId) {
return `https://vimeo.com/api/v2/video/${thumbnailId}.json`;
function processThumbnail(url) {
if (!url) return '';

// If a URL looks like 'https://i.vimeocdn.com/video/12345_295x166.jpg',
// this RegExp returns '_295x166.', otherwise null.
const sizeString = url.match(/_\d+x\d+\./);
if (sizeString) {
const [width, height] = sizeString[0].match(/\d+/g); // => [295, 166]

// Sizes we support:
// Basic (standard) -> 640
// Medium (higher quality) -> 1280
// Max -> Don't set size in URL
//
// Based on: https://developer.vimeo.com/api/oembed/videos
// "The width of the video's thumbnail image in pixels, settable to the following values:
// 100, 200, 295, 640, 960, and 1280. For any other value, we return a thumbnail at the
// next smallest width."
const urls = {
// Note: The keys in this map ("basic" etc.) need to directly map to the values set
// in the settings for "thumbnailquality"
basic: url.replace(sizeString, `_${640}x${Math.round(height * (640 / width))}.`),
medium: url.replace(sizeString, `_${1280}x${Math.round(height * (1280 / width))}.`),
max: url.replace(sizeString, '.'),
};

return urls[pluginOptions.thumbnailquality] || urls.basic;
}

return url;
}

function vimeoLoadingThumb(videoLinkElement, id) {
Expand All @@ -59,18 +77,12 @@ function vimeoLoadingThumb(videoLinkElement, id) {
videoLinkElement.appendChild(playButtonDiv);

if (window.llvConfig.vimeo.loadthumbnail) {
const videoThumbnail = videoLinkElement.getAttribute(
const videoThumbnail = processThumbnail(videoLinkElement.getAttribute(
'data-video-thumbnail',
);
));

if (videoThumbnail) {
inViewOnce(findElements(`[id="${id}"]`), (element) => setBackgroundImage(element, videoThumbnail));
} else {
const script = document.createElement('script');
script.src = `${generateVimeoCallbackUrl(id)}.json?callback=showThumb`;
videoLinkElement.parentNode.insertBefore(
script,
videoLinkElement.firstChild,
);
}
}

Expand All @@ -95,17 +107,11 @@ function vimeoLoadingThumb(videoLinkElement, id) {
function vimeoCreateThumbProcess(videoLinkElement) {
const previewItem = videoLinkElement;
const vid = previewItem.getAttribute('id');

// There was a bug for Vimeo URLs with a query param in it that wasn't filtered out by
// the PHP code. This filtering ensures we only pick the video ID without any query params.
// Note to future self: If you see this filter still in June 2020, feel free to remove it.
// By now it should be fine to rely only on the server-side filtering.
const [filteredVideoId] = vid.match(/[\w]+/);
previewItem.setAttribute('id', filteredVideoId);
previewItem.setAttribute('id', vid);

// Remove no longer needed title (title is necessary for preview in text editor)
previewItem.innerHTML = '';
vimeoLoadingThumb(previewItem, filteredVideoId);
vimeoLoadingThumb(previewItem, vid);

const showOverlayText = pluginOptions.overlaytext.length > 0;
const videoInfoExtra = createElements(
Expand Down