From c79608d7359bcc6563f253aef01b9d273a1821ba Mon Sep 17 00:00:00 2001 From: Jordan Rash <15827604+jordan-rash@users.noreply.github.com> Date: Mon, 4 Mar 2024 14:35:37 -0700 Subject: [PATCH 1/8] share --- natster-io/package.json | 3 +- natster-io/pnpm-lock.yaml | 52 ++++++++++++++++++++- natster-io/src/components/File.vue | 16 ++++++- natster-io/src/stores/catalog.ts | 2 +- natster-io/src/stores/file.ts | 75 +++++++++++++++++++----------- 5 files changed, 118 insertions(+), 30 deletions(-) diff --git a/natster-io/package.json b/natster-io/package.json index 84902f4..c8fa4a5 100644 --- a/natster-io/package.json +++ b/natster-io/package.json @@ -26,7 +26,8 @@ "nkeys.js": "^1.1.0", "pinia": "^2.1.7", "vue": "^3.4.15", - "vue-router": "^4.2.5" + "vue-router": "^4.2.5", + "vue3-audio-player": "^1.0.7" }, "devDependencies": { "@rushstack/eslint-patch": "^1.3.3", diff --git a/natster-io/pnpm-lock.yaml b/natster-io/pnpm-lock.yaml index a629c01..be1f8b6 100644 --- a/natster-io/pnpm-lock.yaml +++ b/natster-io/pnpm-lock.yaml @@ -47,6 +47,9 @@ dependencies: vue-router: specifier: ^4.2.5 version: 4.2.5(vue@3.4.18) + vue3-audio-player: + specifier: ^1.0.7 + version: 1.0.7(typescript@5.3.3) devDependencies: '@rushstack/eslint-patch': @@ -121,6 +124,38 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} + /@any-touch/compute@2.2.0: + resolution: {integrity: sha512-hrw74b/cVT8SmiKFLValmllajw+bBvTa5iUwIXFVVIJM9T3tO15zZC2QbjVz8Uwi6XjH932RDUILGMs2TNvyQg==} + dependencies: + '@any-touch/shared': 2.2.0 + '@any-touch/vector': 2.2.0 + tslib: 2.6.2 + dev: false + + /@any-touch/core@2.2.0: + resolution: {integrity: sha512-xMHAA5aLCatFto+4fQWyE4YAsyN/LsXS4mnYuVpqFYoNz8dl5FsB/TIyb9JrqMKLYMxxcZ9joqR8gDprH1lwBw==} + dependencies: + '@any-touch/shared': 2.2.0 + any-event: 2.2.0 + dev: false + + /@any-touch/pan@2.2.0: + resolution: {integrity: sha512-uMkCHbTm5qWji/FvhumP9n1ZCkPU7hy864g+ZhoWZ0OWAmn7s/TKRo4UqPBfqEPUMV6obGZvatrrgBLWT6J57w==} + dependencies: + '@any-touch/compute': 2.2.0 + '@any-touch/shared': 2.2.0 + dev: false + + /@any-touch/shared@2.2.0: + resolution: {integrity: sha512-2n1zWaATi/3osr/dkIUq5O7aSffKUsTM4DsIbPMW1VEO77v/rX2HkLoxt2Djzj5eCGh7An55Vw8NeA33kTTSRA==} + dev: false + + /@any-touch/vector@2.2.0: + resolution: {integrity: sha512-t7pGYegIDCJl+swwsohZHZKmF71ZMt+hjwVEyhaEP6nQhcx6S7zulxnRxNp1t8s+c/JdK02Q89HnzQ4Ukg4+IA==} + dependencies: + '@any-touch/shared': 2.2.0 + dev: false + /@auth0/auth0-spa-js@2.1.3: resolution: {integrity: sha512-NMTBNuuG4g3rame1aCnNS5qFYIzsTUV5qTFPRfTyYFS1feS6jsCBR+eTq9YkxCp1yuoM2UIcjunPaoPl77U9xQ==} dev: false @@ -1185,6 +1220,12 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} + /any-event@2.2.0: + resolution: {integrity: sha512-PB4sEiVUjL+5mLmwlAGYdI5/1ouckapxS6+RPIvrGXv9XTMav7M3k3rR/f9fwAR+e2608CTR3FOR5HrOEYTtKA==} + dependencies: + tslib: 2.6.2 + dev: false + /any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -2489,7 +2530,6 @@ packages: /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - dev: true /tweetnacl@1.0.3: resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} @@ -2661,6 +2701,16 @@ packages: typescript: 5.3.3 dev: true + /vue3-audio-player@1.0.7(typescript@5.3.3): + resolution: {integrity: sha512-7uGyCDzJaEIN4VV7Sf/s/nOUcO7SV0mRNFjf7dOAG+clVGF8rcL8Arp0vXGwmx4jzxqwOcLhl3C6TK/r9eoI/A==} + dependencies: + '@any-touch/core': 2.2.0 + '@any-touch/pan': 2.2.0 + vue: 3.4.18(typescript@5.3.3) + transitivePeerDependencies: + - typescript + dev: false + /vue@3.4.18(typescript@5.3.3): resolution: {integrity: sha512-0zLRYamFRe0wF4q2L3O24KQzLyLpL64ye1RUToOgOxuWZsb/FhaNRdGmeozdtVYLz6tl94OXLaK7/WQIrVCw1A==} peerDependencies: diff --git a/natster-io/src/components/File.vue b/natster-io/src/components/File.vue index 77d5289..1c7cf96 100644 --- a/natster-io/src/components/File.vue +++ b/natster-io/src/components/File.vue @@ -55,7 +55,7 @@

+ @@ -89,6 +93,8 @@ import { ref, watch } from 'vue' import { storeToRefs } from 'pinia' import { Dialog, DialogPanel, DialogTitle, TransitionChild, TransitionRoot } from '@headlessui/vue' import { InformationCircleIcon, XMarkIcon } from '@heroicons/vue/24/outline' +import AudioPlayer from 'vue3-audio-player' +import 'vue3-audio-player/dist/style.css' import { fileStore } from '../stores/file' const fStore = fileStore() @@ -106,6 +112,14 @@ watch(mimeType, (newVal, oldVal) => { } }) +function getAudioOptions(inSrc, inTitle, inCover) { + return { + src: inSrc, + title: inTitle, + coverImage: inCover + } +} + watch(mediaUrl, (newVal, oldVal) => { if (!!newVal) { setTimeout(() => { diff --git a/natster-io/src/stores/catalog.ts b/natster-io/src/stores/catalog.ts index debbcf8..a4a2a9e 100644 --- a/natster-io/src/stores/catalog.ts +++ b/natster-io/src/stores/catalog.ts @@ -153,7 +153,7 @@ export const catalogStore = defineStore('catalog', { const chunkIdx = parseInt(m.headers.get('x-natster-chunk-idx')) const totalChunks = parseInt(m.headers.get('x-natster-total-chunks')) const senderXKey = m.headers.get('x-natster-sender-xkey') - + let decrypted = xkey.open(m.data, senderXKey) fileArray.push(decrypted) diff --git a/natster-io/src/stores/file.ts b/natster-io/src/stores/file.ts index 3831755..a380cac 100644 --- a/natster-io/src/stores/file.ts +++ b/natster-io/src/stores/file.ts @@ -39,31 +39,18 @@ export const fileStore = defineStore('file', { this.codec = 'avc1.640028,mp4a.40.2' //'avc1.42C028,mp4a.40.2' // FIXME-- read this from headers and pass it in to render() console.log(MediaSource.isTypeSupported(`video/mp4; codecs="${this.codec}"`)) - const _data = data this.mediaSource.addEventListener('sourceopen', () => { this.videoSourceBuffer = this.mediaSource.addSourceBuffer( `video/mp4; codecs="${this.codec}"` ) - - this.videoSourceBuffer.addEventListener('updatestart', (e) => { - // console.log(e) - }) - - this.videoSourceBuffer.addEventListener('update', (e) => { - // console.log(e) - }) - - this.videoSourceBuffer.addEventListener('updateend', (e) => { - // console.log(e) - }) - this.videoSourceBuffer.addEventListener('error', (e) => { console.log(e) }) - this.videoSourceBuffer.addEventListener('abort', (e) => { - // console.log(e) - }) + this.videoSourceBuffer.addEventListener('abort', (e) => {}) + this.videoSourceBuffer.addEventListener('updatestart', (e) => {}) + this.videoSourceBuffer.addEventListener('update', (e) => {}) + this.videoSourceBuffer.addEventListener('updateend', (e) => {}) }) this.mediaSource.addEventListener('sourceended', (e) => { @@ -79,13 +66,8 @@ export const fileStore = defineStore('file', { this.buffer = [] }) - this.mediaSource.addEventListener('sourceclose', (e) => { - // console.log(e) - }) - - this.mediaSource.addEventListener('error', (e) => { - // console.log(e) - }) + this.mediaSource.addEventListener('sourceclose', (e) => {}) + this.mediaSource.addEventListener('error', (e) => {}) } this.appendInterval = setInterval(() => { @@ -97,12 +79,53 @@ export const fileStore = defineStore('file', { this.videoSourceBuffer.appendBuffer(this.buffer.shift()) this.appendCount++ - // console.log(`append count: ${this.appendCount}`) } }, 10) this.buffer.push(data) - // console.log(`buffer length: ${this.buffer.length}`) + } else if (mimeType.toLowerCase() === 'audio/mpeg') { + this.mediaSource = new MediaSource() + this.mediaUrl = URL.createObjectURL(this.mediaSource) + console.log(MediaSource.isTypeSupported(`audio/mpeg`)) + + this.mediaSource.addEventListener('sourceopen', () => { + this.audioSourceBuffer = this.mediaSource.addSourceBuffer(`audio/mpeg`) + this.audioSourceBuffer.addEventListener('error', (e) => { + console.log(e) + }) + + this.audioSourceBuffer.addEventListener('abort', (e) => {}) + this.audioSourceBuffer.addEventListener('updatestart', (e) => {}) + this.audioSourceBuffer.addEventListener('update', (e) => {}) + this.audioSourceBuffer.addEventListener('updateend', (e) => {}) + }) + + this.mediaSource.addEventListener('sourceended', (e) => { + this.mediaSource = null + this.audioSourceBuffer = null + this.videoSourceBuffer = null + + if (this.appendInterval) { + clearInterval(this.appendInterval) + this.appendInterval = null + } + + this.buffer = [] + }) + + this.appendInterval = setInterval(() => { + if ( + this.audioSourceBuffer && + !this.audioSourceBuffer.updating && + this.buffer.length > 0 + ) { + this.audioSourceBuffer.appendBuffer(this.buffer.shift()) + + this.appendCount++ + } + }, 10) + + this.buffer.push(data) } else { this.body = data } From 3ffa50baa82b19d856d5cfcabe7db126a58565d2 Mon Sep 17 00:00:00 2001 From: Jordan Rash <15827604+jordan-rash@users.noreply.github.com> Date: Mon, 4 Mar 2024 14:55:45 -0700 Subject: [PATCH 2/8] semi-working --- natster-io/src/stores/catalog.ts | 6 ++++-- natster-io/src/stores/file.ts | 16 ++++++++++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/natster-io/src/stores/catalog.ts b/natster-io/src/stores/catalog.ts index a4a2a9e..ac03094 100644 --- a/natster-io/src/stores/catalog.ts +++ b/natster-io/src/stores/catalog.ts @@ -201,7 +201,8 @@ export const catalogStore = defineStore('catalog', { const senderXKey = m.headers.get('x-natster-sender-xkey') let decrypted = xkey.open(m.data, senderXKey) - if (mimeType.toLowerCase().indexOf('video/') === 0) { + if (mimeType.toLowerCase().indexOf('video/') === 0 || mimeType.toLowerCase() == 'audio/mpeg') + { if (timeout) { clearTimeout(timeout) timeout = null @@ -215,7 +216,8 @@ export const catalogStore = defineStore('catalog', { sub.unsubscribe() }, 5000) - } else { + } + else { fStore.render(fileName, mimeType, new TextDecoder().decode(decrypted)) if (chunkIdx === totalChunks - 1) { diff --git a/natster-io/src/stores/file.ts b/natster-io/src/stores/file.ts index a380cac..736ec1b 100644 --- a/natster-io/src/stores/file.ts +++ b/natster-io/src/stores/file.ts @@ -94,10 +94,18 @@ export const fileStore = defineStore('file', { console.log(e) }) - this.audioSourceBuffer.addEventListener('abort', (e) => {}) - this.audioSourceBuffer.addEventListener('updatestart', (e) => {}) - this.audioSourceBuffer.addEventListener('update', (e) => {}) - this.audioSourceBuffer.addEventListener('updateend', (e) => {}) + this.audioSourceBuffer.addEventListener('abort', (e) => { + console.log(e) + }) + this.audioSourceBuffer.addEventListener('updatestart', (e) => { + console.log(e) + }) + this.audioSourceBuffer.addEventListener('update', (e) => { + console.log(e) + }) + this.audioSourceBuffer.addEventListener('updateend', (e) => { + console.log(e) + }) }) this.mediaSource.addEventListener('sourceended', (e) => { From ec758bac7a9c39271f8516faffb4acb070fc2481 Mon Sep 17 00:00:00 2001 From: kt Date: Mon, 4 Mar 2024 17:01:06 -0500 Subject: [PATCH 3/8] Handle audio/mpeg with known buffer length --- natster-io/src/stores/catalog.ts | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/natster-io/src/stores/catalog.ts b/natster-io/src/stores/catalog.ts index ac03094..8600ce4 100644 --- a/natster-io/src/stores/catalog.ts +++ b/natster-io/src/stores/catalog.ts @@ -201,8 +201,7 @@ export const catalogStore = defineStore('catalog', { const senderXKey = m.headers.get('x-natster-sender-xkey') let decrypted = xkey.open(m.data, senderXKey) - if (mimeType.toLowerCase().indexOf('video/') === 0 || mimeType.toLowerCase() == 'audio/mpeg') - { + if (mimeType.toLowerCase().indexOf('video/') === 0) { if (timeout) { clearTimeout(timeout) timeout = null @@ -216,9 +215,22 @@ export const catalogStore = defineStore('catalog', { sub.unsubscribe() }, 5000) - } - else { - fStore.render(fileName, mimeType, new TextDecoder().decode(decrypted)) + } else { + if (mimeType.toLowerCase() === 'audio/mpeg') { + if (timeout) { + clearTimeout(timeout) + timeout = null + } + + timeout = setTimeout(() => { + fStore.endStream() + timeout = null + + sub.unsubscribe() + }, 5000) + } else { + fStore.render(fileName, mimeType, new TextDecoder().decode(decrypted)) + } if (chunkIdx === totalChunks - 1) { sub.unsubscribe() From 1a718dacc765ed1292fed950847c88d7c74842b5 Mon Sep 17 00:00:00 2001 From: kt Date: Mon, 4 Mar 2024 17:02:10 -0500 Subject: [PATCH 4/8] Only unsubscribe once we receive all chunks for audio/mpeg --- natster-io/src/stores/catalog.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/natster-io/src/stores/catalog.ts b/natster-io/src/stores/catalog.ts index 8600ce4..5a88d99 100644 --- a/natster-io/src/stores/catalog.ts +++ b/natster-io/src/stores/catalog.ts @@ -225,8 +225,6 @@ export const catalogStore = defineStore('catalog', { timeout = setTimeout(() => { fStore.endStream() timeout = null - - sub.unsubscribe() }, 5000) } else { fStore.render(fileName, mimeType, new TextDecoder().decode(decrypted)) From 4898d8ea2ae7526a846c160e8d11f4b86632961b Mon Sep 17 00:00:00 2001 From: kt Date: Mon, 4 Mar 2024 17:06:11 -0500 Subject: [PATCH 5/8] Render audio chunks --- natster-io/src/stores/catalog.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/natster-io/src/stores/catalog.ts b/natster-io/src/stores/catalog.ts index 5a88d99..9953fe4 100644 --- a/natster-io/src/stores/catalog.ts +++ b/natster-io/src/stores/catalog.ts @@ -226,6 +226,8 @@ export const catalogStore = defineStore('catalog', { fStore.endStream() timeout = null }, 5000) + + fStore.render(fileName, mimeType, decrypted) } else { fStore.render(fileName, mimeType, new TextDecoder().decode(decrypted)) } From c109644c59f0fdfe517bcfc14f7b6f09f8d3ff39 Mon Sep 17 00:00:00 2001 From: kt Date: Mon, 4 Mar 2024 17:13:45 -0500 Subject: [PATCH 6/8] Only initialize media source once for audio --- natster-io/src/stores/file.ts | 108 ++++++++++++++++------------------ 1 file changed, 51 insertions(+), 57 deletions(-) diff --git a/natster-io/src/stores/file.ts b/natster-io/src/stores/file.ts index 736ec1b..30eacb5 100644 --- a/natster-io/src/stores/file.ts +++ b/natster-io/src/stores/file.ts @@ -68,70 +68,64 @@ export const fileStore = defineStore('file', { this.mediaSource.addEventListener('sourceclose', (e) => {}) this.mediaSource.addEventListener('error', (e) => {}) - } - - this.appendInterval = setInterval(() => { - if ( - this.videoSourceBuffer && - !this.videoSourceBuffer.updating && - this.buffer.length > 0 - ) { - this.videoSourceBuffer.appendBuffer(this.buffer.shift()) - this.appendCount++ - } - }, 10) + this.appendInterval = setInterval(() => { + if (this.videoSourceBuffer && !this.videoSourceBuffer.updating && this.buffer.length > 0) { + this.videoSourceBuffer.appendBuffer(this.buffer.shift()) + + this.appendCount++ + } + }, 10) + } this.buffer.push(data) } else if (mimeType.toLowerCase() === 'audio/mpeg') { - this.mediaSource = new MediaSource() - this.mediaUrl = URL.createObjectURL(this.mediaSource) - console.log(MediaSource.isTypeSupported(`audio/mpeg`)) - - this.mediaSource.addEventListener('sourceopen', () => { - this.audioSourceBuffer = this.mediaSource.addSourceBuffer(`audio/mpeg`) - this.audioSourceBuffer.addEventListener('error', (e) => { - console.log(e) - }) + if (!this.mediaSource && !this.mediaUrl && !this.audioSourceBuffer) { + this.mediaSource = new MediaSource() + this.mediaUrl = URL.createObjectURL(this.mediaSource) + console.log(MediaSource.isTypeSupported(`audio/mpeg`)) - this.audioSourceBuffer.addEventListener('abort', (e) => { - console.log(e) - }) - this.audioSourceBuffer.addEventListener('updatestart', (e) => { - console.log(e) - }) - this.audioSourceBuffer.addEventListener('update', (e) => { - console.log(e) + this.mediaSource.addEventListener('sourceopen', () => { + this.audioSourceBuffer = this.mediaSource.addSourceBuffer(`audio/mpeg`) + this.audioSourceBuffer.addEventListener('error', (e) => { + console.log(e) + }) + + this.audioSourceBuffer.addEventListener('abort', (e) => { + console.log(e) + }) + this.audioSourceBuffer.addEventListener('updatestart', (e) => { + console.log(e) + }) + this.audioSourceBuffer.addEventListener('update', (e) => { + console.log(e) + }) + this.audioSourceBuffer.addEventListener('updateend', (e) => { + console.log(e) + }) }) - this.audioSourceBuffer.addEventListener('updateend', (e) => { - console.log(e) + + this.mediaSource.addEventListener('sourceended', (e) => { + this.mediaSource = null + this.audioSourceBuffer = null + this.videoSourceBuffer = null + + if (this.appendInterval) { + clearInterval(this.appendInterval) + this.appendInterval = null + } + + this.buffer = [] }) - }) - - this.mediaSource.addEventListener('sourceended', (e) => { - this.mediaSource = null - this.audioSourceBuffer = null - this.videoSourceBuffer = null - - if (this.appendInterval) { - clearInterval(this.appendInterval) - this.appendInterval = null - } - - this.buffer = [] - }) - - this.appendInterval = setInterval(() => { - if ( - this.audioSourceBuffer && - !this.audioSourceBuffer.updating && - this.buffer.length > 0 - ) { - this.audioSourceBuffer.appendBuffer(this.buffer.shift()) - - this.appendCount++ - } - }, 10) + + this.appendInterval = setInterval(() => { + if (this.audioSourceBuffer && !this.audioSourceBuffer.updating && this.buffer.length > 0) { + this.audioSourceBuffer.appendBuffer(this.buffer.shift()) + + this.appendCount++ + } + }, 10) + } this.buffer.push(data) } else { From 51c13ff01ff37a98deb076b600c91a11a40fcaf4 Mon Sep 17 00:00:00 2001 From: kt Date: Mon, 4 Mar 2024 17:41:47 -0500 Subject: [PATCH 7/8] Fill local buffer when media buffer is full --- natster-io/src/stores/catalog.ts | 11 +--------- natster-io/src/stores/file.ts | 35 +++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/natster-io/src/stores/catalog.ts b/natster-io/src/stores/catalog.ts index 9953fe4..44c266c 100644 --- a/natster-io/src/stores/catalog.ts +++ b/natster-io/src/stores/catalog.ts @@ -217,22 +217,13 @@ export const catalogStore = defineStore('catalog', { }, 5000) } else { if (mimeType.toLowerCase() === 'audio/mpeg') { - if (timeout) { - clearTimeout(timeout) - timeout = null - } - - timeout = setTimeout(() => { - fStore.endStream() - timeout = null - }, 5000) - fStore.render(fileName, mimeType, decrypted) } else { fStore.render(fileName, mimeType, new TextDecoder().decode(decrypted)) } if (chunkIdx === totalChunks - 1) { + fStore.endStream() sub.unsubscribe() } } diff --git a/natster-io/src/stores/file.ts b/natster-io/src/stores/file.ts index 30eacb5..6120756 100644 --- a/natster-io/src/stores/file.ts +++ b/natster-io/src/stores/file.ts @@ -17,13 +17,21 @@ export const fileStore = defineStore('file', { videoSourceBuffer: null, appendCount: 0, - appendInterval: null + appendInterval: null, + streamEndInterval: null, }), actions: { endStream() { if (this.mediaSource) { - this.mediaSource.endOfStream() - console.log('stream ended') + this.streamEndInterval = setInterval(() => { + if (this.buffer.length === 0) { + clearInterval(this.streamEndInterval) + this.streamEndInterval = null + + this.mediaSource.endOfStream() + console.log('stream ended') + } + }, 100) } }, render(title, mimeType, data) { @@ -72,7 +80,6 @@ export const fileStore = defineStore('file', { this.appendInterval = setInterval(() => { if (this.videoSourceBuffer && !this.videoSourceBuffer.updating && this.buffer.length > 0) { this.videoSourceBuffer.appendBuffer(this.buffer.shift()) - this.appendCount++ } }, 10) @@ -118,11 +125,20 @@ export const fileStore = defineStore('file', { this.buffer = [] }) + const re = /sourcebuffer is full/i // FIXME? how does this work across browsers? + this.appendInterval = setInterval(() => { if (this.audioSourceBuffer && !this.audioSourceBuffer.updating && this.buffer.length > 0) { - this.audioSourceBuffer.appendBuffer(this.buffer.shift()) - - this.appendCount++ + const _data = this.buffer.shift() + + try { + this.audioSourceBuffer.appendBuffer(_data) + this.appendCount++ + } catch (e) { + if (e.toString().match(re)) { + this.buffer.unshift(_data) + } + } } }, 10) } @@ -138,6 +154,11 @@ export const fileStore = defineStore('file', { this.appendInterval = null } + if (this.streamEndInterval) { + clearInterval(this.streamEndInterval) + this.streamEndInterval = null + } + this.body = null this.buffer = [] this.codec = null From 17eada2947ff14a3a588c1f5c35e67b572a34436 Mon Sep 17 00:00:00 2001 From: Jordan Rash <15827604+jordan-rash@users.noreply.github.com> Date: Mon, 4 Mar 2024 16:33:11 -0700 Subject: [PATCH 8/8] make playback thing prettier --- natster-io/src/components/File.vue | 51 ++++++++++++++------------ natster-io/src/components/FileComp.vue | 15 ++++---- natster-io/src/stores/catalog.ts | 22 +++++++---- natster-io/src/stores/file.ts | 20 ++++++++-- 4 files changed, 65 insertions(+), 43 deletions(-) diff --git a/natster-io/src/components/File.vue b/natster-io/src/components/File.vue index 1c7cf96..5df32e8 100644 --- a/natster-io/src/components/File.vue +++ b/natster-io/src/components/File.vue @@ -40,37 +40,40 @@
-
-
- {{ - title - }} + + {{ catalog.name }} | {{ title }}

{{ body }}

- - -
+
+ + +