diff options
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/ApiManagers/UploadManager.ts | 2 | ||||
| -rw-r--r-- | src/server/DashUploadUtils.ts | 48 | ||||
| -rw-r--r-- | src/server/SharedMediaTypes.ts | 38 |
3 files changed, 60 insertions, 28 deletions
diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts index 787e331c5..0b6e18743 100644 --- a/src/server/ApiManagers/UploadManager.ts +++ b/src/server/ApiManagers/UploadManager.ts @@ -86,7 +86,7 @@ export default class UploadManager extends ApiManager { const videoId = JSON.parse(payload).videoId; const results: Upload.FileResponse[] = []; const result = await DashUploadUtils.uploadYoutube(videoId); - result && !(result.result instanceof Error) && results.push(result); + result && results.push(result); _success(res, results); resolve(); }); diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts index ef7192ecc..28e26e51e 100644 --- a/src/server/DashUploadUtils.ts +++ b/src/server/DashUploadUtils.ts @@ -17,8 +17,6 @@ import { resolvedServerUrl } from './server_Initialization'; import { AcceptableMedia, Upload } from './SharedMediaTypes'; import request = require('request-promise'); import formidable = require('formidable'); -import { file } from 'jszip'; -import { csvParser } from './DataVizUtils'; const { exec } = require('child_process'); const parse = require('pdf-parse'); const ffmpeg = require('fluent-ffmpeg'); @@ -102,16 +100,41 @@ export namespace DashUploadUtils { } export function uploadYoutube(videoId: string): Promise<Upload.FileResponse> { - console.log('UPLOAD ' + videoId); return new Promise<Upload.FileResponse<Upload.FileInformation>>((res, rej) => { - exec('youtube-dl -o ' + (videoId + '.mp4') + ' https://www.youtube.com/watch?v=' + videoId + ' -f "best[filesize<50M]"', (error: any, stdout: any, stderr: any) => { - if (error) console.log(`error: ${error.message}`); - else if (stderr) console.log(`stderr: ${stderr}`); - else { - console.log(`stdout: ${stdout}`); - const data = { size: 0, path: videoId + '.mp4', name: videoId, type: 'video/mp4' }; - const file = { ...data, toJSON: () => ({ ...data, filename: data.path.replace(/.*\//, ''), mtime: null, length: 0, mime: '', toJson: () => undefined as any }) }; - res(MoveParsedFile(file, Directory.videos)); + console.log('Uploading YouTube video: ' + videoId); + exec('youtube-dl -o ' + (videoId + '.mp4') + ' ' + videoId + ' -f "bestvideo[filesize<5M]+bestaudio/bestvideo+bestaudio"', (error: any, stdout: any, stderr: any) => { + if (error) { + console.log(`error: Error: ${error.message}`); + res({ + source: { + size: 0, + path: videoId, + name: videoId, + type: '', + toJSON: () => ({ name: videoId, path: videoId }), + }, + result: { name: 'failed youtube query', message: `Could not upload YouTube video (${videoId}). Error: ${error.message}` }, + }); + } else if (stderr) { + console.log(`stderr: StdError: ${stderr}`); + res({ + source: { + size: 0, + path: videoId, + name: videoId, + type: '', + toJSON: () => ({ name: videoId, path: videoId }), + }, + result: { name: 'failed youtube query', message: `Could not upload YouTube video (${videoId}). Error: ${stderr}` }, + }); + } else { + exec('youtube-dl -o ' + (videoId + '.mp4') + ' ' + videoId + ' --get-duration', (error: any, stdout: any, stderr: any) => { + const time = Array.from(stdout.trim().split(':')).reverse(); + const duration = (time.length > 2 ? Number(time[2]) * 1000 * 60 : 0) + (time.length > 1 ? Number(time[1]) * 60 : 0) + (time.length > 0 ? Number(time[0]) : 0); + const data = { size: 0, path: videoId + '.mp4', name: videoId, type: 'video/mp4' }; + const file = { ...data, toJSON: () => ({ ...data, filename: data.path.replace(/.*\//, ''), mtime: duration.toString(), mime: '', toJson: () => undefined as any }) }; + res(MoveParsedFile(file, Directory.videos)); + }); } }); }); @@ -352,7 +375,7 @@ export namespace DashUploadUtils { * @param suffix If the file doesn't have a suffix and you want to provide it one * to appear in the new location */ - export async function MoveParsedFile(file: formidable.File, destination: Directory, suffix: string | undefined = undefined, text?: string): Promise<Upload.FileResponse> { + export async function MoveParsedFile(file: formidable.File, destination: Directory, suffix: string | undefined = undefined, text?: string, duration?: number): Promise<Upload.FileResponse> { const { path: sourcePath } = file; let name = path.basename(sourcePath); suffix && (name += suffix); @@ -368,6 +391,7 @@ export namespace DashUploadUtils { agnostic: getAccessPaths(destination, name), }, rawText: text, + duration, }, }); }); diff --git a/src/server/SharedMediaTypes.ts b/src/server/SharedMediaTypes.ts index cde95526f..7db1c2dae 100644 --- a/src/server/SharedMediaTypes.ts +++ b/src/server/SharedMediaTypes.ts @@ -2,36 +2,45 @@ import { ExifData } from 'exif'; import { File } from 'formidable'; export namespace AcceptableMedia { - export const gifs = [".gif"]; - export const pngs = [".png"]; - export const jpgs = [".jpg", ".jpeg"]; - export const webps = [".webp"]; - export const tiffs = [".tiff"]; + export const gifs = ['.gif']; + export const pngs = ['.png']; + export const jpgs = ['.jpg', '.jpeg']; + export const webps = ['.webp']; + export const tiffs = ['.tiff']; export const imageFormats = [...pngs, ...jpgs, ...gifs, ...webps, ...tiffs]; - export const videoFormats = [".mov", ".mp4", ".quicktime", ".mkv", ".x-matroska;codecs=avc1"]; - export const applicationFormats = [".pdf"]; - export const audioFormats = [".wav", ".mp3", ".mpeg", ".flac", ".au", ".aiff", ".m4a", ".webm"]; + export const videoFormats = ['.mov', '.mp4', '.quicktime', '.mkv', '.x-matroska;codecs=avc1']; + export const applicationFormats = ['.pdf']; + export const audioFormats = ['.wav', '.mp3', '.mpeg', '.flac', '.au', '.aiff', '.m4a', '.webm']; } export namespace Upload { - export function isImageInformation(uploadResponse: Upload.FileInformation): uploadResponse is Upload.ImageInformation { - return "nativeWidth" in uploadResponse; + return 'nativeWidth' in uploadResponse; + } + + export function isVideoInformation(uploadResponse: Upload.FileInformation): uploadResponse is Upload.VideoInformation { + return 'duration' in uploadResponse; } export interface FileInformation { accessPaths: AccessPathInfo; rawText?: string; + duration?: number; } - export type FileResponse<T extends FileInformation = FileInformation> = { source: File, result: T | Error }; + export type FileResponse<T extends FileInformation = FileInformation> = { source: File; result: T | Error }; export type ImageInformation = FileInformation & InspectionResults; + export type VideoInformation = FileInformation & VideoResults; + export interface AccessPathInfo { - [suffix: string]: { client: string, server: string }; + [suffix: string]: { client: string; server: string }; } + export interface VideoResults { + duration: number; + } export interface InspectionResults { source: string; requestable: string; @@ -44,8 +53,7 @@ export namespace Upload { } export interface EnrichedExifData { - data: ExifData & ExifData["gps"]; + data: ExifData & ExifData['gps']; error?: string; } - -}
\ No newline at end of file +} |
