Vimeo 視頻無法加到商品描述裡
In Magento 2, You can upload youtube and vimeo video in product add or edit section.
But we are getting some issue while uploading vimeo video in magento 2 from recent changes in vimeo video api calling that why when we try to upload vimeo video we are getting “Video not found” error.
How to fix vimeo video not found error in Magento 2?
Recently, vimeo api updated to their ends points that why we are unable to upload vimeo video in magento 2.
For fixing this issue you need to update end points inside following location:vendor\magento\module-product-video\view\adminhtml\web\js\get-video-information.js
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
define([
'jquery',
'Magento_Ui/js/modal/alert',
'jquery/ui',
'mage/translate'
], function ($, alert) {
'use strict';
var videoRegister = {
_register: {},
/**
* Checks, if api is already registered
*
* @param {String} api
* @returns {bool}
*/
isRegistered: function (api) {
return this._register[api] !== undefined;
},
/**
* Checks, if api is loaded
*
* @param {String} api
* @returns {bool}
*/
isLoaded: function (api) {
return this._register[api] !== undefined && this._register[api] === true;
},
/**
* Register new video api
* @param {String} api
* @param {bool} loaded
*/
register: function (api, loaded) {
loaded = loaded || false;
this._register[api] = loaded;
}
};
$.widget('mage.productVideoLoader', {
/**
* @private
*/
_create: function () {
switch (this.element.data('type')) {
case 'youtube':
this.element.videoYoutube();
this._player = this.element.data('mageVideoYoutube');
break;
case 'vimeo':
this.element.videoVimeo();
this._player = this.element.data('mageVideoVimeo');
break;
default:
throw {
name: $.mage.__('Video Error'),
message: $.mage.__('Unknown video type'),
/**
* Return string
*/
toString: function () {
return this.name + ': ' + this.message;
}
};
}
},
/**
* Initializes variables
* @private
*/
_initialize: function () {
this._params = this.element.data('params') || {};
this._code = this.element.data('code');
this._width = this.element.data('width');
this._height = this.element.data('height');
this._autoplay = !!this.element.data('autoplay');
this._playing = this._autoplay || false;
this.useYoutubeNocookie = this.element.data('youtubenocookie') || false;
this._responsive = this.element.data('responsive') !== false;
if (this._responsive === true) {
this.element.addClass('responsive');
}
this._calculateRatio();
},
/**
* Abstract play command
*/
play: function () {
this._player.play();
},
/**
* Abstract pause command
*/
pause: function () {
this._player.pause();
},
/**
* Abstract stop command
*/
stop: function () {
this._player.stop();
},
/**
* Abstract playing command
*/
playing: function () {
return this._player.playing();
},
/**
* Abstract destroying command
*/
destroy: function () {
if (this._player) {
this._player.destroy();
}
},
/**
* Calculates ratio for responsive videos
* @private
*/
_calculateRatio: function () {
if (!this._responsive) {
return;
}
this.element.css('paddingBottom', this._height / this._width * 100 + '%');
}
});
$.widget('mage.videoYoutube', $.mage.productVideoLoader, {
/**
* Initialization of the Youtube widget
* @private
*/
_create: function () {
var self = this;
this._initialize();
this.element.append('<div/>');
this._on(window, {
/**
* Youtube state check
* @private
*/
'youtubeapiready': function () {
var host = 'https://www.youtube.com';
if (self.useYoutubeNocookie) {
host = 'https://www.youtube-nocookie.com';
}
if (self._player !== undefined) {
return;
}
if (self._autoplay) {
self._params.autoplay = 1;
}
self._params.rel = 0;
self._player = new window.YT.Player(self.element.children(':first')[0], {
height: self._height,
width: self._width,
videoId: self._code,
playerVars: self._params,
host: host,
events: {
/**
* @private
*/
'onReady': function onPlayerReady() {
self._player.getDuration();
},
/**
* State change flag init
*/
onStateChange: function (data) {
switch (window.parseInt(data.data, 10)) {
case 1:
self._playing = true;
break;
default:
self._playing = false;
break;
}
self._trigger('statechange', {}, data);
}
}
});
}
});
this._loadApi();
},
/**
* Loads Youtube API and triggers event, when loaded
* @private
*/
_loadApi: function () {
var element,
scriptTag;
if (videoRegister.isRegistered('youtube')) {
if (videoRegister.isLoaded('youtube')) {
$(window).trigger('youtubeapiready');
}
return;
}
videoRegister.register('youtube');
element = document.createElement('script');
scriptTag = document.getElementsByTagName('script')[0];
element.async = true;
element.src = 'https://www.youtube.com/iframe_api';
scriptTag.parentNode.insertBefore(element, scriptTag);
/**
* Trigger youtube api ready event
*/
window.onYouTubeIframeAPIReady = function () {
$(window).trigger('youtubeapiready');
videoRegister.register('youtube', true);
};
},
/**
* Play command for Youtube
*/
play: function () {
this._player.playVideo();
this._playing = true;
},
/**
* Pause command for Youtube
*/
pause: function () {
this._player.pauseVideo();
this._playing = false;
},
/**
* Stop command for Youtube
*/
stop: function () {
this._player.stopVideo();
this._playing = false;
},
/**
* Playing command for Youtube
*/
playing: function () {
return this._playing;
},
/**
* stops and unloads player
* @private
*/
destroy: function () {
this.stop();
if (this._player) {
this._player.destroy();
}
}
});
$.widget('mage.videoVimeo', $.mage.productVideoLoader, {
/**
* Initialize the Vimeo widget
* @private
*/
_create: function () {
var timestamp,
src,
additionalParams;
this._initialize();
timestamp = new Date().getTime();
if (this._autoplay) {
additionalParams += '&autoplay=1';
}
src = 'https://player.vimeo.com/video/' +
this._code + '?api=1&player_id=vimeo' +
this._code +
timestamp +
additionalParams;
this.element.append(
$('<iframe/>')
.attr('frameborder', 0)
.attr('id', 'vimeo' + this._code + timestamp)
.attr('width', this._width)
.attr('height', this._height)
.attr('src', src)
);
}
});
$.widget('mage.videoData', {
options: {
youtubeKey: '',
eventSource: '' //where is data going from - focus out or click on button
},
_REQUEST_VIDEO_INFORMATION_TRIGGER: 'request_video_information',
_UPDATE_VIDEO_INFORMATION_TRIGGER: 'updated_video_information',
_START_UPDATE_INFORMATION_TRIGGER: 'update_video_information',
_ERROR_UPDATE_INFORMATION_TRIGGER: 'error_updated_information',
_FINISH_UPDATE_INFORMATION_TRIGGER: 'finish_update_information',
_VIDEO_URL_VALIDATE_TRIGGER: 'validate_video_url',
_videoInformation: null,
_currentVideoUrl: null,
/**
* @private
*/
_init: function () {
this.element.on(this._START_UPDATE_INFORMATION_TRIGGER, $.proxy(this._onRequestHandler, this));
this.element.on(this._ERROR_UPDATE_INFORMATION_TRIGGER, $.proxy(this._onVideoInvalid, this));
this.element.on(this._FINISH_UPDATE_INFORMATION_TRIGGER, $.proxy(
function () {
this._currentVideoUrl = null;
}, this
));
this.element.on(this._VIDEO_URL_VALIDATE_TRIGGER, $.proxy(this._onUrlValidateHandler, this));
},
/**
* @private
*/
_onUrlValidateHandler: function (event, callback, forceVideo) {
var url = this.element.val(),
videoInfo;
videoInfo = this._validateURL(url, forceVideo);
if (videoInfo) {
callback();
} else {
this._onRequestError($.mage.__('Invalid video url'));
}
},
/**
* @private
*/
_onRequestHandler: function () {
var url = this.element.val(),
self = this,
videoInfo,
type,
id,
googleapisUrl;
if (this._currentVideoUrl === url) {
return;
}
this._currentVideoUrl = url;
this.element.trigger(this._REQUEST_VIDEO_INFORMATION_TRIGGER, {
url: url
});
if (!url) {
return;
}
videoInfo = this._validateURL(url);
if (!videoInfo) {
this._onRequestError($.mage.__('Invalid video url'));
return;
}
/**
*
* @param {Object} data
* @private
*/
function _onYouTubeLoaded(data) {
var tmp,
uploadedFormatted,
respData,
createErrorMessage;
/**
* Create errors message
*
* @returns {String}
*/
createErrorMessage = function () {
var error = data.error,
errors = error.errors,
i,
errLength = errors.length,
tmpError,
errReason,
errorsMessage = [];
for (i = 0; i < errLength; i++) {
tmpError = errors[i];
errReason = tmpError.reason;
if (['keyInvalid'].indexOf(errReason) !== -1) {
errorsMessage.push($.mage.__('Youtube API key is invalid'));
break;
}
errorsMessage.push(tmpError.message);
}
return $.mage.__('Video cant be shown due to the following reason: ') +
$.unique(errorsMessage).join(', ');
};
if (data.error && [400, 402, 403].indexOf(data.error.code) !== -1) {
this._onRequestError(createErrorMessage());
return;
}
if (!data.items || data.items.length < 1) {
this._onRequestError($.mage.__('Video not found'));
return;
}
tmp = data.items[0];
uploadedFormatted = tmp.snippet.publishedAt.replace('T', ' ').replace(/\..+/g, '');
respData = {
duration: this._formatYoutubeDuration(tmp.contentDetails.duration),
channel: tmp.snippet.channelTitle,
channelId: tmp.snippet.channelId,
uploaded: uploadedFormatted,
title: tmp.snippet.localized.title,
description: tmp.snippet.description,
thumbnail: tmp.snippet.thumbnails.high.url,
videoId: videoInfo.id,
videoProvider: videoInfo.type,
useYoutubeNocookie: videoInfo.useYoutubeNocookie
};
this._videoInformation = respData;
this.element.trigger(this._UPDATE_VIDEO_INFORMATION_TRIGGER, respData);
this.element.trigger(this._FINISH_UPDATE_INFORMATION_TRIGGER, true);
}
/**
* @private
*/
function _onVimeoLoaded(data) {
var tmp,
respData;
if (!data) {
this._onRequestError($.mage.__('Video not found'));
return null;
}
tmp = data;
respData = {
duration: this._formatVimeoDuration(tmp.duration),
channel: tmp['author_name'],
channelId: tmp['author_url'],
uploaded: tmp['upload_date'],
title: tmp.title,
description: tmp.description.replace(/( |<([^>]+)>)/ig, ''),
thumbnail: tmp['thumbnail_url'],
videoId: videoInfo.id,
videoProvider: videoInfo.type
};
this._videoInformation = respData;
this.element.trigger(this._UPDATE_VIDEO_INFORMATION_TRIGGER, respData);
this.element.trigger(this._FINISH_UPDATE_INFORMATION_TRIGGER, true);
}
type = videoInfo.type;
id = videoInfo.id;
if (type === 'youtube') {
googleapisUrl = 'https://www.googleapis.com/youtube/v3/videos?id=' +
id +
'&part=snippet,contentDetails&key=' +
this.options.youtubeKey + '&alt=json&callback=?';
$.getJSON(googleapisUrl,
{
format: 'json'
},
$.proxy(_onYouTubeLoaded, self)
).fail(
function () {
self._onRequestError('Video not found');
}
);
} else if (type === 'vimeo') {
$.ajax({
url: 'https://vimeo.com/api/oembed.json',
dataType: 'jsonp',
data: {
format: 'json',
url: 'https://vimeo.com/' + id
},
timeout: 5000,
success: $.proxy(_onVimeoLoaded, self),
/**
* @private
*/
error: function () {
self._onRequestError($.mage.__('Video not found'));
}
});
}
},
/**
* @private
*/
_onVideoInvalid: function (event, data) {
this._videoInformation = null;
this.element.val('');
alert({
content: 'Error: "' + data + '"'
});
},
/**
* @private
*/
_onRequestError: function (error) {
this.element.trigger(this._ERROR_UPDATE_INFORMATION_TRIGGER, error);
this.element.trigger(this._FINISH_UPDATE_INFORMATION_TRIGGER, false);
this._currentVideoUrl = null;
},
/**
* @private
*/
_formatYoutubeDuration: function (duration) {
var match = duration.match(/PT(\d+H)?(\d+M)?(\d+S)?/),
hours = parseInt(match[1], 10) || 0,
minutes = parseInt(match[2], 10) || 0,
seconds = parseInt(match[3], 10) || 0;
return this._formatVimeoDuration(hours * 3600 + minutes * 60 + seconds);
},
/**
* @private
*/
_formatVimeoDuration: function (seconds) {
return (new Date(seconds * 1000)).toUTCString().match(/(\d\d:\d\d:\d\d)/)[0];
},
/**
* @private
*/
_parseHref: function (href) {
var a = document.createElement('a');
a.href = href;
return a;
},
/**
* @private
*/
_validateURL: function (href, forceVideo) {
var id,
type,
ampersandPosition,
vimeoRegex,
useYoutubeNocookie = false;
if (typeof href !== 'string') {
return href;
}
href = this._parseHref(href);
if (href.host.match(/youtube\.com/) && href.search) {
id = href.search.split('v=')[1];
if (id) {
ampersandPosition = id.indexOf('&');
type = 'youtube';
}
if (id && ampersandPosition !== -1) {
id = id.substring(0, ampersandPosition);
}
} else if (href.host.match(/youtube\.com|youtu\.be|youtube-nocookie.com/)) {
id = href.pathname.replace(/^\/(embed\/|v\/)?/, '').replace(/\/.*/, '');
type = 'youtube';
if (href.host.match(/youtube-nocookie.com/)) {
useYoutubeNocookie = true;
}
} else if (href.host.match(/vimeo\.com/)) {
type = 'vimeo';
vimeoRegex = new RegExp(['https?:\\/\\/(?:www\\.|player\\.)?vimeo.com\\/(?:channels\\/(?:\\w+\\/)',
'?|groups\\/([^\\/]*)\\/videos\\/|album\\/(\\d+)\\/video\\/|video\\/|)(\\d+)(?:$|\\/|\\?)'
].join(''));
if (href.href.match(vimeoRegex) != null) {
id = href.href.match(vimeoRegex)[3];
}
}
if ((!id || !type) && forceVideo) {
id = href.href;
type = 'custom';
}
return id ? {
id: id, type: type, s: href.search.replace(/^\?/, ''), useYoutubeNocookie: useYoutubeNocookie
} : false;
}
});
});