aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Wilkins <samwilkins333@gmail.com>2020-05-18 16:43:14 -0700
committerSam Wilkins <samwilkins333@gmail.com>2020-05-18 16:43:14 -0700
commitf52b7a81059c0b50ad6f56928adb057bf6902493 (patch)
treea2f6ffad8e739c4e007c0f6609e2ac30029533e9 /src
parentda7ba72e8c75dfaa9920920b8234d99f699578a8 (diff)
youtube screenshot integration tested
Diffstat (limited to 'src')
-rw-r--r--src/client/views/nodes/VideoBox.tsx40
-rw-r--r--src/server/ApiManagers/UploadManager.ts53
2 files changed, 52 insertions, 41 deletions
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index bcbd65258..6ec48ca89 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -22,6 +22,7 @@ import { InkingControl } from "../InkingControl";
import { FieldView, FieldViewProps } from './FieldView';
import "./VideoBox.scss";
import { documentSchema } from "../../../fields/documentSchemas";
+import { Networking } from "../../Network";
const path = require('path');
export const timeSchema = createSchema({
@@ -118,29 +119,38 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
b.isLinkButton = true;
this.props.addDocument?.(b);
DocUtils.MakeLink({ doc: b }, { doc: this.rootDoc }, "video snapshot");
+ Networking.PostToServer("/youtubeScreenshot", {
+ id: this.youtubeVideoId,
+ timecode: this.layoutDoc.currentTimecode
+ }).then(response => {
+ this.props.removeDocument?.(b);
+ this.createRealSummaryLink(response.accessPaths.agnostic.client);
+ });
} else {
//convert to desired file format
const dataUrl = canvas.toDataURL('image/png'); // can also use 'image/png'
// if you want to preview the captured image,
const filename = path.basename(encodeURIComponent("snapshot" + StrCast(this.rootDoc.title).replace(/\..*$/, "") + "_" + (this.layoutDoc.currentTimecode || 0).toString().replace(/\./, "_")));
- VideoBox.convertDataUri(dataUrl, filename).then(returnedFilename => {
- if (returnedFilename) {
- const url = this.choosePath(Utils.prepend(returnedFilename));
- const imageSummary = Docs.Create.ImageDocument(url, {
- _nativeWidth: this.layoutDoc._nativeWidth, _nativeHeight: this.layoutDoc._nativeHeight,
- x: (this.layoutDoc.x || 0) + width, y: (this.layoutDoc.y || 0),
- _width: 150, _height: height / width * 150, title: "--snapshot" + (this.layoutDoc.currentTimecode || 0) + " image-"
- });
- Doc.GetProto(imageSummary)["data-nativeWidth"] = this.layoutDoc._nativeWidth;
- Doc.GetProto(imageSummary)["data-nativeHeight"] = this.layoutDoc._nativeHeight;
- imageSummary.isLinkButton = true;
- this.props.addDocument?.(imageSummary);
- DocUtils.MakeLink({ doc: imageSummary }, { doc: this.rootDoc }, "video snapshot");
- }
- });
+ VideoBox.convertDataUri(dataUrl, filename).then(this.createRealSummaryLink);
}
}
+ private createRealSummaryLink = (relative: string) => {
+ const url = this.choosePath(Utils.prepend(relative));
+ const width = (this.layoutDoc._width || 0);
+ const height = (this.layoutDoc._height || 0);
+ const imageSummary = Docs.Create.ImageDocument(url, {
+ _nativeWidth: this.layoutDoc._nativeWidth, _nativeHeight: this.layoutDoc._nativeHeight,
+ x: (this.layoutDoc.x || 0) + width, y: (this.layoutDoc.y || 0),
+ _width: 150, _height: height / width * 150, title: "--snapshot" + (this.layoutDoc.currentTimecode || 0) + " image-"
+ });
+ Doc.GetProto(imageSummary)["data-nativeWidth"] = this.layoutDoc._nativeWidth;
+ Doc.GetProto(imageSummary)["data-nativeHeight"] = this.layoutDoc._nativeHeight;
+ imageSummary.isLinkButton = true;
+ this.props.addDocument?.(imageSummary);
+ DocUtils.MakeLink({ doc: imageSummary }, { doc: this.rootDoc }, "video snapshot");
+ }
+
@action
updateTimecode = () => {
this.player && (this.layoutDoc.currentTimecode = this.player.currentTime);
diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts
index 06c2e516d..1ab81803f 100644
--- a/src/server/ApiManagers/UploadManager.ts
+++ b/src/server/ApiManagers/UploadManager.ts
@@ -68,34 +68,34 @@ export default class UploadManager extends ApiManager {
method: Method.POST,
subscription: new RouteSubscriber("youtubeScreenshot"),
secureHandler: async ({ req, res }) => {
- const { url, t } = req.query;
- const parseUrl = (url: string) => {
- url = decodeURIComponent(url)
- if (!/^(?:f|ht)tps?\:\/\//.test(url)) {
- url = 'http://' + url
- }
- return url;
- }
- let targetUrl: string;
- if (!url || !t || !isWebUri(targetUrl = parseUrl(url as string))) {
- return res.send();
- }
- const buffer = await captureYoutubeScreenshot(targetUrl, t as string);
+ const { id, timecode } = req.body;
+ const convert = (raw: string) => {
+ const number = Math.floor(Number(raw));
+ const seconds = number % 60;
+ const minutes = (number - seconds) / 60;
+ return `${minutes}m${seconds}s`;
+ };
+ const suffix = timecode ? `&t=${convert(timecode)}` : ``;
+ const targetUrl = `https://www.youtube.com/watch?v=${id}${suffix}`;
+ const buffer = await captureYoutubeScreenshot(targetUrl);
if (!buffer) {
return res.send();
}
- const resolvedName = `${targetUrl}@${t}.png`;
+ const resolvedName = `youtube_capture_${id}_${suffix}.png`;
const resolvedPath = serverPathToFile(Directory.images, resolvedName);
- writeFile(resolvedPath, buffer, async error => {
- if (error) {
- return res.send();
- }
- await DashUploadUtils.outputResizedImages(() => createReadStream(resolvedPath), resolvedName, pathToDirectory(Directory.images));
- res.send({
- accessPaths: {
- agnostic: DashUploadUtils.getAccessPaths(Directory.images, resolvedName)
+ return new Promise<void>(resolve => {
+ writeFile(resolvedPath, buffer, async error => {
+ if (error) {
+ return res.send();
}
- } as Upload.FileInformation);
+ await DashUploadUtils.outputResizedImages(() => createReadStream(resolvedPath), resolvedName, pathToDirectory(Directory.images));
+ res.send({
+ accessPaths: {
+ agnostic: DashUploadUtils.getAccessPaths(Directory.images, resolvedName)
+ }
+ } as Upload.FileInformation);
+ resolve();
+ });
});
}
});
@@ -284,17 +284,18 @@ export default class UploadManager extends ApiManager {
*
* On failure, returns undefined.
*/
-async function captureYoutubeScreenshot(targetUrl: string, t: string): Promise<Opt<Buffer>> {
+async function captureYoutubeScreenshot(targetUrl: string): Promise<Opt<Buffer>> {
const browser = await launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] });
const page = await browser.newPage();
await page.setViewport({ width: 1920, height: 1080 });
- await page.goto(targetUrl + '&t=' + t, { waitUntil: 'networkidle0' });
+ await page.goto(targetUrl, { waitUntil: 'networkidle0' });
// hide youtube player controls.
await page.evaluate(() => (document.querySelector('.ytp-chrome-bottom') as any).style.display = 'none');
- const buffer = await (await page.$('.html5-video-player'))?.screenshot({ encoding: "binary" });
+ const videoPlayer = await page.$('.html5-video-player');
+ const buffer = await videoPlayer?.screenshot({ encoding: "binary" });
await browser.close();
return buffer;