diff --git a/examples/nextjs-real-time-transcription/app/page.tsx b/examples/nextjs-real-time-transcription/app/page.tsx index bf95cb14..038b42df 100644 --- a/examples/nextjs-real-time-transcription/app/page.tsx +++ b/examples/nextjs-real-time-transcription/app/page.tsx @@ -2,11 +2,11 @@ import { getFeatures, RealtimeTranscriptionProvider, } from '@speechmatics/real-time-client-react'; -import { PCMAudioRecorderProvider } from '@speechmatics/browser-audio-input-react'; import type { Metadata } from 'next'; import { Controls } from '@/components/Controls'; import { Output } from '@/components/Output'; import { Status } from '@/components/Status'; +import { AudioProvider } from '@/components/AudioProvider'; export const metadata: Metadata = { title: 'Speechmatics Real-time example', @@ -21,7 +21,7 @@ export default async function Page() { ); return ( - +

Real-time Example

@@ -34,6 +34,6 @@ export default async function Page() {
-
+ ); } diff --git a/examples/nextjs-real-time-transcription/components/AudioProvider.tsx b/examples/nextjs-real-time-transcription/components/AudioProvider.tsx new file mode 100644 index 00000000..d8564a79 --- /dev/null +++ b/examples/nextjs-real-time-transcription/components/AudioProvider.tsx @@ -0,0 +1,18 @@ +'use client'; + +import { useAudioContext } from '@/lib/hooks/useAudioContext'; +import { PCMAudioRecorderProvider } from '@speechmatics/browser-audio-input-react'; +import type { PropsWithChildren } from 'react'; + +export function AudioProvider({ children }: PropsWithChildren) { + const audioContext = useAudioContext(); + + return ( + + {children} + + ); +} diff --git a/examples/nextjs-real-time-transcription/lib/hooks/useAudioContext.ts b/examples/nextjs-real-time-transcription/lib/hooks/useAudioContext.ts new file mode 100644 index 00000000..be88103e --- /dev/null +++ b/examples/nextjs-real-time-transcription/lib/hooks/useAudioContext.ts @@ -0,0 +1,36 @@ +import { useEffect, useMemo, useSyncExternalStore } from 'react'; +import { RECORDING_SAMPLE_RATE } from '../constants'; + +export function useAudioContext() { + const hydrated = useHydrated(); + const audioContext = useMemo( + () => + hydrated + ? new window.AudioContext({ sampleRate: RECORDING_SAMPLE_RATE }) + : undefined, + [hydrated], + ); + + useCleanupAudioContext(audioContext); + + return audioContext; +} + +// Lets us know if we're rendering client side or not +const useHydrated = () => + useSyncExternalStore( + () => () => {}, + () => true, + () => false, + ); + +// Close audio context when component unmounts +function useCleanupAudioContext(context?: AudioContext) { + useEffect(() => { + return () => { + if (context && context.state !== 'closed') { + context.close(); + } + }; + }, [context]); +} diff --git a/examples/nextjs-real-time-transcription/package.json b/examples/nextjs-real-time-transcription/package.json index d338842a..7ebc1959 100644 --- a/examples/nextjs-real-time-transcription/package.json +++ b/examples/nextjs-real-time-transcription/package.json @@ -24,8 +24,7 @@ }, "devDependencies": { "@types/node": "^20", - "@types/react": "^18", - "@types/react-dom": "^18", + "@types/react": "^19.0.10", "copy-webpack-plugin": "^12.0.2", "typescript": "^5" } diff --git a/packages/browser-audio-input-react/package.json b/packages/browser-audio-input-react/package.json index 09f453ab..41baa486 100644 --- a/packages/browser-audio-input-react/package.json +++ b/packages/browser-audio-input-react/package.json @@ -31,7 +31,7 @@ "react": "^18 || ^19" }, "devDependencies": { - "@types/react": "^18.3.12", + "@types/react": "^19.0.10", "typescript-event-target": "^1.1.1" } } diff --git a/packages/web-pcm-player-react/README.md b/packages/web-pcm-player-react/README.md index 6d024e41..453efd8b 100644 --- a/packages/web-pcm-player-react/README.md +++ b/packages/web-pcm-player-react/README.md @@ -70,4 +70,9 @@ export default function Index() { ); } -``` \ No newline at end of file +``` + + +## React context + +This \ No newline at end of file diff --git a/packages/web-pcm-player-react/package.json b/packages/web-pcm-player-react/package.json index 4fa93d9a..4220431d 100644 --- a/packages/web-pcm-player-react/package.json +++ b/packages/web-pcm-player-react/package.json @@ -24,7 +24,7 @@ "react": "^18 || ^19" }, "devDependencies": { - "@types/react": "^18.3.12", + "@types/react": "^19.0.10", "typescript-event-target": "^1.1.1" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a3e13bac..2772856a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -140,11 +140,8 @@ importers: specifier: ^20 version: 20.0.0 '@types/react': - specifier: ^18 - version: 18.3.12 - '@types/react-dom': - specifier: ^18 - version: 18.0.0 + specifier: ^19.0.10 + version: 19.0.10 copy-webpack-plugin: specifier: ^12.0.2 version: 12.0.2(webpack@5.96.1(esbuild@0.23.1)) @@ -311,8 +308,8 @@ importers: version: 18.0.0 devDependencies: '@types/react': - specifier: ^18.3.12 - version: 18.3.12 + specifier: ^19.0.10 + version: 19.0.10 typescript-event-target: specifier: ^1.1.1 version: 1.1.1 @@ -409,8 +406,8 @@ importers: version: 19.0.0 devDependencies: '@types/react': - specifier: ^18.3.12 - version: 18.3.12 + specifier: ^19.0.10 + version: 19.0.10 typescript-event-target: specifier: ^1.1.1 version: 1.1.1 @@ -2261,9 +2258,6 @@ packages: '@types/prop-types@15.7.13': resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==} - '@types/react-dom@18.0.0': - resolution: {integrity: sha512-49897Y0UiCGmxZqpC8Blrf6meL8QUla6eb+BBhn69dTXlmuOlzkfr7HHY/O8J25e1lTUMs+YYxSlVDAaGHCOLg==} - '@types/react-dom@19.0.3': resolution: {integrity: sha512-0Knk+HJiMP/qOZgMyNFamlIjw9OFCsyC2ZbigmEEyXXixgre6IQpm/4V+r3qH4GC1JPvRJKInw+on2rV6YZLeA==} peerDependencies: @@ -2275,6 +2269,9 @@ packages: '@types/react@18.3.12': resolution: {integrity: sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==} + '@types/react@19.0.10': + resolution: {integrity: sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==} + '@types/react@19.0.7': resolution: {integrity: sha512-MoFsEJKkAtZCrC1r6CM8U22GzhG7u2Wir8ons/aCKH6MBdD1ibV24zOSSkdZVUKqN5i396zG5VKLYZ3yaUZdLA==} @@ -8565,10 +8562,6 @@ snapshots: '@types/prop-types@15.7.13': {} - '@types/react-dom@18.0.0': - dependencies: - '@types/react': 18.3.12 - '@types/react-dom@19.0.3(@types/react@19.0.7)': dependencies: '@types/react': 19.0.7 @@ -8582,6 +8575,10 @@ snapshots: '@types/prop-types': 15.7.13 csstype: 3.1.3 + '@types/react@19.0.10': + dependencies: + csstype: 3.1.3 + '@types/react@19.0.7': dependencies: csstype: 3.1.3