@remotion/webcodecs 4.0.251 → 4.0.252
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/auto-select-writer.d.ts +1 -1
- package/dist/can-copy-video-track.js +2 -1
- package/dist/choose-correct-hevc-profile.d.ts +5 -0
- package/dist/choose-correct-hevc-profile.js +42 -0
- package/dist/convert-media.d.ts +3 -4
- package/dist/convert-media.js +7 -5
- package/dist/create/iso-base-media/codec-specific/create-codec-specific-data.d.ts +11 -0
- package/dist/create/iso-base-media/codec-specific/create-codec-specific-data.js +29 -11
- package/dist/create/iso-base-media/codec-specific/hvc1.d.ts +2 -0
- package/dist/create/iso-base-media/codec-specific/hvc1.js +48 -0
- package/dist/create/iso-base-media/create-iso-base-media.js +8 -4
- package/dist/create/iso-base-media/serialize-track.js +3 -1
- package/dist/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-hvcc.d.ts +1 -0
- package/dist/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-hvcc.js +16 -0
- package/dist/create/matroska/cluster.d.ts +1 -1
- package/dist/create/matroska/create-matroska-media.js +8 -4
- package/dist/create/matroska/matroska-trackentry.js +3 -0
- package/dist/create/matroska/matroska-utils.d.ts +1 -1
- package/dist/create/media-fn.d.ts +2 -3
- package/dist/create/wav/create-wav.js +8 -4
- package/dist/esm/buffer.mjs +5 -22
- package/dist/esm/index.mjs +426 -62
- package/dist/esm/web-fs.mjs +4 -22
- package/dist/get-available-containers.d.ts +1 -2
- package/dist/get-available-containers.js +3 -3
- package/dist/get-available-video-codecs.d.ts +1 -2
- package/dist/get-available-video-codecs.js +3 -4
- package/dist/get-codec-string.d.ts +7 -0
- package/dist/get-codec-string.js +21 -0
- package/dist/hevc-levels.d.ts +13 -0
- package/dist/hevc-levels.js +233 -0
- package/dist/index.d.ts +0 -1
- package/dist/on-audio-track.js +1 -0
- package/dist/select-container-creator.d.ts +1 -1
- package/dist/test/remux-serverside.test.js +2 -2
- package/dist/video-encoder-config.js +4 -6
- package/dist/video-encoder.js +4 -0
- package/dist/writers/buffer-implementation/writer.d.ts +1 -1
- package/dist/writers/buffer-implementation/writer.js +5 -4
- package/dist/writers/buffer.d.ts +1 -1
- package/dist/writers/web-fs.d.ts +1 -1
- package/dist/writers/web-fs.js +4 -4
- package/package.json +5 -5
package/dist/esm/index.mjs
CHANGED
|
@@ -125,11 +125,14 @@ var createContent = async ({ filename }) => {
|
|
|
125
125
|
writPromise = writPromise.then(() => write(arr));
|
|
126
126
|
return writPromise;
|
|
127
127
|
},
|
|
128
|
-
|
|
128
|
+
finish: async () => {
|
|
129
|
+
await writPromise;
|
|
129
130
|
try {
|
|
130
131
|
await writable.close();
|
|
131
132
|
} catch {
|
|
132
133
|
}
|
|
134
|
+
},
|
|
135
|
+
async getBlob() {
|
|
133
136
|
const newHandle = await directoryHandle.getFileHandle(actualFilename, {
|
|
134
137
|
create: true
|
|
135
138
|
});
|
|
@@ -141,9 +144,6 @@ var createContent = async ({ filename }) => {
|
|
|
141
144
|
writPromise = writPromise.then(() => updateDataAt(position, data));
|
|
142
145
|
return writPromise;
|
|
143
146
|
},
|
|
144
|
-
waitForFinish: async () => {
|
|
145
|
-
await writPromise;
|
|
146
|
-
},
|
|
147
147
|
remove
|
|
148
148
|
};
|
|
149
149
|
return writer;
|
|
@@ -192,10 +192,14 @@ var createContent2 = ({ filename, mimeType }) => {
|
|
|
192
192
|
writPromise = writPromise.then(() => write(arr));
|
|
193
193
|
return writPromise;
|
|
194
194
|
},
|
|
195
|
-
|
|
195
|
+
finish: async () => {
|
|
196
|
+
await writPromise;
|
|
196
197
|
if (removed) {
|
|
197
198
|
return Promise.reject(new Error("Already called .remove() on the result"));
|
|
198
199
|
}
|
|
200
|
+
return Promise.resolve();
|
|
201
|
+
},
|
|
202
|
+
getBlob() {
|
|
199
203
|
const arr = new Uint8Array(buf);
|
|
200
204
|
return Promise.resolve(new File([arr.slice()], filename, { type: mimeType }));
|
|
201
205
|
},
|
|
@@ -207,9 +211,6 @@ var createContent2 = ({ filename, mimeType }) => {
|
|
|
207
211
|
updateDataAt: (position, newData) => {
|
|
208
212
|
writPromise = writPromise.then(() => updateDataAt(position, newData));
|
|
209
213
|
return writPromise;
|
|
210
|
-
},
|
|
211
|
-
waitForFinish: async () => {
|
|
212
|
-
await writPromise;
|
|
213
214
|
}
|
|
214
215
|
};
|
|
215
216
|
return Promise.resolve(writer);
|
|
@@ -912,7 +913,7 @@ var canCopyVideoTrack = ({
|
|
|
912
913
|
return inputTrack.codecWithoutConfig === "vp8" || inputTrack.codecWithoutConfig === "vp9";
|
|
913
914
|
}
|
|
914
915
|
if (outputContainer === "mp4") {
|
|
915
|
-
return inputTrack.codecWithoutConfig === "h264" && (inputContainer === "mp4" || inputContainer === "avi");
|
|
916
|
+
return (inputTrack.codecWithoutConfig === "h264" || inputTrack.codecWithoutConfig === "h265") && (inputContainer === "mp4" || inputContainer === "avi");
|
|
916
917
|
}
|
|
917
918
|
if (outputContainer === "wav") {
|
|
918
919
|
return false;
|
|
@@ -1049,6 +1050,284 @@ var chooseCorrectAvc1Profile = ({
|
|
|
1049
1050
|
return `avc1.6400${profile.hex}`;
|
|
1050
1051
|
};
|
|
1051
1052
|
|
|
1053
|
+
// src/hevc-levels.ts
|
|
1054
|
+
var hevcLevels = [
|
|
1055
|
+
{
|
|
1056
|
+
level: "3.1",
|
|
1057
|
+
maxBitrateMainTier: 1e4,
|
|
1058
|
+
maxBitrateHighTier: null,
|
|
1059
|
+
maxResolutionsAndFrameRates: [
|
|
1060
|
+
{
|
|
1061
|
+
width: 720,
|
|
1062
|
+
height: 480,
|
|
1063
|
+
fps: 84.3
|
|
1064
|
+
},
|
|
1065
|
+
{
|
|
1066
|
+
width: 720,
|
|
1067
|
+
height: 576,
|
|
1068
|
+
fps: 75
|
|
1069
|
+
},
|
|
1070
|
+
{
|
|
1071
|
+
width: 960,
|
|
1072
|
+
height: 540,
|
|
1073
|
+
fps: 60
|
|
1074
|
+
},
|
|
1075
|
+
{
|
|
1076
|
+
width: 1280,
|
|
1077
|
+
height: 720,
|
|
1078
|
+
fps: 33.7
|
|
1079
|
+
}
|
|
1080
|
+
]
|
|
1081
|
+
},
|
|
1082
|
+
{
|
|
1083
|
+
level: "4",
|
|
1084
|
+
maxBitrateMainTier: 12000,
|
|
1085
|
+
maxBitrateHighTier: 30000,
|
|
1086
|
+
maxResolutionsAndFrameRates: [
|
|
1087
|
+
{
|
|
1088
|
+
width: 1280,
|
|
1089
|
+
height: 720,
|
|
1090
|
+
fps: 68
|
|
1091
|
+
},
|
|
1092
|
+
{
|
|
1093
|
+
width: 1920,
|
|
1094
|
+
height: 1080,
|
|
1095
|
+
fps: 32
|
|
1096
|
+
},
|
|
1097
|
+
{
|
|
1098
|
+
width: 2048,
|
|
1099
|
+
height: 1080,
|
|
1100
|
+
fps: 30
|
|
1101
|
+
}
|
|
1102
|
+
]
|
|
1103
|
+
},
|
|
1104
|
+
{
|
|
1105
|
+
level: "4.1",
|
|
1106
|
+
maxBitrateMainTier: 20000,
|
|
1107
|
+
maxBitrateHighTier: 50000,
|
|
1108
|
+
maxResolutionsAndFrameRates: [
|
|
1109
|
+
{
|
|
1110
|
+
width: 1280,
|
|
1111
|
+
height: 720,
|
|
1112
|
+
fps: 136
|
|
1113
|
+
},
|
|
1114
|
+
{
|
|
1115
|
+
width: 1920,
|
|
1116
|
+
height: 1080,
|
|
1117
|
+
fps: 64
|
|
1118
|
+
},
|
|
1119
|
+
{
|
|
1120
|
+
width: 2048,
|
|
1121
|
+
height: 1080,
|
|
1122
|
+
fps: 60
|
|
1123
|
+
}
|
|
1124
|
+
]
|
|
1125
|
+
},
|
|
1126
|
+
{
|
|
1127
|
+
level: "5",
|
|
1128
|
+
maxBitrateMainTier: 25000,
|
|
1129
|
+
maxBitrateHighTier: 1e5,
|
|
1130
|
+
maxResolutionsAndFrameRates: [
|
|
1131
|
+
{
|
|
1132
|
+
width: 1920,
|
|
1133
|
+
height: 1080,
|
|
1134
|
+
fps: 128
|
|
1135
|
+
},
|
|
1136
|
+
{
|
|
1137
|
+
width: 2048,
|
|
1138
|
+
height: 1080,
|
|
1139
|
+
fps: 120
|
|
1140
|
+
},
|
|
1141
|
+
{
|
|
1142
|
+
width: 3840,
|
|
1143
|
+
height: 2160,
|
|
1144
|
+
fps: 32
|
|
1145
|
+
},
|
|
1146
|
+
{
|
|
1147
|
+
width: 4096,
|
|
1148
|
+
height: 2160,
|
|
1149
|
+
fps: 30
|
|
1150
|
+
}
|
|
1151
|
+
]
|
|
1152
|
+
},
|
|
1153
|
+
{
|
|
1154
|
+
level: "5.1",
|
|
1155
|
+
maxBitrateMainTier: 40000,
|
|
1156
|
+
maxBitrateHighTier: 160000,
|
|
1157
|
+
maxResolutionsAndFrameRates: [
|
|
1158
|
+
{
|
|
1159
|
+
width: 1920,
|
|
1160
|
+
height: 1080,
|
|
1161
|
+
fps: 256
|
|
1162
|
+
},
|
|
1163
|
+
{
|
|
1164
|
+
width: 2048,
|
|
1165
|
+
height: 1080,
|
|
1166
|
+
fps: 240
|
|
1167
|
+
},
|
|
1168
|
+
{
|
|
1169
|
+
width: 3840,
|
|
1170
|
+
height: 2160,
|
|
1171
|
+
fps: 64
|
|
1172
|
+
},
|
|
1173
|
+
{
|
|
1174
|
+
width: 4096,
|
|
1175
|
+
height: 2160,
|
|
1176
|
+
fps: 60
|
|
1177
|
+
}
|
|
1178
|
+
]
|
|
1179
|
+
},
|
|
1180
|
+
{
|
|
1181
|
+
level: "5.2",
|
|
1182
|
+
maxBitrateMainTier: 60000,
|
|
1183
|
+
maxBitrateHighTier: 240000,
|
|
1184
|
+
maxResolutionsAndFrameRates: [
|
|
1185
|
+
{
|
|
1186
|
+
width: 2048,
|
|
1187
|
+
height: 1080,
|
|
1188
|
+
fps: 300
|
|
1189
|
+
},
|
|
1190
|
+
{
|
|
1191
|
+
width: 3840,
|
|
1192
|
+
height: 2160,
|
|
1193
|
+
fps: 128
|
|
1194
|
+
},
|
|
1195
|
+
{
|
|
1196
|
+
width: 4096,
|
|
1197
|
+
height: 2160,
|
|
1198
|
+
fps: 120
|
|
1199
|
+
}
|
|
1200
|
+
]
|
|
1201
|
+
},
|
|
1202
|
+
{
|
|
1203
|
+
level: "6",
|
|
1204
|
+
maxBitrateMainTier: 60000,
|
|
1205
|
+
maxBitrateHighTier: 240000,
|
|
1206
|
+
maxResolutionsAndFrameRates: [
|
|
1207
|
+
{
|
|
1208
|
+
width: 3840,
|
|
1209
|
+
height: 2160,
|
|
1210
|
+
fps: 128
|
|
1211
|
+
},
|
|
1212
|
+
{
|
|
1213
|
+
width: 4096,
|
|
1214
|
+
height: 2160,
|
|
1215
|
+
fps: 120
|
|
1216
|
+
},
|
|
1217
|
+
{
|
|
1218
|
+
width: 7680,
|
|
1219
|
+
height: 4320,
|
|
1220
|
+
fps: 32
|
|
1221
|
+
},
|
|
1222
|
+
{
|
|
1223
|
+
width: 8192,
|
|
1224
|
+
height: 4320,
|
|
1225
|
+
fps: 30
|
|
1226
|
+
}
|
|
1227
|
+
]
|
|
1228
|
+
},
|
|
1229
|
+
{
|
|
1230
|
+
level: "6.1",
|
|
1231
|
+
maxBitrateMainTier: 120000,
|
|
1232
|
+
maxBitrateHighTier: 480000,
|
|
1233
|
+
maxResolutionsAndFrameRates: [
|
|
1234
|
+
{
|
|
1235
|
+
width: 3840,
|
|
1236
|
+
height: 2160,
|
|
1237
|
+
fps: 256
|
|
1238
|
+
},
|
|
1239
|
+
{
|
|
1240
|
+
width: 4096,
|
|
1241
|
+
height: 2160,
|
|
1242
|
+
fps: 240
|
|
1243
|
+
},
|
|
1244
|
+
{
|
|
1245
|
+
width: 7680,
|
|
1246
|
+
height: 4320,
|
|
1247
|
+
fps: 64
|
|
1248
|
+
},
|
|
1249
|
+
{
|
|
1250
|
+
width: 8192,
|
|
1251
|
+
height: 4320,
|
|
1252
|
+
fps: 60
|
|
1253
|
+
}
|
|
1254
|
+
]
|
|
1255
|
+
},
|
|
1256
|
+
{
|
|
1257
|
+
level: "6.2",
|
|
1258
|
+
maxBitrateMainTier: 240000,
|
|
1259
|
+
maxBitrateHighTier: 800000,
|
|
1260
|
+
maxResolutionsAndFrameRates: [
|
|
1261
|
+
{
|
|
1262
|
+
width: 3840,
|
|
1263
|
+
height: 2160,
|
|
1264
|
+
fps: 512
|
|
1265
|
+
},
|
|
1266
|
+
{
|
|
1267
|
+
width: 4096,
|
|
1268
|
+
height: 2160,
|
|
1269
|
+
fps: 480
|
|
1270
|
+
},
|
|
1271
|
+
{
|
|
1272
|
+
width: 7680,
|
|
1273
|
+
height: 4320,
|
|
1274
|
+
fps: 128
|
|
1275
|
+
},
|
|
1276
|
+
{
|
|
1277
|
+
width: 8192,
|
|
1278
|
+
height: 4320,
|
|
1279
|
+
fps: 120
|
|
1280
|
+
}
|
|
1281
|
+
]
|
|
1282
|
+
}
|
|
1283
|
+
];
|
|
1284
|
+
|
|
1285
|
+
// src/choose-correct-hevc-profile.ts
|
|
1286
|
+
var chooseCorrectHevcProfile = ({
|
|
1287
|
+
width,
|
|
1288
|
+
height,
|
|
1289
|
+
fps
|
|
1290
|
+
}) => {
|
|
1291
|
+
const profile = hevcLevels.find((p) => {
|
|
1292
|
+
return p.maxResolutionsAndFrameRates.some((max) => {
|
|
1293
|
+
if (width > max.width) {
|
|
1294
|
+
return false;
|
|
1295
|
+
}
|
|
1296
|
+
if (height > max.height) {
|
|
1297
|
+
return false;
|
|
1298
|
+
}
|
|
1299
|
+
const fallbackFps = fps ?? 60;
|
|
1300
|
+
return fallbackFps <= max.fps;
|
|
1301
|
+
});
|
|
1302
|
+
});
|
|
1303
|
+
if (!profile) {
|
|
1304
|
+
throw new Error(`No suitable HEVC profile found for ${width}x${height}@${fps}fps`);
|
|
1305
|
+
}
|
|
1306
|
+
return `hvc1.${1}.${0}.${"L"}${Math.round(Number(profile.level) * 30)}.${"b0"}`;
|
|
1307
|
+
};
|
|
1308
|
+
|
|
1309
|
+
// src/get-codec-string.ts
|
|
1310
|
+
var getCodecStringForEncoder = ({
|
|
1311
|
+
codec,
|
|
1312
|
+
fps,
|
|
1313
|
+
height,
|
|
1314
|
+
width
|
|
1315
|
+
}) => {
|
|
1316
|
+
if (codec === "h264") {
|
|
1317
|
+
return chooseCorrectAvc1Profile({ fps, height, width });
|
|
1318
|
+
}
|
|
1319
|
+
if (codec === "h265") {
|
|
1320
|
+
return chooseCorrectHevcProfile({ fps, height, width });
|
|
1321
|
+
}
|
|
1322
|
+
if (codec === "vp8") {
|
|
1323
|
+
return "vp8";
|
|
1324
|
+
}
|
|
1325
|
+
if (codec === "vp9") {
|
|
1326
|
+
return "vp09.00.10.08";
|
|
1327
|
+
}
|
|
1328
|
+
throw new Error(`Unknown codec: ${codec}`);
|
|
1329
|
+
};
|
|
1330
|
+
|
|
1052
1331
|
// src/video-encoder-config.ts
|
|
1053
1332
|
var getVideoEncoderConfig = async ({
|
|
1054
1333
|
codec,
|
|
@@ -1060,10 +1339,12 @@ var getVideoEncoderConfig = async ({
|
|
|
1060
1339
|
return null;
|
|
1061
1340
|
}
|
|
1062
1341
|
const config = {
|
|
1063
|
-
codec:
|
|
1342
|
+
codec: getCodecStringForEncoder({ codec, fps, height, width }),
|
|
1064
1343
|
height,
|
|
1065
1344
|
width,
|
|
1066
|
-
bitrate: isSafari() ? 3000000 : undefined
|
|
1345
|
+
bitrate: isSafari() ? 3000000 : undefined,
|
|
1346
|
+
bitrateMode: codec === "vp9" && !isSafari() ? "quantizer" : undefined,
|
|
1347
|
+
framerate: fps ?? undefined
|
|
1067
1348
|
};
|
|
1068
1349
|
const hardware = {
|
|
1069
1350
|
...config,
|
|
@@ -1222,6 +1503,29 @@ var generateOutputFilename = (source, container) => {
|
|
|
1222
1503
|
return `${withoutExtension}.${container}`;
|
|
1223
1504
|
};
|
|
1224
1505
|
|
|
1506
|
+
// src/get-available-containers.ts
|
|
1507
|
+
var availableContainers = ["webm", "mp4", "wav"];
|
|
1508
|
+
var getAvailableContainers = () => {
|
|
1509
|
+
return availableContainers;
|
|
1510
|
+
};
|
|
1511
|
+
|
|
1512
|
+
// src/get-available-video-codecs.ts
|
|
1513
|
+
var availableVideoCodecs = ["vp8", "vp9", "h264", "h265"];
|
|
1514
|
+
var getAvailableVideoCodecs = ({
|
|
1515
|
+
container
|
|
1516
|
+
}) => {
|
|
1517
|
+
if (container === "mp4") {
|
|
1518
|
+
return ["h264", "h265"];
|
|
1519
|
+
}
|
|
1520
|
+
if (container === "webm") {
|
|
1521
|
+
return ["vp8", "vp9"];
|
|
1522
|
+
}
|
|
1523
|
+
if (container === "wav") {
|
|
1524
|
+
return [];
|
|
1525
|
+
}
|
|
1526
|
+
throw new Error(`Unsupported container: ${container}`);
|
|
1527
|
+
};
|
|
1528
|
+
|
|
1225
1529
|
// src/on-audio-track.ts
|
|
1226
1530
|
import {
|
|
1227
1531
|
MediaParserInternals as MediaParserInternals3
|
|
@@ -1375,7 +1679,8 @@ var makeAudioTrackHandler = ({
|
|
|
1375
1679
|
const codecPrivate = audioOperation.audioCodec === "aac" ? MediaParserInternals3.createAacCodecPrivate({
|
|
1376
1680
|
audioObjectType: 2,
|
|
1377
1681
|
sampleRate: track.sampleRate,
|
|
1378
|
-
channelConfiguration: track.numberOfChannels
|
|
1682
|
+
channelConfiguration: track.numberOfChannels,
|
|
1683
|
+
codecPrivate: null
|
|
1379
1684
|
}) : null;
|
|
1380
1685
|
const { trackNumber } = await state.addTrack({
|
|
1381
1686
|
type: "audio",
|
|
@@ -1770,7 +2075,10 @@ var createVideoEncoder = ({
|
|
|
1770
2075
|
}
|
|
1771
2076
|
const keyFrame = framesProcessed % 40 === 0;
|
|
1772
2077
|
encoder.encode(convertToCorrectVideoFrame({ videoFrame: frame, outputCodec }), {
|
|
1773
|
-
keyFrame
|
|
2078
|
+
keyFrame,
|
|
2079
|
+
vp9: {
|
|
2080
|
+
quantizer: 36
|
|
2081
|
+
}
|
|
1774
2082
|
});
|
|
1775
2083
|
ioSynchronizer.inputItem(frame.timestamp, keyFrame);
|
|
1776
2084
|
framesProcessed++;
|
|
@@ -2479,6 +2787,17 @@ var createAvccBox = (privateData) => {
|
|
|
2479
2787
|
]));
|
|
2480
2788
|
};
|
|
2481
2789
|
|
|
2790
|
+
// src/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-hvcc.ts
|
|
2791
|
+
var createHvccBox = (privateData) => {
|
|
2792
|
+
if (!privateData) {
|
|
2793
|
+
throw new Error("privateData is required");
|
|
2794
|
+
}
|
|
2795
|
+
return addSize(combineUint8Arrays([
|
|
2796
|
+
stringsToUint8Array("hvcC"),
|
|
2797
|
+
privateData
|
|
2798
|
+
]));
|
|
2799
|
+
};
|
|
2800
|
+
|
|
2482
2801
|
// src/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-pasp.ts
|
|
2483
2802
|
var createPasp = (x, y) => {
|
|
2484
2803
|
return addSize(combineUint8Arrays([
|
|
@@ -2522,6 +2841,40 @@ var createAvc1Data = ({
|
|
|
2522
2841
|
]));
|
|
2523
2842
|
};
|
|
2524
2843
|
|
|
2844
|
+
// src/create/iso-base-media/codec-specific/hvc1.ts
|
|
2845
|
+
var createHvc1Data = ({
|
|
2846
|
+
compressorName,
|
|
2847
|
+
depth,
|
|
2848
|
+
height,
|
|
2849
|
+
horizontalResolution,
|
|
2850
|
+
hvccBox,
|
|
2851
|
+
pasp,
|
|
2852
|
+
verticalResolution,
|
|
2853
|
+
width
|
|
2854
|
+
}) => {
|
|
2855
|
+
return addSize(combineUint8Arrays([
|
|
2856
|
+
stringsToUint8Array("hvc1"),
|
|
2857
|
+
new Uint8Array([0, 0, 0, 0, 0, 0]),
|
|
2858
|
+
new Uint8Array([0, 1]),
|
|
2859
|
+
new Uint8Array([0, 0]),
|
|
2860
|
+
new Uint8Array([0, 0]),
|
|
2861
|
+
new Uint8Array([0, 0, 0, 0]),
|
|
2862
|
+
new Uint8Array([0, 0, 0, 0]),
|
|
2863
|
+
new Uint8Array([0, 0, 0, 0]),
|
|
2864
|
+
numberTo16BitUIntOrInt(width),
|
|
2865
|
+
numberTo16BitUIntOrInt(height),
|
|
2866
|
+
setFixedPointSignedOrUnsigned1616Number(horizontalResolution),
|
|
2867
|
+
setFixedPointSignedOrUnsigned1616Number(verticalResolution),
|
|
2868
|
+
new Uint8Array([0, 0, 0, 0]),
|
|
2869
|
+
numberTo16BitUIntOrInt(1),
|
|
2870
|
+
stringToPascalString(compressorName),
|
|
2871
|
+
numberTo16BitUIntOrInt(depth),
|
|
2872
|
+
numberTo16BitUIntOrInt(-1),
|
|
2873
|
+
hvccBox,
|
|
2874
|
+
pasp
|
|
2875
|
+
]));
|
|
2876
|
+
};
|
|
2877
|
+
|
|
2525
2878
|
// src/create/iso-base-media/codec-specific/mp4a.ts
|
|
2526
2879
|
var createMp4a = ({
|
|
2527
2880
|
sampleRate,
|
|
@@ -2574,17 +2927,33 @@ var createMp4a = ({
|
|
|
2574
2927
|
// src/create/iso-base-media/codec-specific/create-codec-specific-data.ts
|
|
2575
2928
|
var createCodecSpecificData = (track) => {
|
|
2576
2929
|
if (track.type === "video") {
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2930
|
+
if (track.codec === "h264") {
|
|
2931
|
+
return createAvc1Data({
|
|
2932
|
+
avccBox: createAvccBox(track.codecPrivate),
|
|
2933
|
+
compressorName: "WebCodecs",
|
|
2934
|
+
depth: 24,
|
|
2935
|
+
horizontalResolution: 72,
|
|
2936
|
+
verticalResolution: 72,
|
|
2937
|
+
height: track.height,
|
|
2938
|
+
width: track.width,
|
|
2939
|
+
pasp: createPasp(1, 1),
|
|
2940
|
+
type: "avc1-data"
|
|
2941
|
+
});
|
|
2942
|
+
}
|
|
2943
|
+
if (track.codec === "h265") {
|
|
2944
|
+
return createHvc1Data({
|
|
2945
|
+
hvccBox: createHvccBox(track.codecPrivate),
|
|
2946
|
+
compressorName: "WebCodecs",
|
|
2947
|
+
depth: 24,
|
|
2948
|
+
horizontalResolution: 72,
|
|
2949
|
+
verticalResolution: 72,
|
|
2950
|
+
height: track.height,
|
|
2951
|
+
width: track.width,
|
|
2952
|
+
pasp: createPasp(1, 1),
|
|
2953
|
+
type: "hvc1-data"
|
|
2954
|
+
});
|
|
2955
|
+
}
|
|
2956
|
+
throw new Error("Unsupported codec specific data " + track.codec);
|
|
2588
2957
|
}
|
|
2589
2958
|
if (track.type === "audio") {
|
|
2590
2959
|
return createMp4a({
|
|
@@ -3041,7 +3410,7 @@ var serializeTrack = ({
|
|
|
3041
3410
|
samplePositions,
|
|
3042
3411
|
timescale
|
|
3043
3412
|
}) => {
|
|
3044
|
-
if (track.codec !== "h264" && track.codec !== "aac") {
|
|
3413
|
+
if (track.codec !== "h264" && track.codec !== "h265" && track.codec !== "aac") {
|
|
3045
3414
|
throw new Error("Currently only H.264 and AAC is supported");
|
|
3046
3415
|
}
|
|
3047
3416
|
return createTrak({
|
|
@@ -3150,7 +3519,11 @@ var createIsoBaseMedia = async ({
|
|
|
3150
3519
|
majorBrand: "isom",
|
|
3151
3520
|
minorBrand: 512
|
|
3152
3521
|
});
|
|
3153
|
-
const w = await writer.createContent({
|
|
3522
|
+
const w = await writer.createContent({
|
|
3523
|
+
filename,
|
|
3524
|
+
mimeType: "video/mp4",
|
|
3525
|
+
logLevel
|
|
3526
|
+
});
|
|
3154
3527
|
await w.write(header);
|
|
3155
3528
|
let globalDurationInUnits = 0;
|
|
3156
3529
|
const lowestTrackTimestamps = {};
|
|
@@ -3266,8 +3639,8 @@ var createIsoBaseMedia = async ({
|
|
|
3266
3639
|
};
|
|
3267
3640
|
const waitForFinishPromises = [];
|
|
3268
3641
|
return {
|
|
3269
|
-
|
|
3270
|
-
return w.
|
|
3642
|
+
getBlob: () => {
|
|
3643
|
+
return w.getBlob();
|
|
3271
3644
|
},
|
|
3272
3645
|
remove: async () => {
|
|
3273
3646
|
await w.remove();
|
|
@@ -3308,7 +3681,7 @@ var createIsoBaseMedia = async ({
|
|
|
3308
3681
|
await updateMoov();
|
|
3309
3682
|
await updateMdatSize();
|
|
3310
3683
|
MediaParserInternals6.Log.verbose(logLevel, "All write operations done. Waiting for finish...");
|
|
3311
|
-
await w.
|
|
3684
|
+
await w.finish();
|
|
3312
3685
|
}
|
|
3313
3686
|
};
|
|
3314
3687
|
};
|
|
@@ -3743,6 +4116,9 @@ var makeAudioCodecId = (codecId) => {
|
|
|
3743
4116
|
if (codecId === "aac") {
|
|
3744
4117
|
return "A_AAC";
|
|
3745
4118
|
}
|
|
4119
|
+
if (codecId === "ac3") {
|
|
4120
|
+
return "A_AC3";
|
|
4121
|
+
}
|
|
3746
4122
|
if (codecId === "mp3") {
|
|
3747
4123
|
return "A_MPEG/L3";
|
|
3748
4124
|
}
|
|
@@ -3943,7 +4319,11 @@ var createMatroskaMedia = async ({
|
|
|
3943
4319
|
progressTracker
|
|
3944
4320
|
}) => {
|
|
3945
4321
|
const header = makeMatroskaHeader();
|
|
3946
|
-
const w = await writer.createContent({
|
|
4322
|
+
const w = await writer.createContent({
|
|
4323
|
+
filename,
|
|
4324
|
+
mimeType: "video/webm",
|
|
4325
|
+
logLevel
|
|
4326
|
+
});
|
|
3947
4327
|
await w.write(header.bytes);
|
|
3948
4328
|
const matroskaInfo = makeMatroskaInfo({
|
|
3949
4329
|
timescale
|
|
@@ -4076,8 +4456,8 @@ var createMatroskaMedia = async ({
|
|
|
4076
4456
|
}
|
|
4077
4457
|
});
|
|
4078
4458
|
},
|
|
4079
|
-
|
|
4080
|
-
return w.
|
|
4459
|
+
getBlob: async () => {
|
|
4460
|
+
return w.getBlob();
|
|
4081
4461
|
},
|
|
4082
4462
|
remove: async () => {
|
|
4083
4463
|
await w.remove();
|
|
@@ -4104,9 +4484,9 @@ var createMatroskaMedia = async ({
|
|
|
4104
4484
|
});
|
|
4105
4485
|
await updateSeekWrite();
|
|
4106
4486
|
await w.write(createMatroskaCues(cues).bytes);
|
|
4107
|
-
await w.waitForFinish();
|
|
4108
4487
|
const segmentSize = w.getWrittenByteCount() - segmentOffset - matroskaToHex(matroskaElements.Segment).byteLength - MATROSKA_SEGMENT_MIN_VINT_WIDTH;
|
|
4109
4488
|
await updateSegmentSize(segmentSize);
|
|
4489
|
+
await w.finish();
|
|
4110
4490
|
}
|
|
4111
4491
|
};
|
|
4112
4492
|
};
|
|
@@ -4133,7 +4513,11 @@ var createWav = async ({
|
|
|
4133
4513
|
writer,
|
|
4134
4514
|
progressTracker
|
|
4135
4515
|
}) => {
|
|
4136
|
-
const w = await writer.createContent({
|
|
4516
|
+
const w = await writer.createContent({
|
|
4517
|
+
filename,
|
|
4518
|
+
mimeType: "audio/wav",
|
|
4519
|
+
logLevel
|
|
4520
|
+
});
|
|
4137
4521
|
await w.write(new Uint8Array([82, 73, 70, 70]));
|
|
4138
4522
|
const sizePosition = w.getWrittenByteCount();
|
|
4139
4523
|
await w.write(new Uint8Array([0, 0, 0, 0]));
|
|
@@ -4183,8 +4567,8 @@ var createWav = async ({
|
|
|
4183
4567
|
};
|
|
4184
4568
|
const waitForFinishPromises = [];
|
|
4185
4569
|
return {
|
|
4186
|
-
|
|
4187
|
-
return w.
|
|
4570
|
+
getBlob: () => {
|
|
4571
|
+
return w.getBlob();
|
|
4188
4572
|
},
|
|
4189
4573
|
remove: () => {
|
|
4190
4574
|
return w.remove();
|
|
@@ -4208,7 +4592,7 @@ var createWav = async ({
|
|
|
4208
4592
|
await Promise.all(waitForFinishPromises.map((p) => p()));
|
|
4209
4593
|
await operationProm.current;
|
|
4210
4594
|
await updateSize();
|
|
4211
|
-
await w.
|
|
4595
|
+
await w.finish();
|
|
4212
4596
|
},
|
|
4213
4597
|
addTrack: async (track) => {
|
|
4214
4598
|
if (track.type !== "audio") {
|
|
@@ -4336,11 +4720,11 @@ var convertMedia = async function({
|
|
|
4336
4720
|
if (userPassedAbortSignal?.aborted) {
|
|
4337
4721
|
return Promise.reject(new error_cause_default("Aborted"));
|
|
4338
4722
|
}
|
|
4339
|
-
if (container !== "webm" && container
|
|
4340
|
-
return Promise.reject(new TypeError(
|
|
4723
|
+
if (container !== "webm" && availableContainers.indexOf(container) === -1) {
|
|
4724
|
+
return Promise.reject(new TypeError(`Only the following values for "container" are supported currently: ${JSON.stringify(availableContainers)}`));
|
|
4341
4725
|
}
|
|
4342
|
-
if (videoCodec && videoCodec
|
|
4343
|
-
return Promise.reject(new TypeError(
|
|
4726
|
+
if (videoCodec && availableVideoCodecs.indexOf(videoCodec) === -1) {
|
|
4727
|
+
return Promise.reject(new TypeError(`Only the following values for "videoCodec" are supported currently: ${JSON.stringify(availableVideoCodecs)}`));
|
|
4344
4728
|
}
|
|
4345
4729
|
const { resolve, reject, getPromiseToImmediatelyReturn } = withResolversAndWaitForReturn();
|
|
4346
4730
|
const controller = new AbortController;
|
|
@@ -4452,7 +4836,7 @@ var convertMedia = async function({
|
|
|
4452
4836
|
return state.waitForFinish();
|
|
4453
4837
|
}).then(() => {
|
|
4454
4838
|
resolve({
|
|
4455
|
-
save: state.
|
|
4839
|
+
save: state.getBlob,
|
|
4456
4840
|
remove: state.remove,
|
|
4457
4841
|
finalState: throttledState.get()
|
|
4458
4842
|
});
|
|
@@ -4487,26 +4871,6 @@ var getAvailableAudioCodecs = ({
|
|
|
4487
4871
|
}
|
|
4488
4872
|
throw new Error(`Unsupported container: ${container}`);
|
|
4489
4873
|
};
|
|
4490
|
-
// src/get-available-containers.ts
|
|
4491
|
-
var availableContainers = ["webm", "mp4", "wav"];
|
|
4492
|
-
var getAvailableContainers = () => {
|
|
4493
|
-
return availableContainers;
|
|
4494
|
-
};
|
|
4495
|
-
// src/get-available-video-codecs.ts
|
|
4496
|
-
var getAvailableVideoCodecs = ({
|
|
4497
|
-
container
|
|
4498
|
-
}) => {
|
|
4499
|
-
if (container === "mp4") {
|
|
4500
|
-
return ["h264"];
|
|
4501
|
-
}
|
|
4502
|
-
if (container === "webm") {
|
|
4503
|
-
return ["vp8", "vp9"];
|
|
4504
|
-
}
|
|
4505
|
-
if (container === "wav") {
|
|
4506
|
-
return [];
|
|
4507
|
-
}
|
|
4508
|
-
throw new Error(`Unsupported container: ${container}`);
|
|
4509
|
-
};
|
|
4510
4874
|
// src/index.ts
|
|
4511
4875
|
var WebCodecsInternals = {
|
|
4512
4876
|
rotateAndResizeVideoFrame,
|