Public
Script
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Readme

Video Storage

Intended to be imported into other Vals and used with Mux Webhooks (like our webhookHandler. Stores videos off into Sqlite.

Webhook handlers

At least these are how we use them in the webhookHandler

FunctionMux EventNote
createVideo()video.upload.createdTriggered when a direct upload is initially created
updateVideoCreated()video.upload.asset_createdTriggered when an asset is created
updateVideoReady()video.asset.readyAn asset is ready for playback

Others

  • getAllVideos Lists all the videos in the database
  • backfillVideo Takes a video object and puts it in the DB. Useful if you're iterating over to...you guessed it, backfill content.
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
import { sqlite } from "https://esm.town/v/std/sqlite";
import Mux from "npm:@mux/mux-node";
// await sqlite.execute(`DROP TABLE videos;`);
await sqlite.execute(`create table if not exists videos(
id text unique,
upload_id text unique,
created_at text,
uploaded_at text,
ready_at text,
status text,
playback_ids json,
duration integer,
resolution_tier text,
encoding_tier text,
max_stored_frame_rate integer,
aspect_ratio text,
tracks json,
non_standard_input_reasons json,
environment_id text,
environment_name text
)`);
export function rowObjects(data) {
return data.rows.map(row => {
return data.columns.reduce((obj, column, index) => {
let value;
if (data.columnTypes[index] === "json") {
value = JSON.parse(row[index]);
} else {
value = row[index];
}
obj[column] = value;
return obj;
}, {});
});
}
export async function createVideo(webhook: Mux.Webhooks.VideoUploadCreatedWebhookEvent) {
const {
environment,
data: {
id,
},
} = webhook;
return await sqlite.execute({
sql: `insert into videos(
upload_id,
created_at,
environment_id,
environment_name
)
values (
:id,
datetime('now'),
:environment_id,
:environment_name
)`,
args: {
id,
environment_id: environment.id,
environment_name: environment.name,
},
});
}
export async function updateVideoCreated(webhook: Mux.Webhooks.VideoUploadAssetCreatedWebhookEvent) {
const sql = `
UPDATE videos
SET
id = :id,
uploaded_at = datetime("now")
WHERE upload_id = :upload_id;`;
const {
data: {
id,
asset_id,
},
} = webhook;
return await sqlite.execute({
sql,
args: {
id: asset_id,
upload_id: id,
},
});
}
// Just returns the sql statement itself so that we can use `batch` in our backfill script.
export function backfillVideo(asset: Mux.Video.Asset) {
const sql = `
INSERT OR IGNORE INTO videos (
id,
upload_id,
status,
created_at,
duration,
resolution_tier,
encoding_tier,
July 18, 2024