From acb66c9f056432cecddb6f6d94bfb4ccb7fd7238 Mon Sep 17 00:00:00 2001 From: animanathome Date: Fri, 25 Oct 2024 21:40:37 -0700 Subject: [PATCH 1/6] adding duration support for webm --- src/backends/beamcoder.ts | 18 +++++++++++++++++- test/framefusion.test.ts | 15 ++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/backends/beamcoder.ts b/src/backends/beamcoder.ts index 71681a1..c0106bf 100644 --- a/src/backends/beamcoder.ts +++ b/src/backends/beamcoder.ts @@ -18,6 +18,13 @@ const VERBOSE = false; */ const RGBA_PIXEL_SIZE = 4; +// Convert a duration string in the format HH:MM:SS to seconds +// Example: 00:01:30 -> 90 +function convertDurationToSeconds(duration) { + const [hours, minutes, seconds] = duration.split(':').map(parseFloat); + return hours * 3600 + minutes * 60 + seconds; +} + const createDecoder = ({ demuxer, streamIndex, @@ -34,6 +41,8 @@ const createDecoder = ({ thread_count: threadCount, }; + console.log('codec', demuxer.streams[streamIndex].codecpar.name); + if (demuxer.streams[streamIndex].codecpar.name === 'vp8') { return beamcoder.decoder({ ...commonParams, @@ -242,7 +251,14 @@ export class BeamcoderExtractor extends BaseExtractor implements Extractor { * This is the duration of the first video stream in the file expressed in seconds. */ get duration(): number { - return this.ptsToTime(this.#demuxer.streams[this.#streamIndex].duration); + const stream = this.#demuxer.streams[this.#streamIndex]; + if (stream.duration !== null) { + return this.ptsToTime(stream.duration); + } + if (stream?.metadata?.DURATION) { + return convertDurationToSeconds(stream.metadata.DURATION); + } + return 0; } /** diff --git a/test/framefusion.test.ts b/test/framefusion.test.ts index 2420d5b..422720b 100644 --- a/test/framefusion.test.ts +++ b/test/framefusion.test.ts @@ -60,7 +60,7 @@ describe('FrameFusion', () => { await extractor.dispose(); }); - it('can get duration', async() => { + it('can get duration from mp4', async() => { // Arrange const extractor = await BeamcoderExtractor.create({ inputFileOrUrl: 'https://storage.googleapis.com/lumen5-prod-images/countTo60.mp4', @@ -73,6 +73,19 @@ describe('FrameFusion', () => { await extractor.dispose(); }); + it('can get duration from webm', async() => { + // Arrange + const extractor = await BeamcoderExtractor.create({ + inputFileOrUrl: 'https://storage.googleapis.com/lumen5-prod-video/anita-6uTzyZtNRIqOTag.webm', + }); + + // Act and Assert + expect(extractor.duration).to.equal(115); + + // Cleanup + await extractor.dispose(); + }); + it('can get duration when audio stream is longer than video stream', async() => { // Arrange const extractor = await BeamcoderExtractor.create({ From c4a4ca1c8e5c7b5f34ab5da7f78f14acfd5a3d97 Mon Sep 17 00:00:00 2001 From: animanathome Date: Fri, 25 Oct 2024 21:49:25 -0700 Subject: [PATCH 2/6] cleanup --- src/backends/beamcoder.ts | 2 -- test/framefusion.test.ts | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/backends/beamcoder.ts b/src/backends/beamcoder.ts index c0106bf..9c68407 100644 --- a/src/backends/beamcoder.ts +++ b/src/backends/beamcoder.ts @@ -41,8 +41,6 @@ const createDecoder = ({ thread_count: threadCount, }; - console.log('codec', demuxer.streams[streamIndex].codecpar.name); - if (demuxer.streams[streamIndex].codecpar.name === 'vp8') { return beamcoder.decoder({ ...commonParams, diff --git a/test/framefusion.test.ts b/test/framefusion.test.ts index 422720b..f758f20 100644 --- a/test/framefusion.test.ts +++ b/test/framefusion.test.ts @@ -73,7 +73,7 @@ describe('FrameFusion', () => { await extractor.dispose(); }); - it('can get duration from webm', async() => { + it.only('can get duration from webm', async() => { // Arrange const extractor = await BeamcoderExtractor.create({ inputFileOrUrl: 'https://storage.googleapis.com/lumen5-prod-video/anita-6uTzyZtNRIqOTag.webm', From fd05775924358852feca15b3f7abc7e3a7e06e45 Mon Sep 17 00:00:00 2001 From: animanathome Date: Fri, 25 Oct 2024 21:49:57 -0700 Subject: [PATCH 3/6] enable all tests --- test/framefusion.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/framefusion.test.ts b/test/framefusion.test.ts index f758f20..422720b 100644 --- a/test/framefusion.test.ts +++ b/test/framefusion.test.ts @@ -73,7 +73,7 @@ describe('FrameFusion', () => { await extractor.dispose(); }); - it.only('can get duration from webm', async() => { + it('can get duration from webm', async() => { // Arrange const extractor = await BeamcoderExtractor.create({ inputFileOrUrl: 'https://storage.googleapis.com/lumen5-prod-video/anita-6uTzyZtNRIqOTag.webm', From 2ca6dd44bbcd2a2662d05e1380dc39b98c749ea6 Mon Sep 17 00:00:00 2001 From: animanathome Date: Fri, 25 Oct 2024 21:57:48 -0700 Subject: [PATCH 4/6] incrementing version number --- package.json | 2 +- test/framefusion.test.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 7bf6f55..cb524f7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lumen5/framefusion", - "version": "1.0.6", + "version": "1.0.7", "type": "module", "scripts": { "docs": "typedoc framefusion.ts", diff --git a/test/framefusion.test.ts b/test/framefusion.test.ts index 422720b..edda8b4 100644 --- a/test/framefusion.test.ts +++ b/test/framefusion.test.ts @@ -73,10 +73,10 @@ describe('FrameFusion', () => { await extractor.dispose(); }); - it('can get duration from webm', async() => { + it.only('can get duration from webm', async() => { // Arrange const extractor = await BeamcoderExtractor.create({ - inputFileOrUrl: 'https://storage.googleapis.com/lumen5-prod-video/anita-6uTzyZtNRIqOTag.webm', + inputFileOrUrl: 'https://storage.googleapis.com/lumen5-prod-video/anita-6uTzyZtNRKztypC.webm', }); // Act and Assert From 0e5fe700ceeba95d42fe8686a5ae3ae790d98ddd Mon Sep 17 00:00:00 2001 From: animanathome Date: Mon, 28 Oct 2024 08:12:43 -0700 Subject: [PATCH 5/6] enable all tests --- test/framefusion.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/framefusion.test.ts b/test/framefusion.test.ts index edda8b4..a154bff 100644 --- a/test/framefusion.test.ts +++ b/test/framefusion.test.ts @@ -73,7 +73,7 @@ describe('FrameFusion', () => { await extractor.dispose(); }); - it.only('can get duration from webm', async() => { + it('can get duration from webm', async() => { // Arrange const extractor = await BeamcoderExtractor.create({ inputFileOrUrl: 'https://storage.googleapis.com/lumen5-prod-video/anita-6uTzyZtNRKztypC.webm', From 060f966d517a638ecba01959724c23f401072570 Mon Sep 17 00:00:00 2001 From: animanathome Date: Mon, 28 Oct 2024 08:22:21 -0700 Subject: [PATCH 6/6] rebase --- src/backends/beamcoder.ts | 12 +----------- test/framefusion.test.ts | 4 ++-- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/backends/beamcoder.ts b/src/backends/beamcoder.ts index 9c68407..def3674 100644 --- a/src/backends/beamcoder.ts +++ b/src/backends/beamcoder.ts @@ -18,13 +18,6 @@ const VERBOSE = false; */ const RGBA_PIXEL_SIZE = 4; -// Convert a duration string in the format HH:MM:SS to seconds -// Example: 00:01:30 -> 90 -function convertDurationToSeconds(duration) { - const [hours, minutes, seconds] = duration.split(':').map(parseFloat); - return hours * 3600 + minutes * 60 + seconds; -} - const createDecoder = ({ demuxer, streamIndex, @@ -253,10 +246,7 @@ export class BeamcoderExtractor extends BaseExtractor implements Extractor { if (stream.duration !== null) { return this.ptsToTime(stream.duration); } - if (stream?.metadata?.DURATION) { - return convertDurationToSeconds(stream.metadata.DURATION); - } - return 0; + return this.ptsToTime(this.#demuxer.duration) / 1000; } /** diff --git a/test/framefusion.test.ts b/test/framefusion.test.ts index a154bff..2400a32 100644 --- a/test/framefusion.test.ts +++ b/test/framefusion.test.ts @@ -73,14 +73,14 @@ describe('FrameFusion', () => { await extractor.dispose(); }); - it('can get duration from webm', async() => { + it.only('can get duration from webm', async() => { // Arrange const extractor = await BeamcoderExtractor.create({ inputFileOrUrl: 'https://storage.googleapis.com/lumen5-prod-video/anita-6uTzyZtNRKztypC.webm', }); // Act and Assert - expect(extractor.duration).to.equal(115); + expect(extractor.duration).to.equal(115.248); // Cleanup await extractor.dispose();