From a875df7c49d57afef8aec958ec9d0996695ad991 Mon Sep 17 00:00:00 2001 From: Blake Erickson Date: Fri, 17 Mar 2023 16:30:24 -0600 Subject: [PATCH] DEV: Generate video thumbnails from the File object instead of the DOM 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 6520b95f7d..5531f8f4df 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 ce355aeede..9b5856178b 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 92c2cd6062..b94f465f0a 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, });