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 }}
+