Readme

A val that you can set up as your webhook endpoint for Mux.com to use CLIP for moderation. This is attempting to use the storyboard image, but so far the results seem pretty subpar.

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
import { addVideo } from "https://esm.town/v/mmcc/muxVideoStorage";
import { email } from "https://esm.town/v/std/email";
import process from "node:process";
import Replicate from "npm:replicate";
const replicate = new Replicate({
auth: process.env.REPLICATE_API_TOKEN,
});
const model = "cjwbw/clip-vit-large-patch14:566ab1f111e526640c5154e712d4d54961414278f89d36590f1425badc763ecb";
// since we're going to try running these prompts on storyboard, we're going
// to preface each prompt with details on being a collection of images.
const storyboardPreface = "a collection of images that include";
const classes = [
["safe", "appropriate content"],
["artistic_nudity", "artistic nudity"],
["pornography", "pornographic imagery"],
["nsfw", "NSFW content"],
["hateful", "hateful symbols"],
];
const prompts = classes.map(c => `${storyboardPreface} ${c[1]}`);
export default async function(req: Request): Promise<Response> {
if (req.method === "GET") {
return Response.json({ nada: true });
}
const hook = await req.json();
if (hook.type !== "video.asset.ready") {
return Response.json({ message: "Hey thanks, but ignoring this one." });
}
const playbackId = hook.data.playback_ids[0].id;
const output = await replicate.run(
model,
{
input: {
text: prompts.join(" | "),
image: `https://image.mux.com/${playbackId}/storyboard.jpg`,
},
},
);
const combinedObject = classes.reduce((obj, key, index) => {
obj[key[0]] = output[index];
return obj;
}, {});
console.log(combinedObject);
// await email({
// text: `
// Hey a new video just came in, here's the moderation report:
// Asset ID: ${hook.data.id}
// Playback ID: ${playbackId}
// ${classes.map((c, i) => `${c[0]}: ${output[i]}`).join("\n")}
// `,
// });
try {
await addVideo(hook.data, combinedObject);
} catch (err) {
// If something blew up at some point, we could end up in a situation where this has been saved...
console.log(err);
}
return Response.json({ ok: true });
}
👆 This is a val. Vals are TypeScript snippets of code, written in the browser and run on our servers. Create scheduled functions, email yourself, and persist small pieces of data — all from the browser.