@vpalmisano/webrtcperf 4.1.1 → 4.1.4
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/README.md +1 -0
- package/app.min.js +1 -1
- package/build/src/app.js +63 -61
- package/build/src/app.js.map +1 -1
- package/build/src/config.d.ts +1 -0
- package/build/src/config.js +8 -1
- package/build/src/config.js.map +1 -1
- package/build/src/session.js +9 -0
- package/build/src/session.js.map +1 -1
- package/build/src/vmaf.d.ts +5 -3
- package/build/src/vmaf.js +23 -14
- package/build/src/vmaf.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/app.ts +69 -61
- package/src/config.ts +8 -1
- package/src/session.ts +12 -0
- package/src/vmaf.ts +25 -14
package/src/vmaf.ts
CHANGED
|
@@ -75,7 +75,7 @@ export async function prepareVideo(
|
|
|
75
75
|
await runShellCommand(
|
|
76
76
|
`ffmpeg -hide_banner -loglevel warning -threads ${Math.min(cpus, 16)} \
|
|
77
77
|
${videoDuration ? `-t ${videoDuration}` : ''} \
|
|
78
|
-
-i ${fpath} \
|
|
78
|
+
-stream_loop -1 -i ${fpath} \
|
|
79
79
|
-filter_complex "[0:v]scale=w=${videoWidth || width}:h=${videoHeight || height},fps=${videoFramerate || frameRate},${filter}\
|
|
80
80
|
drawbox=x=0:y=0:w=iw:h=${textHeight}:color=black:t=fill,\
|
|
81
81
|
drawtext=fontfile=/usr/share/fonts/truetype/noto/NotoMono-Regular.ttf:text='${id || 0}-%{eif\\:t*1000\\:u}':fontcolor=white:fontsize=${fontsize}:x=(w-text_w)/2:y=(${textHeight}-text_h)/2[out]" \
|
|
@@ -94,8 +94,9 @@ drawtext=fontfile=/usr/share/fonts/truetype/noto/NotoMono-Regular.ttf:text='${id
|
|
|
94
94
|
* @param fpath The input video file path.
|
|
95
95
|
* @param crop The crop filter.
|
|
96
96
|
* @param keepSourceFile If the source file should be kept.
|
|
97
|
+
* @param skipDuplicated If the duplicated recognized frames should be skipped.
|
|
97
98
|
*/
|
|
98
|
-
export async function convertToIvf(fpath: string, crop?: string, keepSourceFile = true) {
|
|
99
|
+
export async function convertToIvf(fpath: string, crop?: string, keepSourceFile = true, skipDuplicated = false) {
|
|
99
100
|
const { width, height, frameRate } = await parseVideo(fpath)
|
|
100
101
|
const outputPath = fpath.replace(/\.[^.]+$/, '.ivf.raw')
|
|
101
102
|
log.debug(`convertToIvf ${fpath} ${width}x${height}@${frameRate} -> ${outputPath} crop:`, crop)
|
|
@@ -108,8 +109,11 @@ export async function convertToIvf(fpath: string, crop?: string, keepSourceFile
|
|
|
108
109
|
-f ivf ${outputPath}`,
|
|
109
110
|
true,
|
|
110
111
|
)
|
|
112
|
+
if (!keepSourceFile) {
|
|
113
|
+
await fs.promises.unlink(fpath)
|
|
114
|
+
}
|
|
111
115
|
|
|
112
|
-
await fixIvfFrames(outputPath,
|
|
116
|
+
await fixIvfFrames(outputPath, false, skipDuplicated)
|
|
113
117
|
}
|
|
114
118
|
|
|
115
119
|
/**
|
|
@@ -223,7 +227,7 @@ async function parseIvf(fpath: string, runRecognizer = false) {
|
|
|
223
227
|
log.warn(`IVF file ${fname}: pts ${pts} <= prev ${ptsIndex[ptsIndex.length - 1]}`)
|
|
224
228
|
} */
|
|
225
229
|
if (frames.has(pts)) {
|
|
226
|
-
|
|
230
|
+
log.debug(`IVF file ${fname}: pts ${pts} already present, skipping`)
|
|
227
231
|
skipped++
|
|
228
232
|
} else {
|
|
229
233
|
frames.set(pts, { pts, index, position, size: size + 12 })
|
|
@@ -262,8 +266,9 @@ ts: ${firstTimestamp.toFixed(2)}-${lastTimestamp.toFixed(2)} (${(lastTimestamp -
|
|
|
262
266
|
}
|
|
263
267
|
}
|
|
264
268
|
|
|
265
|
-
export async function fixIvfFrames(filePath: string, keepSourceFile = true) {
|
|
269
|
+
export async function fixIvfFrames(filePath: string, keepSourceFile = true, skipDuplicated = false) {
|
|
266
270
|
const fname = path.basename(filePath)
|
|
271
|
+
log.debug(`fixIvfFrames ${fname} keepSourceFile=${keepSourceFile} skipDuplicated=${skipDuplicated}`)
|
|
267
272
|
const dirPath = path.dirname(filePath)
|
|
268
273
|
if (!fname.endsWith('.ivf.raw')) {
|
|
269
274
|
throw new Error(`fixIvfFrames ${fname}: invalid file extension, expected ".ivf.raw"`)
|
|
@@ -313,12 +318,16 @@ export async function fixIvfFrames(filePath: string, keepSourceFile = true) {
|
|
|
313
318
|
if (nextFrame?.recognizedPts && (nextFrame?.recognizedPts || 0) < frame.recognizedPts) {
|
|
314
319
|
continue
|
|
315
320
|
}
|
|
316
|
-
//
|
|
321
|
+
// Duplicated recognized frame.
|
|
317
322
|
if (prevFrame?.recognizedPts && frame.recognizedPts === prevFrame.recognizedPts) {
|
|
318
|
-
|
|
319
|
-
`${
|
|
320
|
-
)
|
|
321
|
-
|
|
323
|
+
log.debug(
|
|
324
|
+
`${fname}: duplicate recognized frame pts=${pts}:${frame.recognizedPts} prev=${prevFrame.pts}:${prevFrame.recognizedPts} next=${nextFrame?.pts}:${nextFrame?.recognizedPts} (${skipDuplicated ? 'skipped' : 'fixed'})`,
|
|
325
|
+
)
|
|
326
|
+
if (skipDuplicated) {
|
|
327
|
+
continue
|
|
328
|
+
} else {
|
|
329
|
+
frame.recognizedPts += frame.pts - prevFrame.pts
|
|
330
|
+
}
|
|
322
331
|
}
|
|
323
332
|
const frameView = new DataView(new ArrayBuffer(frame.size))
|
|
324
333
|
await fd.read(frameView, 0, frame.size, frame.position)
|
|
@@ -343,7 +352,8 @@ export async function fixIvfFrames(filePath: string, keepSourceFile = true) {
|
|
|
343
352
|
return { participantDisplayName, outFilePath }
|
|
344
353
|
}
|
|
345
354
|
|
|
346
|
-
export async function fixIvfFiles(directory: string, keepSourceFiles = true) {
|
|
355
|
+
export async function fixIvfFiles(directory: string, keepSourceFiles = true, skipDuplicated = false) {
|
|
356
|
+
log.debug(`fixIvfFiles ${directory} keepSourceFiles=${keepSourceFiles} skipDuplicated=${skipDuplicated}`)
|
|
347
357
|
const reference = new Map<string, string>()
|
|
348
358
|
const degraded = new Map<string, string[]>()
|
|
349
359
|
|
|
@@ -381,7 +391,7 @@ export async function fixIvfFiles(directory: string, keepSourceFiles = true) {
|
|
|
381
391
|
rawFiles,
|
|
382
392
|
async filePath => {
|
|
383
393
|
try {
|
|
384
|
-
const { participantDisplayName, outFilePath } = await fixIvfFrames(filePath, keepSourceFiles)
|
|
394
|
+
const { participantDisplayName, outFilePath } = await fixIvfFrames(filePath, keepSourceFiles, skipDuplicated)
|
|
385
395
|
return { participantDisplayName, outFilePath }
|
|
386
396
|
} catch (err) {
|
|
387
397
|
log.error(`fixIvfFrames error: ${(err as Error).stack}`)
|
|
@@ -690,16 +700,17 @@ interface VmafConfig {
|
|
|
690
700
|
vmafKeepIntermediateFiles: boolean
|
|
691
701
|
vmafKeepSourceFiles: boolean
|
|
692
702
|
vmafCrop?: string
|
|
703
|
+
vmafSkipDuplicated?: boolean
|
|
693
704
|
}
|
|
694
705
|
|
|
695
706
|
export async function calculateVmafScore(config: VmafConfig): Promise<VmafScore[]> {
|
|
696
|
-
const { vmafPath, vmafPreview, vmafKeepIntermediateFiles, vmafKeepSourceFiles, vmafCrop } = config
|
|
707
|
+
const { vmafPath, vmafPreview, vmafKeepIntermediateFiles, vmafKeepSourceFiles, vmafCrop, vmafSkipDuplicated } = config
|
|
697
708
|
if (!fs.existsSync(config.vmafPath)) {
|
|
698
709
|
throw new Error(`VMAF path ${config.vmafPath} does not exist`)
|
|
699
710
|
}
|
|
700
711
|
log.debug(`calculateVmafScore referencePath=${vmafPath}`)
|
|
701
712
|
|
|
702
|
-
const { reference, degraded } = await fixIvfFiles(vmafPath, vmafKeepSourceFiles)
|
|
713
|
+
const { reference, degraded } = await fixIvfFiles(vmafPath, vmafKeepSourceFiles, vmafSkipDuplicated)
|
|
703
714
|
|
|
704
715
|
const crop: VmafCrop | undefined = vmafCrop ? json5.parse(vmafCrop) : undefined
|
|
705
716
|
|