125 lines
3.1 KiB
TypeScript
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();
|
|
}
|