-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.ts
113 lines (88 loc) · 4.27 KB
/
main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { crfs } from "./utils.ts"
import { verify, verifyScenes } from "./verify.ts"
import scene_pos from "./scenes.json" assert { type: "json" }
import { encode } from "./encode.ts"
import { analyse } from "./analyse.ts"
import { SegmentLoader } from "./segments.ts"
import { getTaskStream, Task, createTaskRunners } from "./task.ts"
import { parse } from "https://deno.land/[email protected]/flags/mod.ts";
const tasks: Record<string, Task> = {
"encode": encode,
"analyse": analyse,
"verify": async (_key: number, segment: number[], crf: number, _segmentPath: string, _outPath: string, _retries?: number) => { await verify(segment[0], segment[1], crf, flags.outPath) }
}
const task: Task = tasks[Deno.args[0]] || encode
const videoPath = Deno.args[1] || '/Users/benja/Downloads/vid_comp/video.mp4'
const flags = parse(Deno.args, {
boolean: ["server"],
string: ["runners", "cacheDir", "outPath"],
alias: {
s: "server",
r: "runners"
},
default: {
runners: "8",
cacheDir: "segments",
outPath: "encodes"
// outPath: task === encode ? "encodes" : "analyses"
}
})
// docker run -v /local/scratch/hongbenj/encodes:/app/encodes -v /local/scratch/hongbenj:/local -v analyses:/app/analyses encode analyse /local/video.mp4 --cacheDir /local/cache
const numRunners = Number(flags.runners)
console.log("Flags:", flags)
const segmentLoader = new SegmentLoader(videoPath, flags.cacheDir)
const videoInfo = await segmentLoader.videoInfo
console.log("Video info:", videoInfo)
const scenes = scene_pos.map((a: number, i: number) => [a, scene_pos[i + 1] || videoInfo.frames])
const started = (await Promise.all(scenes.map(async scene => await Deno.stat(`${flags.outPath}/${scene[0]}`).catch(() => { }) && scene))).filter(a => a) as number[][]
const encodeReg = /^\d+.webm$/
const completed = started.filter(scene => [...Deno.readDirSync(`${flags.outPath}/${scene[0]}`)].filter(file => encodeReg.test(file.name)).length === crfs.length)
const semiCompleted = started.filter(scene => !completed.includes(scene))
const startedAnalyse = (await Promise.all(scenes.map(async scene => await Deno.stat(`analyses/${scene[0]}`).catch(() => { }) && scene))).filter(a => a) as number[][]
const analyseReg = /^\d+.json$/
const completedAnalyse = startedAnalyse.filter(scene => [...Deno.readDirSync(`analyses/${scene[0]}`)].filter(file => analyseReg.test(file.name)).length === crfs.length)
console.log("Scenes completed:", completed)
console.log("Scenes semi-completed:", semiCompleted)
const toVerify = [completed[completed.length - 1], ...semiCompleted].filter(a => a)
const toEncode = [...await verifyScenes(toVerify, flags.outPath), ...scenes.filter(scene => !completed.includes(scene))]
// const toEncode = []
console.log("Encode queue:", toEncode)
await Deno.mkdir("encodes").catch(() => { })
// const encodeQueue = {
// [tasks.encode]: toEncode,
// [tasks.analyse]: [...scenes.filter(scene => !toEncode.includes(scene) && !completedAnalyse.includes(scene))].reverse(),
// [tasks.verify]: toEncode
// }[task]
const encodeQueue = (() => {
switch (task) {
case tasks.encode:
return toEncode
case tasks.analyse:
return [...scenes.filter(scene => !toEncode.includes(scene) && !completedAnalyse.includes(scene))].reverse()
case tasks.verify:
return [...scenes.filter(scene => !toEncode.includes(scene))].reverse()
default:
return toEncode
}
})()
if (flags.server) {
const server = Deno.listen({ port: 8080 })
for await (const conn of server) {
const httpConn = Deno.serveHttp(conn)
for await (const requestEvent of httpConn) {
requestEvent.respondWith(new Response(JSON.stringify({ encodeQueue, completed, semiCompleted }), {
headers: new Headers({
"content-type": "application/json"
})
}))
}
}
} else {
const taskStream = getTaskStream(task === tasks.verify ? null : segmentLoader, () => encodeQueue.pop(), task, numRunners, flags.outPath)
const taskRunners = createTaskRunners(taskStream, numRunners)
console.log("Running", taskRunners.length, "tasks")
await Promise.all(taskRunners)
console.log("Finished all tasks")
segmentLoader?.cleanup()
}
Deno.exit(0)