Files
Video-encoder-still-effed/src/main.ts
T

125 lines
3.1 KiB
TypeScript

import { parseArgs } from "@std/cli";
import { exists } from "@std/fs";
import { resolve } from "@std/path";
import {
OMDBMovieInfo,
OMDBSeriesInfo,
parsedVideoInfo,
VideoInfo,
} from "./types.ts";
import { VideoParser } from "./videoParser.ts";
import { encodingCommandBuilder } from "./commandBuilder.ts";
function analyzeVideo(videoFile: string): VideoInfo {
const cmd = "ffprobe";
const args = [
"-v",
"quiet",
"-print_format",
"json",
"-show_format",
"-show_streams",
videoFile,
];
const process = new Deno.Command(cmd, { args });
const { stdout } = process.outputSync();
const videoInfo = JSON.parse(new TextDecoder().decode(stdout));
return videoInfo;
}
function buildVideoInfo(
videoInfo: VideoInfo,
movieInfo?: OMDBMovieInfo | OMDBSeriesInfo,
): parsedVideoInfo {
const parser = new VideoParser(videoInfo);
if (movieInfo) {
parser.metadata = {
title: movieInfo.Title,
date_released: movieInfo.Released,
imdb_id: movieInfo.imdbID,
};
}
return parser.parse();
}
async function fetchMovieInfo(
imdbID: string,
apiKey: string,
): Promise<OMDBMovieInfo | OMDBSeriesInfo> {
const response = await fetch(
`https://www.omdbapi.com/?i=${imdbID}&apikey=${apiKey}`,
);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const movieInfo = await response.json();
if (movieInfo.Response === "False") {
throw new Error(movieInfo.Error);
}
return movieInfo;
}
async function writeShellScript(command: string) {
if (await exists("./encode.sh")) {
let counter = 1;
while (true) {
if (await exists(`./encode_${counter}.sh`)) {
counter++;
} else {
break;
}
}
Deno.writeTextFileSync(`./encode_${counter}.sh`, command);
console.log(`Created ./encode_${counter}.sh`);
return;
}
const script = `#!/bin/bash\n${command}`;
Deno.writeTextFileSync("./encode.sh", script);
}
async function main() {
// Parse arguments
const args = parseArgs(Deno.args);
if (!args.i) {
console.log("Usage: deno run main.ts -i <video_file>");
Deno.exit(1);
}
if (!args.k) {
const confirm = prompt(
"No key entered. Are you sure you want to continue? (y/N)",
);
if (confirm !== "y") {
Deno.exit(1);
}
}
// Check if file exists
const videoFile: string = String(args.i);
if (!await exists(videoFile)) {
console.log("File does not exist");
Deno.exit(1);
}
// Analyze video
const videoInfo = analyzeVideo(videoFile);
videoInfo.format.filename = resolve(videoFile);
if (args.k) {
const imdbID = prompt("Enter IMDb ID. Leave empty to skip");
let jsonVideoInfo;
if (imdbID) {
const movieInfo = await fetchMovieInfo(imdbID, args.k);
jsonVideoInfo = buildVideoInfo(videoInfo, movieInfo);
} else {
jsonVideoInfo = buildVideoInfo(videoInfo);
}
const command = encodingCommandBuilder(jsonVideoInfo);
await writeShellScript(command);
} else {
const jsonVideoInfo = buildVideoInfo(videoInfo);
const command = encodingCommandBuilder(jsonVideoInfo);
await writeShellScript(command);
}
}
if (import.meta.main) {
main();
}