Skip to content

Commit

Permalink
Wip
Browse files Browse the repository at this point in the history
  • Loading branch information
uasan committed May 19, 2024
1 parent 2516a8f commit 5145399
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 11 deletions.
9 changes: 8 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
export * from './src/interfaces/server/app.ts';
export * from './src/interfaces/server/cache.ts';
export * from './src/interfaces/server/context.ts';

export * from './src/interfaces/migration/context.js';
export * from './src/interfaces/server/cache.ts';

export * from './src/interfaces/security/WebAuthn.js';
export * from './src/interfaces/security/Challenge.ts';
export * from './src/interfaces/security/decorators.ts';

export * from './src/interfaces/types/Blob.ts';
export * from './src/interfaces/types/File.ts';
export * from './src/interfaces/types/Validators.ts';

export * from './src/interfaces/postgres/model.ts';
export * from './src/interfaces/postgres/decorators.ts';

export * from './src/interfaces/utils/io.ts';

export * from './src/interfaces/media/video.ts';

export * from './src/interfaces/exceptions/BadRequest.ts';
export * from './src/interfaces/exceptions/Conflict.ts';
export * from './src/interfaces/exceptions/ContentTooLarge.ts';
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/entities/api/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export function makeRouteMethod(name, node) {
}

if (isVoidLikeType(returnType)) {
(ast = factoryStatement(ast)), internals.respondNoContent(res);
ast = internals.respondNoContent(res, ast);
} else if (File.isAssignable(returnType)) {
ast = internals.respondFile(res, ast);
} else if (BinaryData.isAssignable(returnType) || isStringType(returnType)) {
Expand Down
19 changes: 19 additions & 0 deletions src/interfaces/media/video.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
interface VideoInfo {
size: number;
width: number;
height: number;
duration: number;
}

interface ConvertVideoOptions {
type?: 'AV1';
poster?: string;
maxWidth: number;
maxHeight: number;
}

export declare function convertVideo(
source: string,
target: string,
options: ConvertVideoOptions
): Promise<VideoInfo>;
5 changes: 1 addition & 4 deletions src/interfaces/security/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,4 @@ import type { ServerContext } from '../server/context.ts';

export declare function Permission(
rule: (context: ServerContext, payload?: any) => Promise<boolean>
): (
target: (payload?: any) => any,
context: ClassMethodDecoratorContext
) => void;
): (target: unknown, context: ClassMethodDecoratorContext) => void;
5 changes: 1 addition & 4 deletions src/interfaces/server/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,4 @@ interface CacheOptions {

export declare function Cache(
options: boolean | number | CacheOptions
): (
target: (payload?: any) => any,
context: ClassMethodDecoratorContext
) => void;
): (target: unknown, context: ClassMethodDecoratorContext) => void;
78 changes: 78 additions & 0 deletions src/runtime/media/video.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { IO, env } from '#utils/io.js';
import { UnProcessable } from '../exceptions/UnProcessable.js';

const PATH_FFMPEG = env.PATH_FFMPEG || 'ffmpeg';
const PATH_FFPROBE = env.PATH_FFPROBE || 'ffprobe';

export async function getVideoInfo(path) {
const { streams } = JSON.parse(
await IO.exec(
`${PATH_FFPROBE} -v error -print_format json -show_streams -select_streams v "${path}"`
)
);

if (streams?.length) {
return streams[0];
} else {
throw new UnProcessable('Not found video streams');
}
}

export async function convertVideo(source, target, options) {
let { width, height, duration: ds } = await getVideoInfo(source);
let duration = Math.round(Number(ds));

let cmd = PATH_FFMPEG + ' -i "' + source + '" -v error';

if (width > options.maxWidth || height > options.maxHeight) {
if (width > height) {
height = Math.round(options.maxHeight / (width / height));
width = options.maxWidth;

cmd += ' -vf "scale=' + width + ':-1"';
} else {
width = Math.round(options.maxWidth / (height / width));
height = options.maxHeight;

cmd += ' -vf "scale=-1:' + height + '"';
}
}

if (options.type === 'AV1') {
cmd += ' -c:v libsvtav1';
cmd += ' -preset 10';
cmd += ' -crf 36';
cmd += ' -pix_fmt yuv420p10le';
cmd += ' -svtav1-params fast-decode=1';
} else {
cmd += ' -c:v copy';
}

cmd += ' -c:a copy';
cmd += ' -y "' + target + '"';

await IO.exec(cmd);

if (options.poster) {
const time = duration / 10;

await IO.exec(
`${PATH_FFMPEG} -y -v error -ss ${time} -i "${target}" -frames:v 1 "${options.poster}"`
);
}

return { width, height, duration, size: IO.getFileSize(target) };
}

// console.log(
// await convertVideo(
// '/Users/oleksiiskydan/Desktop/Labs/Files/2.mp4',
// '/Users/oleksiiskydan/Desktop/Labs/Files/aa.mkv',
// {
// type: 'AV1',
// maxWidth: 1280,
// maxHeight: 1280,
// poster: '/Users/oleksiiskydan/Desktop/Labs/Files/aa.avif',
// }
// )
// );
17 changes: 16 additions & 1 deletion src/runtime/utils/io.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { Buffer } from 'node:buffer';
import { Writable } from 'node:stream';
import { createWriteStream } from 'node:fs';
import { exec } from 'node:child_process';
import { statSync, createWriteStream } from 'node:fs';
import { TransformStream } from 'node:stream/web';
import { open as openFile, rename as moveFile } from 'node:fs/promises';
import { randomUUID, createHash, webcrypto as crypto } from 'node:crypto';

export { env } from 'node:process';

export const getRandomString = length =>
Buffer.from(crypto.getRandomValues(new Uint8Array(length)))
.toString('base64url')
Expand All @@ -22,6 +25,7 @@ export const IO = {
),

getTempFileName: () => join(tmpdir(), randomUUID()),
getFileSize: path => statSync(path).size,

createFileWriteStream: (path, options) =>
Writable.toWeb(createWriteStream(path, options)),
Expand All @@ -38,4 +42,15 @@ export const IO = {

return hash;
},

exec(command, options) {
return {
then(resolve, reject) {
exec(command, options, (error, stdout) => {
if (error) reject(error);
else resolve(stdout);
});
},
};
},
};

0 comments on commit 5145399

Please sign in to comment.