From 62e7c7212612722aa7cf0306b70e0f6a21e71d3d Mon Sep 17 00:00:00 2001 From: Blake Erickson Date: Mon, 20 Mar 2023 13:40:14 -0600 Subject: [PATCH] DEV: Generate video thumbnails from the File object instead of the DOM (#20696) In order to avoid built in browser CORS issues and sites that are using CDNs this change allows us to generate thumbnail images from videos directly from the File uploaded instead of reading the already uploaded file via the `video` tag. Follow-up to: f144c64e139e41f176ea2ec3433a468fa49b955f --- .../app/components/composer-editor.js | 2 -- .../app/mixins/composer-upload-uppy.js | 5 +++ .../mixins/composer-video-thumbnail-uppy.js | 34 +++++-------------- 3 files changed, 13 insertions(+), 28 deletions(-) diff --git a/app/assets/javascripts/discourse/app/components/composer-editor.js b/app/assets/javascripts/discourse/app/components/composer-editor.js index 6520b95f7db..5531f8f4df0 100644 --- a/app/assets/javascripts/discourse/app/components/composer-editor.js +++ b/app/assets/javascripts/discourse/app/components/composer-editor.js @@ -937,8 +937,6 @@ export default Component.extend( // Short upload urls need resolution resolveAllShortUrls(ajax, this.siteSettings, preview); - this._generateVideoThumbnail(); - preview.addEventListener("click", this._handleImageScaleButtonClick); this._registerImageAltTextButtonClick(preview); diff --git a/app/assets/javascripts/discourse/app/mixins/composer-upload-uppy.js b/app/assets/javascripts/discourse/app/mixins/composer-upload-uppy.js index ce355aeede3..9b5856178b2 100644 --- a/app/assets/javascripts/discourse/app/mixins/composer-upload-uppy.js +++ b/app/assets/javascripts/discourse/app/mixins/composer-upload-uppy.js @@ -325,6 +325,11 @@ export default Mixin.create(ExtendableUploader, UppyS3Multipart, { cacheShortUploadUrl(upload.short_url, upload); + // video/mp4, video/webm, video/quicktime, etc. + if (file.type.split("/")[0] === "video") { + this._generateVideoThumbnail(file, upload.url); + } + if (this.useUploadPlaceholders) { this.appEvents.trigger( `${this.composerEventPrefix}:replace-text`, diff --git a/app/assets/javascripts/discourse/app/mixins/composer-video-thumbnail-uppy.js b/app/assets/javascripts/discourse/app/mixins/composer-video-thumbnail-uppy.js index 92c2cd6062e..b94f465f0a1 100644 --- a/app/assets/javascripts/discourse/app/mixins/composer-video-thumbnail-uppy.js +++ b/app/assets/javascripts/discourse/app/mixins/composer-video-thumbnail-uppy.js @@ -17,30 +17,12 @@ export default Mixin.create(ExtendableUploader, UppyS3Multipart, { useUploadPlaceholders: true, @bind - _generateVideoThumbnail() { - if (!this.siteSettings.enable_diffhtml_preview) { - return; - } + _generateVideoThumbnail(videoFile, uploadUrl) { + let video = document.createElement("video"); + video.src = URL.createObjectURL(videoFile.data); - let videos = document.getElementsByClassName("video-container"); - if (!videos) { - return; - } - - // Only generate a topic thumbnail for the first video - let video_container = videos[0]; - if (!video_container) { - return; - } - - let video = video_container.querySelector("video:first-of-type"); - if (!video) { - return; - } - - let video_src = video.getElementsByTagName("source")[0].src; - let video_sha1 = video_src - .substring(video_src.lastIndexOf("/") + 1) + let videoSha1 = uploadUrl + .substring(uploadUrl.lastIndexOf("/") + 1) .split(".")[0]; // Wait for the video element to load, otherwise the canvas will be empty @@ -58,10 +40,10 @@ export default Mixin.create(ExtendableUploader, UppyS3Multipart, { // upload video thumbnail canvas.toBlob((blob) => { this._uppyInstance = new Uppy({ - id: `screenshot-placeholder`, + id: "video-thumbnail", meta: { upload_type: `thumbnail`, - video_sha1, + videoSha1, }, autoProceed: true, }); @@ -99,7 +81,7 @@ export default Mixin.create(ExtendableUploader, UppyS3Multipart, { try { this._uppyInstance.addFile({ source: `${this.id} thumbnail`, - name: video_sha1, + name: `${videoSha1}`, type: blob.type, data: blob, });