1import * as GCP from "@/GCP";
2import * as Effect from "effect/Effect";
3import { serveProbes } from "../../bindingHost.ts";
4
5const sdConfig: GCP.Transcoder.JobConfig = {
6 elementaryStreams: [
7 {
8 key: "video-stream0",
9 videoStream: {
10 h264: {
11 heightPixels: 360,
12 widthPixels: 640,
13 bitrateBps: 550000,
14 frameRate: 30,
15 },
16 },
17 },
18 {
19 key: "audio-stream0",
20 audioStream: { codec: "aac", bitrateBps: 64000 },
21 },
22 ],
23 muxStreams: [
24 {
25 key: "sd",
26 container: "mp4",
27 elementaryStreams: ["video-stream0", "audio-stream0"],
28 },
29 ],
30};
31
32export const Template = GCP.Transcoder.JobTemplate("WebSd", {
33 location: "us-central1",
34 config: sdConfig,
35});
36
37export const Media = GCP.Storage.Bucket("Media", {
38 location: "US-CENTRAL1",
39 forceDestroy: true,
40});
41
42/**
43 * Effect-native Cloud Run service exercising the Transcoder binding as its
44 * own runtime service account. Deployed from {@link ../Bindings.test.ts}.
45 */
46export default class TranscoderBindingsHost extends GCP.Function<TranscoderBindingsHost>()(
47 "TranscoderBindingsHost",
48 { main: import.meta.url, invokerIamDisabled: true },
49 Effect.gen(function* () {
50 const createJob = yield* GCP.Transcoder.CreateJob(Template);
51 const media = yield* Media;
52 const bucketName = yield* media.bucketName;
53
54 return {
55 fetch: serveProbes({
56 createJob: Effect.gen(function* () {
57 const bucket = yield* bucketName;
58 const job = yield* createJob({
59 body: {
60 inputUri: `gs://${bucket}/inputs/file.mp4`,
61 outputUri: `gs://${bucket}/outputs/`,
62 ttlAfterCompletionDays: 1,
63 },
64 });
65 return {
66 name: job.name,
67 muxStreams: (job.config?.muxStreams ?? []).map(
68 (stream) => stream.key,
69 ),
70 };
71 }),
72 }),
73 };
74 }).pipe(Effect.provide(GCP.Transcoder.CreateJobHttp)),
75) {}