@editframe/api 0.8.0-beta.4 → 0.8.0-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CHUNK_SIZE_BYTES.d.ts +1 -0
- package/dist/CHUNK_SIZE_BYTES.js +7 -0
- package/dist/client.d.ts +0 -2
- package/dist/client.js +2 -14
- package/dist/client.test.d.ts +1 -0
- package/dist/readableFromBuffers.d.ts +2 -0
- package/dist/resources/caption-file.d.ts +22 -3
- package/dist/resources/caption-file.js +28 -26
- package/dist/resources/caption-file.test.d.ts +1 -0
- package/dist/resources/image-file.d.ts +5 -3
- package/dist/resources/image-file.js +23 -27
- package/dist/resources/image-file.test.d.ts +1 -0
- package/dist/resources/isobmff-file.d.ts +2 -3
- package/dist/resources/isobmff-file.js +17 -23
- package/dist/resources/isobmff-file.test.d.ts +1 -0
- package/dist/resources/isobmff-track.d.ts +27 -28
- package/dist/resources/isobmff-track.js +18 -31
- package/dist/resources/isobmff-track.test.d.ts +1 -0
- package/dist/resources/renders.d.ts +4 -5
- package/dist/resources/renders.js +17 -21
- package/dist/resources/renders.test.d.ts +1 -0
- package/dist/resources/unprocessed-file.d.ts +14 -12
- package/dist/resources/unprocessed-file.js +36 -45
- package/dist/resources/unprocessed-file.test.d.ts +1 -0
- package/dist/resources/url-token.d.ts +0 -1
- package/dist/resources/url-token.test.d.ts +1 -0
- package/dist/streamChunker.d.ts +2 -0
- package/dist/streamChunker.js +17 -0
- package/dist/streamChunker.test.d.ts +1 -0
- package/dist/uploadChunks.d.ts +10 -0
- package/dist/uploadChunks.js +65 -0
- package/dist/uploadChunks.test.d.ts +1 -0
- package/package.json +4 -3
- package/src/resources/caption-file.test.ts +124 -0
- package/src/resources/caption-file.ts +49 -24
- package/src/resources/image-file.test.ts +138 -0
- package/src/resources/image-file.ts +28 -25
- package/src/resources/isobmff-file.test.ts +108 -0
- package/src/resources/isobmff-file.ts +19 -22
- package/src/resources/isobmff-track.test.ts +152 -0
- package/src/resources/isobmff-track.ts +22 -31
- package/src/resources/renders.test.ts +112 -0
- package/src/resources/renders.ts +19 -20
- package/src/resources/test-av-file.txt +1 -0
- package/src/resources/unprocessed-file.test.ts +312 -0
- package/src/resources/unprocessed-file.ts +41 -44
- package/src/resources/url-token.test.ts +46 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare let CHUNK_SIZE_BYTES: number;
|
package/dist/client.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { RequestInit } from 'node-fetch';
|
|
2
|
-
import * as jwt from "jsonwebtoken";
|
|
3
2
|
export declare class Client {
|
|
4
3
|
#private;
|
|
5
4
|
constructor(token: string, efHost?: string);
|
|
6
5
|
authenticatedFetch: (path: string, init?: RequestInit) => Promise<import('node-fetch').Response>;
|
|
7
|
-
sign(payload: Record<string, unknown>, expiresIn?: Parameters<typeof jwt.sign>[2]["expiresIn"]): string;
|
|
8
6
|
}
|
package/dist/client.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import debug from "debug";
|
|
2
|
-
import * as jwt from "jsonwebtoken";
|
|
3
2
|
import fetch from "node-fetch";
|
|
4
3
|
const log = debug("ef:api:client");
|
|
5
4
|
class Client {
|
|
@@ -9,7 +8,7 @@ class Client {
|
|
|
9
8
|
const url = new URL(path, this.#efHost);
|
|
10
9
|
log(
|
|
11
10
|
"Authenticated fetch",
|
|
12
|
-
{ url, init },
|
|
11
|
+
{ url: url.toString(), init },
|
|
13
12
|
"(Token will be added as Bearer token)"
|
|
14
13
|
);
|
|
15
14
|
Object.assign(init.headers, {
|
|
@@ -25,22 +24,11 @@ class Client {
|
|
|
25
24
|
this.#efHost = efHost;
|
|
26
25
|
const { apiKey, apiSecret } = token.match(/^(?<apiSecret>ef_[^_]+)_(?<apiKey>.+)$/)?.groups ?? {};
|
|
27
26
|
if (!apiKey || !apiSecret) {
|
|
28
|
-
throw new Error("Invalid token format");
|
|
27
|
+
throw new Error("Invalid token format. Must look like: ef_{}_{}");
|
|
29
28
|
}
|
|
30
|
-
this.#apiKey = apiKey;
|
|
31
|
-
this.#apiSecret = apiSecret;
|
|
32
29
|
}
|
|
33
|
-
#apiKey;
|
|
34
|
-
#apiSecret;
|
|
35
30
|
#token;
|
|
36
31
|
#efHost;
|
|
37
|
-
sign(payload, expiresIn = 60) {
|
|
38
|
-
payload.cid = this.#apiKey;
|
|
39
|
-
return jwt.sign(payload, this.#apiSecret, {
|
|
40
|
-
algorithm: "HS256",
|
|
41
|
-
expiresIn
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
32
|
}
|
|
45
33
|
export {
|
|
46
34
|
Client
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,20 +1,39 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { Client } from '../client.ts';
|
|
4
|
-
|
|
5
4
|
export declare const CreateCaptionFilePayload: z.ZodObject<{
|
|
6
5
|
id: z.ZodString;
|
|
7
6
|
filename: z.ZodString;
|
|
7
|
+
byte_size: z.ZodNumber;
|
|
8
8
|
}, "strip", z.ZodTypeAny, {
|
|
9
9
|
id: string;
|
|
10
10
|
filename: string;
|
|
11
|
+
byte_size: number;
|
|
11
12
|
}, {
|
|
12
13
|
id: string;
|
|
13
14
|
filename: string;
|
|
15
|
+
byte_size: number;
|
|
14
16
|
}>;
|
|
15
17
|
export interface CreateCaptionFileResult {
|
|
16
18
|
complete: boolean | null;
|
|
17
19
|
id: string;
|
|
18
20
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Create a caption file
|
|
23
|
+
* @param client - The authenticated client to use for the request
|
|
24
|
+
* @param payload - The payload to send to the server
|
|
25
|
+
* @returns The result of the request
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* const result = await createCaptionFile(client, {
|
|
29
|
+
* id: "123",
|
|
30
|
+
* filename: "caption.srt",
|
|
31
|
+
* });
|
|
32
|
+
* console.log(result);
|
|
33
|
+
* ```
|
|
34
|
+
* @category CaptionFile
|
|
35
|
+
* @resource
|
|
36
|
+
* @beta
|
|
37
|
+
*/
|
|
38
|
+
export declare const createCaptionFile: (client: Client, payload: z.infer<typeof CreateCaptionFilePayload>) => Promise<CreateCaptionFileResult>;
|
|
39
|
+
export declare const uploadCaptionFile: (client: Client, fileId: string, fileStream: Readable, fileSize: number) => Promise<unknown>;
|
|
@@ -1,53 +1,55 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import debug from "debug";
|
|
3
3
|
const log = debug("ef:api:caption-file");
|
|
4
|
+
const MAX_CAPTION_SIZE = 1024 * 1024 * 2;
|
|
4
5
|
const CreateCaptionFilePayload = z.object({
|
|
5
6
|
id: z.string(),
|
|
6
|
-
filename: z.string()
|
|
7
|
+
filename: z.string(),
|
|
8
|
+
byte_size: z.number().int().max(MAX_CAPTION_SIZE)
|
|
7
9
|
});
|
|
10
|
+
const restrictSize = (size) => {
|
|
11
|
+
if (size > MAX_CAPTION_SIZE) {
|
|
12
|
+
throw new Error(
|
|
13
|
+
`File size ${size} bytes exceeds limit ${MAX_CAPTION_SIZE} bytes
|
|
14
|
+
`
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
8
18
|
const createCaptionFile = async (client, payload) => {
|
|
9
19
|
log("Creating caption file", payload);
|
|
10
|
-
|
|
20
|
+
restrictSize(payload.byte_size);
|
|
21
|
+
const response = await client.authenticatedFetch(
|
|
11
22
|
"/api/video2/caption_files",
|
|
12
23
|
{
|
|
13
24
|
method: "POST",
|
|
14
25
|
body: JSON.stringify(payload)
|
|
15
26
|
}
|
|
16
27
|
);
|
|
17
|
-
log("Caption file created",
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return await fileCreation.json();
|
|
21
|
-
}
|
|
22
|
-
default: {
|
|
23
|
-
console.error(
|
|
24
|
-
`Failed to create file ${fileCreation.status} ${fileCreation.statusText}`
|
|
25
|
-
);
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
+
log("Caption file created", response);
|
|
29
|
+
if (response.ok) {
|
|
30
|
+
return await response.json();
|
|
28
31
|
}
|
|
32
|
+
throw new Error(
|
|
33
|
+
`Failed to create caption ${response.status} ${response.statusText}`
|
|
34
|
+
);
|
|
29
35
|
};
|
|
30
|
-
const uploadCaptionFile = async (client, fileId, fileStream) => {
|
|
36
|
+
const uploadCaptionFile = async (client, fileId, fileStream, fileSize) => {
|
|
31
37
|
log("Uploading caption file", fileId);
|
|
32
|
-
|
|
38
|
+
restrictSize(fileSize);
|
|
39
|
+
const response = await client.authenticatedFetch(
|
|
33
40
|
`/api/video2/caption_files/${fileId}/upload`,
|
|
34
41
|
{
|
|
35
42
|
method: "POST",
|
|
36
43
|
body: fileStream
|
|
37
44
|
}
|
|
38
45
|
);
|
|
39
|
-
log("Caption file uploaded",
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return fileIndex.json();
|
|
43
|
-
}
|
|
44
|
-
default: {
|
|
45
|
-
console.error(
|
|
46
|
-
`Failed to upload caption ${fileIndex.status} ${fileIndex.statusText}`
|
|
47
|
-
);
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
46
|
+
log("Caption file uploaded", response);
|
|
47
|
+
if (response.ok) {
|
|
48
|
+
return response.json();
|
|
50
49
|
}
|
|
50
|
+
throw new Error(
|
|
51
|
+
`Failed to upload caption ${response.status} ${response.statusText}`
|
|
52
|
+
);
|
|
51
53
|
};
|
|
52
54
|
export {
|
|
53
55
|
CreateCaptionFilePayload,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { Client } from '../client.ts';
|
|
4
|
-
|
|
5
4
|
export declare const CreateImageFilePayload: z.ZodObject<{
|
|
6
5
|
id: z.ZodString;
|
|
7
6
|
height: z.ZodNumber;
|
|
8
7
|
width: z.ZodNumber;
|
|
9
8
|
mime_type: z.ZodEnum<["image/jpeg", "image/png", "image/jpg", "image/webp"]>;
|
|
10
9
|
filename: z.ZodString;
|
|
10
|
+
byte_size: z.ZodNumber;
|
|
11
11
|
}, "strip", z.ZodTypeAny, {
|
|
12
12
|
id: string;
|
|
13
13
|
filename: string;
|
|
14
|
+
byte_size: number;
|
|
14
15
|
height: number;
|
|
15
16
|
width: number;
|
|
16
17
|
mime_type: "image/jpeg" | "image/png" | "image/jpg" | "image/webp";
|
|
17
18
|
}, {
|
|
18
19
|
id: string;
|
|
19
20
|
filename: string;
|
|
21
|
+
byte_size: number;
|
|
20
22
|
height: number;
|
|
21
23
|
width: number;
|
|
22
24
|
mime_type: "image/jpeg" | "image/png" | "image/jpg" | "image/webp";
|
|
@@ -25,5 +27,5 @@ export interface CreateImageFileResult {
|
|
|
25
27
|
complete: boolean | null;
|
|
26
28
|
id: string;
|
|
27
29
|
}
|
|
28
|
-
export declare const createImageFile: (client: Client, payload: z.infer<typeof CreateImageFilePayload>) => Promise<CreateImageFileResult
|
|
29
|
-
export declare const uploadImageFile: (client: Client, fileId: string, fileStream: Readable) => Promise<
|
|
30
|
+
export declare const createImageFile: (client: Client, payload: z.infer<typeof CreateImageFilePayload>) => Promise<CreateImageFileResult>;
|
|
31
|
+
export declare const uploadImageFile: (client: Client, fileId: string, fileStream: Readable, fileSize: number) => Promise<void>;
|
|
@@ -1,49 +1,45 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import debug from "debug";
|
|
3
|
+
import { uploadChunks } from "../uploadChunks.js";
|
|
3
4
|
const log = debug("ef:api:image-file");
|
|
5
|
+
const MAX_IMAGE_SIZE = 1024 * 1024 * 16;
|
|
4
6
|
const CreateImageFilePayload = z.object({
|
|
5
7
|
id: z.string(),
|
|
6
8
|
height: z.number().int(),
|
|
7
9
|
width: z.number().int(),
|
|
8
10
|
mime_type: z.enum(["image/jpeg", "image/png", "image/jpg", "image/webp"]),
|
|
9
|
-
filename: z.string()
|
|
11
|
+
filename: z.string(),
|
|
12
|
+
byte_size: z.number().int().max(MAX_IMAGE_SIZE)
|
|
10
13
|
});
|
|
11
14
|
const createImageFile = async (client, payload) => {
|
|
12
15
|
log("Creating image file", payload);
|
|
16
|
+
CreateImageFilePayload.parse(payload);
|
|
13
17
|
const response = await client.authenticatedFetch("/api/video2/image_files", {
|
|
14
18
|
method: "POST",
|
|
15
19
|
body: JSON.stringify(payload)
|
|
16
20
|
});
|
|
17
21
|
log("Image file created", response);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return await response.json();
|
|
21
|
-
}
|
|
22
|
-
default: {
|
|
23
|
-
console.error(
|
|
24
|
-
`Failed to create file ${response.status} ${response.statusText}`
|
|
25
|
-
);
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
22
|
+
if (response.ok) {
|
|
23
|
+
return await response.json();
|
|
28
24
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const fileIndex = await client.authenticatedFetch(
|
|
32
|
-
`/api/video2/image_files/${fileId}/upload`,
|
|
33
|
-
{
|
|
34
|
-
method: "POST",
|
|
35
|
-
body: fileStream
|
|
36
|
-
}
|
|
25
|
+
throw new Error(
|
|
26
|
+
`Failed to create file ${response.status} ${response.statusText}`
|
|
37
27
|
);
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
28
|
+
};
|
|
29
|
+
const uploadImageFile = async (client, fileId, fileStream, fileSize) => {
|
|
30
|
+
log("Uploading image file", fileId);
|
|
31
|
+
if (fileSize > MAX_IMAGE_SIZE) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
`File size ${fileSize} bytes exceeds limit ${MAX_IMAGE_SIZE} bytes`
|
|
34
|
+
);
|
|
46
35
|
}
|
|
36
|
+
const result = await uploadChunks(client, {
|
|
37
|
+
url: `/api/video2/image_files/${fileId}/upload`,
|
|
38
|
+
fileSize,
|
|
39
|
+
fileStream
|
|
40
|
+
});
|
|
41
|
+
log("Image file upload complete");
|
|
42
|
+
return result;
|
|
47
43
|
};
|
|
48
44
|
export {
|
|
49
45
|
CreateImageFilePayload,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { Client } from '../client.ts';
|
|
4
|
-
|
|
5
4
|
export declare const CreateISOBMFFFilePayload: z.ZodObject<{
|
|
6
5
|
id: z.ZodString;
|
|
7
6
|
filename: z.ZodString;
|
|
@@ -16,5 +15,5 @@ export interface CreateISOBMFFFileResult {
|
|
|
16
15
|
fragment_index_complete: boolean;
|
|
17
16
|
id: string;
|
|
18
17
|
}
|
|
19
|
-
export declare const createISOBMFFFile: (client: Client, payload: z.infer<typeof CreateISOBMFFFilePayload>) => Promise<CreateISOBMFFFileResult
|
|
20
|
-
export declare const uploadFragmentIndex: (client: Client, fileId: string, fileStream: Readable) => Promise<unknown>;
|
|
18
|
+
export declare const createISOBMFFFile: (client: Client, payload: z.infer<typeof CreateISOBMFFFilePayload>) => Promise<CreateISOBMFFFileResult>;
|
|
19
|
+
export declare const uploadFragmentIndex: (client: Client, fileId: string, fileStream: Readable, fileSize: number) => Promise<unknown>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import debug from "debug";
|
|
3
3
|
const log = debug("ef:api:isobmff-file");
|
|
4
|
+
const FILE_SIZE_LIMIT = 1024 * 1024 * 2;
|
|
4
5
|
const CreateISOBMFFFilePayload = z.object({
|
|
5
6
|
id: z.string(),
|
|
6
7
|
filename: z.string()
|
|
@@ -15,39 +16,32 @@ const createISOBMFFFile = async (client, payload) => {
|
|
|
15
16
|
}
|
|
16
17
|
);
|
|
17
18
|
log("ISOBMFF file created", response);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return await response.json();
|
|
21
|
-
}
|
|
22
|
-
default: {
|
|
23
|
-
console.error(
|
|
24
|
-
`Failed to create file ${response.status} ${response.statusText}`
|
|
25
|
-
);
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
19
|
+
if (response.ok) {
|
|
20
|
+
return await response.json();
|
|
28
21
|
}
|
|
22
|
+
throw new Error(
|
|
23
|
+
`Failed to create isobmff file ${response.status} ${response.statusText}`
|
|
24
|
+
);
|
|
29
25
|
};
|
|
30
|
-
const uploadFragmentIndex = async (client, fileId, fileStream) => {
|
|
26
|
+
const uploadFragmentIndex = async (client, fileId, fileStream, fileSize) => {
|
|
31
27
|
log("Uploading fragment index", fileId);
|
|
32
|
-
|
|
28
|
+
if (fileSize > FILE_SIZE_LIMIT) {
|
|
29
|
+
throw new Error(`File size exceeds limit of ${FILE_SIZE_LIMIT} bytes`);
|
|
30
|
+
}
|
|
31
|
+
const response = await client.authenticatedFetch(
|
|
33
32
|
`/api/video2/isobmff_files/${fileId}/index/upload`,
|
|
34
33
|
{
|
|
35
34
|
method: "POST",
|
|
36
35
|
body: fileStream
|
|
37
36
|
}
|
|
38
37
|
);
|
|
39
|
-
log("Fragment index uploaded",
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return fileIndex.json();
|
|
43
|
-
}
|
|
44
|
-
default: {
|
|
45
|
-
console.error(
|
|
46
|
-
`Failed to create fragment index ${fileIndex.status} ${fileIndex.statusText}`
|
|
47
|
-
);
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
38
|
+
log("Fragment index uploaded", response);
|
|
39
|
+
if (response.ok) {
|
|
40
|
+
return response.json();
|
|
50
41
|
}
|
|
42
|
+
throw new Error(
|
|
43
|
+
`Failed to create fragment index ${response.status} ${response.statusText}`
|
|
44
|
+
);
|
|
51
45
|
};
|
|
52
46
|
export {
|
|
53
47
|
CreateISOBMFFFilePayload,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { Client } from '../client.ts';
|
|
4
|
-
|
|
5
4
|
export declare const CreateISOBMFFTrackPayload: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
6
5
|
file_id: z.ZodString;
|
|
7
6
|
track_id: z.ZodNumber;
|
|
@@ -29,7 +28,6 @@ export declare const CreateISOBMFFTrackPayload: z.ZodDiscriminatedUnion<"type",
|
|
|
29
28
|
bit_rate: z.ZodString;
|
|
30
29
|
disposition: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
31
30
|
}, "strip", z.ZodTypeAny, {
|
|
32
|
-
duration: number;
|
|
33
31
|
index: number;
|
|
34
32
|
codec_name: string;
|
|
35
33
|
codec_long_name: string;
|
|
@@ -47,11 +45,11 @@ export declare const CreateISOBMFFTrackPayload: z.ZodDiscriminatedUnion<"type",
|
|
|
47
45
|
start_pts: number;
|
|
48
46
|
start_time: number;
|
|
49
47
|
duration_ts: number;
|
|
48
|
+
duration: number;
|
|
50
49
|
bit_rate: string;
|
|
51
50
|
disposition: Record<string, unknown>;
|
|
52
51
|
initial_padding?: number | undefined;
|
|
53
52
|
}, {
|
|
54
|
-
duration: number;
|
|
55
53
|
index: number;
|
|
56
54
|
codec_name: string;
|
|
57
55
|
codec_long_name: string;
|
|
@@ -69,6 +67,7 @@ export declare const CreateISOBMFFTrackPayload: z.ZodDiscriminatedUnion<"type",
|
|
|
69
67
|
start_pts: number;
|
|
70
68
|
start_time: number;
|
|
71
69
|
duration_ts: number;
|
|
70
|
+
duration: number;
|
|
72
71
|
bit_rate: string;
|
|
73
72
|
disposition: Record<string, unknown>;
|
|
74
73
|
initial_padding?: number | undefined;
|
|
@@ -77,11 +76,12 @@ export declare const CreateISOBMFFTrackPayload: z.ZodDiscriminatedUnion<"type",
|
|
|
77
76
|
codec_name: z.ZodString;
|
|
78
77
|
byte_size: z.ZodNumber;
|
|
79
78
|
}, "strip", z.ZodTypeAny, {
|
|
79
|
+
byte_size: number;
|
|
80
80
|
type: "audio";
|
|
81
|
+
codec_name: string;
|
|
81
82
|
file_id: string;
|
|
82
83
|
track_id: number;
|
|
83
84
|
probe_info: {
|
|
84
|
-
duration: number;
|
|
85
85
|
index: number;
|
|
86
86
|
codec_name: string;
|
|
87
87
|
codec_long_name: string;
|
|
@@ -99,19 +99,19 @@ export declare const CreateISOBMFFTrackPayload: z.ZodDiscriminatedUnion<"type",
|
|
|
99
99
|
start_pts: number;
|
|
100
100
|
start_time: number;
|
|
101
101
|
duration_ts: number;
|
|
102
|
+
duration: number;
|
|
102
103
|
bit_rate: string;
|
|
103
104
|
disposition: Record<string, unknown>;
|
|
104
105
|
initial_padding?: number | undefined;
|
|
105
106
|
};
|
|
106
107
|
duration_ms: number;
|
|
107
|
-
codec_name: string;
|
|
108
|
-
byte_size: number;
|
|
109
108
|
}, {
|
|
109
|
+
byte_size: number;
|
|
110
110
|
type: "audio";
|
|
111
|
+
codec_name: string;
|
|
111
112
|
file_id: string;
|
|
112
113
|
track_id: number;
|
|
113
114
|
probe_info: {
|
|
114
|
-
duration: number;
|
|
115
115
|
index: number;
|
|
116
116
|
codec_name: string;
|
|
117
117
|
codec_long_name: string;
|
|
@@ -129,13 +129,12 @@ export declare const CreateISOBMFFTrackPayload: z.ZodDiscriminatedUnion<"type",
|
|
|
129
129
|
start_pts: number;
|
|
130
130
|
start_time: number;
|
|
131
131
|
duration_ts: number;
|
|
132
|
+
duration: number;
|
|
132
133
|
bit_rate: string;
|
|
133
134
|
disposition: Record<string, unknown>;
|
|
134
135
|
initial_padding?: number | undefined;
|
|
135
136
|
};
|
|
136
137
|
duration_ms: number;
|
|
137
|
-
codec_name: string;
|
|
138
|
-
byte_size: number;
|
|
139
138
|
}>, z.ZodObject<{
|
|
140
139
|
file_id: z.ZodString;
|
|
141
140
|
track_id: z.ZodNumber;
|
|
@@ -161,6 +160,8 @@ export declare const CreateISOBMFFTrackPayload: z.ZodDiscriminatedUnion<"type",
|
|
|
161
160
|
bit_rate: z.ZodOptional<z.ZodString>;
|
|
162
161
|
disposition: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
163
162
|
}, "strip", z.ZodTypeAny, {
|
|
163
|
+
height: number;
|
|
164
|
+
width: number;
|
|
164
165
|
index: number;
|
|
165
166
|
codec_name: string;
|
|
166
167
|
codec_long_name: string;
|
|
@@ -171,16 +172,16 @@ export declare const CreateISOBMFFTrackPayload: z.ZodDiscriminatedUnion<"type",
|
|
|
171
172
|
avg_frame_rate: string;
|
|
172
173
|
time_base: string;
|
|
173
174
|
disposition: Record<string, unknown>;
|
|
174
|
-
width: number;
|
|
175
|
-
height: number;
|
|
176
175
|
coded_width: number;
|
|
177
176
|
coded_height: number;
|
|
178
|
-
duration?: number | undefined;
|
|
179
177
|
start_pts?: number | undefined;
|
|
180
178
|
start_time?: number | undefined;
|
|
181
179
|
duration_ts?: number | undefined;
|
|
180
|
+
duration?: number | undefined;
|
|
182
181
|
bit_rate?: string | undefined;
|
|
183
182
|
}, {
|
|
183
|
+
height: number;
|
|
184
|
+
width: number;
|
|
184
185
|
index: number;
|
|
185
186
|
codec_name: string;
|
|
186
187
|
codec_long_name: string;
|
|
@@ -191,24 +192,26 @@ export declare const CreateISOBMFFTrackPayload: z.ZodDiscriminatedUnion<"type",
|
|
|
191
192
|
avg_frame_rate: string;
|
|
192
193
|
time_base: string;
|
|
193
194
|
disposition: Record<string, unknown>;
|
|
194
|
-
width: number;
|
|
195
|
-
height: number;
|
|
196
195
|
coded_width: number;
|
|
197
196
|
coded_height: number;
|
|
198
|
-
duration?: number | undefined;
|
|
199
197
|
start_pts?: number | undefined;
|
|
200
198
|
start_time?: number | undefined;
|
|
201
199
|
duration_ts?: number | undefined;
|
|
200
|
+
duration?: number | undefined;
|
|
202
201
|
bit_rate?: string | undefined;
|
|
203
202
|
}>;
|
|
204
203
|
duration_ms: z.ZodNumber;
|
|
205
204
|
codec_name: z.ZodString;
|
|
206
205
|
byte_size: z.ZodNumber;
|
|
207
206
|
}, "strip", z.ZodTypeAny, {
|
|
207
|
+
byte_size: number;
|
|
208
208
|
type: "video";
|
|
209
|
+
codec_name: string;
|
|
209
210
|
file_id: string;
|
|
210
211
|
track_id: number;
|
|
211
212
|
probe_info: {
|
|
213
|
+
height: number;
|
|
214
|
+
width: number;
|
|
212
215
|
index: number;
|
|
213
216
|
codec_name: string;
|
|
214
217
|
codec_long_name: string;
|
|
@@ -219,24 +222,24 @@ export declare const CreateISOBMFFTrackPayload: z.ZodDiscriminatedUnion<"type",
|
|
|
219
222
|
avg_frame_rate: string;
|
|
220
223
|
time_base: string;
|
|
221
224
|
disposition: Record<string, unknown>;
|
|
222
|
-
width: number;
|
|
223
|
-
height: number;
|
|
224
225
|
coded_width: number;
|
|
225
226
|
coded_height: number;
|
|
226
|
-
duration?: number | undefined;
|
|
227
227
|
start_pts?: number | undefined;
|
|
228
228
|
start_time?: number | undefined;
|
|
229
229
|
duration_ts?: number | undefined;
|
|
230
|
+
duration?: number | undefined;
|
|
230
231
|
bit_rate?: string | undefined;
|
|
231
232
|
};
|
|
232
233
|
duration_ms: number;
|
|
233
|
-
codec_name: string;
|
|
234
|
-
byte_size: number;
|
|
235
234
|
}, {
|
|
235
|
+
byte_size: number;
|
|
236
236
|
type: "video";
|
|
237
|
+
codec_name: string;
|
|
237
238
|
file_id: string;
|
|
238
239
|
track_id: number;
|
|
239
240
|
probe_info: {
|
|
241
|
+
height: number;
|
|
242
|
+
width: number;
|
|
240
243
|
index: number;
|
|
241
244
|
codec_name: string;
|
|
242
245
|
codec_long_name: string;
|
|
@@ -247,25 +250,21 @@ export declare const CreateISOBMFFTrackPayload: z.ZodDiscriminatedUnion<"type",
|
|
|
247
250
|
avg_frame_rate: string;
|
|
248
251
|
time_base: string;
|
|
249
252
|
disposition: Record<string, unknown>;
|
|
250
|
-
width: number;
|
|
251
|
-
height: number;
|
|
252
253
|
coded_width: number;
|
|
253
254
|
coded_height: number;
|
|
254
|
-
duration?: number | undefined;
|
|
255
255
|
start_pts?: number | undefined;
|
|
256
256
|
start_time?: number | undefined;
|
|
257
257
|
duration_ts?: number | undefined;
|
|
258
|
+
duration?: number | undefined;
|
|
258
259
|
bit_rate?: string | undefined;
|
|
259
260
|
};
|
|
260
261
|
duration_ms: number;
|
|
261
|
-
codec_name: string;
|
|
262
|
-
byte_size: number;
|
|
263
262
|
}>]>;
|
|
264
263
|
export interface CreateISOBMFFTrackResult {
|
|
265
|
-
|
|
264
|
+
next_byte: number;
|
|
266
265
|
byte_size: number;
|
|
267
266
|
track_id: number;
|
|
268
267
|
file_id: string;
|
|
269
268
|
}
|
|
270
|
-
export declare const createISOBMFFTrack: (client: Client, payload: z.infer<typeof CreateISOBMFFTrackPayload>) => Promise<CreateISOBMFFTrackResult
|
|
271
|
-
export declare const uploadISOBMFFTrack: (client: Client, fileId: string, trackId: number, fileStream: Readable) => Promise<
|
|
269
|
+
export declare const createISOBMFFTrack: (client: Client, payload: z.infer<typeof CreateISOBMFFTrackPayload>) => Promise<CreateISOBMFFTrackResult>;
|
|
270
|
+
export declare const uploadISOBMFFTrack: (client: Client, fileId: string, trackId: number, fileStream: Readable, trackSize: number) => Promise<void>;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import debug from "debug";
|
|
3
3
|
import { AudioStreamSchema, VideoStreamSchema } from "@editframe/assets";
|
|
4
|
+
import { uploadChunks } from "../uploadChunks.js";
|
|
4
5
|
const log = debug("ef:api:isobmff-track");
|
|
6
|
+
const MAX_TRACK_SIZE = 1024 * 1024 * 1024;
|
|
5
7
|
const CreateISOBMFFTrackPayload = z.discriminatedUnion("type", [
|
|
6
8
|
z.object({
|
|
7
9
|
file_id: z.string(),
|
|
@@ -10,7 +12,7 @@ const CreateISOBMFFTrackPayload = z.discriminatedUnion("type", [
|
|
|
10
12
|
probe_info: AudioStreamSchema,
|
|
11
13
|
duration_ms: z.number().int(),
|
|
12
14
|
codec_name: z.string(),
|
|
13
|
-
byte_size: z.number().int()
|
|
15
|
+
byte_size: z.number().int().max(MAX_TRACK_SIZE)
|
|
14
16
|
}),
|
|
15
17
|
z.object({
|
|
16
18
|
file_id: z.string(),
|
|
@@ -19,11 +21,12 @@ const CreateISOBMFFTrackPayload = z.discriminatedUnion("type", [
|
|
|
19
21
|
probe_info: VideoStreamSchema,
|
|
20
22
|
duration_ms: z.number().int(),
|
|
21
23
|
codec_name: z.string(),
|
|
22
|
-
byte_size: z.number().int()
|
|
24
|
+
byte_size: z.number().int().max(MAX_TRACK_SIZE)
|
|
23
25
|
})
|
|
24
26
|
]);
|
|
25
27
|
const createISOBMFFTrack = async (client, payload) => {
|
|
26
28
|
log("Creating isobmff track", payload);
|
|
29
|
+
CreateISOBMFFTrackPayload.parse(payload);
|
|
27
30
|
const response = await client.authenticatedFetch(
|
|
28
31
|
"/api/video2/isobmff_tracks",
|
|
29
32
|
{
|
|
@@ -32,37 +35,21 @@ const createISOBMFFTrack = async (client, payload) => {
|
|
|
32
35
|
}
|
|
33
36
|
);
|
|
34
37
|
log("ISOBMFF track created", response);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return await response.json();
|
|
38
|
-
}
|
|
39
|
-
default: {
|
|
40
|
-
console.error("Failed to create track");
|
|
41
|
-
console.error(await response.json());
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
38
|
+
if (response.ok) {
|
|
39
|
+
return await response.json();
|
|
44
40
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
log("Uploading isobmff track", fileId, trackId);
|
|
48
|
-
const trackIndex = await client.authenticatedFetch(
|
|
49
|
-
`/api/video2/isobmff_tracks/${fileId}/${trackId}/upload`,
|
|
50
|
-
{
|
|
51
|
-
method: "POST",
|
|
52
|
-
body: fileStream
|
|
53
|
-
}
|
|
41
|
+
throw new Error(
|
|
42
|
+
`Failed to create isobmff track ${response.status} ${response.statusText}`
|
|
54
43
|
);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
}
|
|
44
|
+
};
|
|
45
|
+
const uploadISOBMFFTrack = async (client, fileId, trackId, fileStream, trackSize) => {
|
|
46
|
+
log("Uploading fragment track", fileId);
|
|
47
|
+
await uploadChunks(client, {
|
|
48
|
+
url: `/api/video2/isobmff_tracks/${fileId}/${trackId}/upload`,
|
|
49
|
+
fileStream,
|
|
50
|
+
fileSize: trackSize
|
|
51
|
+
});
|
|
52
|
+
log("Fragment track upload complete");
|
|
66
53
|
};
|
|
67
54
|
export {
|
|
68
55
|
CreateISOBMFFTrackPayload,
|