@siteed/expo-audio-studio 2.4.0 → 2.5.0

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.
Files changed (81) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/README.md +25 -0
  3. package/android/src/main/java/net/siteed/audiostream/AudioAnalysisData.kt +22 -0
  4. package/android/src/main/java/net/siteed/audiostream/AudioDeviceManager.kt +1501 -0
  5. package/android/src/main/java/net/siteed/audiostream/AudioFileHandler.kt +10 -5
  6. package/android/src/main/java/net/siteed/audiostream/AudioNotificationsManager.kt +27 -25
  7. package/android/src/main/java/net/siteed/audiostream/AudioProcessor.kt +73 -71
  8. package/android/src/main/java/net/siteed/audiostream/AudioRecorderManager.kt +581 -255
  9. package/android/src/main/java/net/siteed/audiostream/Constants.kt +17 -1
  10. package/android/src/main/java/net/siteed/audiostream/ExpoAudioStreamModule.kt +435 -158
  11. package/android/src/main/java/net/siteed/audiostream/LogUtils.kt +65 -0
  12. package/android/src/main/java/net/siteed/audiostream/PermissionUtils.kt +14 -5
  13. package/android/src/main/java/net/siteed/audiostream/RecordingConfig.kt +9 -1
  14. package/build/AudioAnalysis/AudioAnalysis.types.js.map +1 -1
  15. package/build/AudioDeviceManager.d.ts +107 -0
  16. package/build/AudioDeviceManager.d.ts.map +1 -0
  17. package/build/AudioDeviceManager.js +493 -0
  18. package/build/AudioDeviceManager.js.map +1 -0
  19. package/build/AudioRecorder.provider.d.ts.map +1 -1
  20. package/build/AudioRecorder.provider.js +3 -0
  21. package/build/AudioRecorder.provider.js.map +1 -1
  22. package/build/ExpoAudioStream.types.d.ts +90 -1
  23. package/build/ExpoAudioStream.types.d.ts.map +1 -1
  24. package/build/ExpoAudioStream.types.js +7 -1
  25. package/build/ExpoAudioStream.types.js.map +1 -1
  26. package/build/ExpoAudioStream.web.d.ts +37 -0
  27. package/build/ExpoAudioStream.web.d.ts.map +1 -1
  28. package/build/ExpoAudioStream.web.js +399 -54
  29. package/build/ExpoAudioStream.web.js.map +1 -1
  30. package/build/ExpoAudioStreamModule.d.ts.map +1 -1
  31. package/build/ExpoAudioStreamModule.js +20 -0
  32. package/build/ExpoAudioStreamModule.js.map +1 -1
  33. package/build/WebRecorder.web.d.ts +63 -10
  34. package/build/WebRecorder.web.d.ts.map +1 -1
  35. package/build/WebRecorder.web.js +277 -68
  36. package/build/WebRecorder.web.js.map +1 -1
  37. package/build/hooks/useAudioDevices.d.ts +14 -0
  38. package/build/hooks/useAudioDevices.d.ts.map +1 -0
  39. package/build/hooks/useAudioDevices.js +151 -0
  40. package/build/hooks/useAudioDevices.js.map +1 -0
  41. package/build/index.d.ts +2 -0
  42. package/build/index.d.ts.map +1 -1
  43. package/build/index.js +4 -0
  44. package/build/index.js.map +1 -1
  45. package/build/useAudioRecorder.d.ts +1 -0
  46. package/build/useAudioRecorder.d.ts.map +1 -1
  47. package/build/useAudioRecorder.js +20 -1
  48. package/build/useAudioRecorder.js.map +1 -1
  49. package/build/utils/BlobFix.d.ts.map +1 -1
  50. package/build/utils/BlobFix.js +2 -2
  51. package/build/utils/BlobFix.js.map +1 -1
  52. package/build/workers/InlineFeaturesExtractor.web.d.ts +1 -1
  53. package/build/workers/InlineFeaturesExtractor.web.d.ts.map +1 -1
  54. package/build/workers/InlineFeaturesExtractor.web.js +27 -26
  55. package/build/workers/InlineFeaturesExtractor.web.js.map +1 -1
  56. package/build/workers/inlineAudioWebWorker.web.d.ts +1 -1
  57. package/build/workers/inlineAudioWebWorker.web.d.ts.map +1 -1
  58. package/build/workers/inlineAudioWebWorker.web.js +25 -1
  59. package/build/workers/inlineAudioWebWorker.web.js.map +1 -1
  60. package/ios/AudioDeviceManager.swift +654 -0
  61. package/ios/AudioStreamManager.swift +964 -760
  62. package/ios/ExpoAudioStreamModule.swift +174 -19
  63. package/ios/Features.swift +1 -1
  64. package/ios/ISSUE_IOS.md +45 -0
  65. package/ios/Logger.swift +13 -1
  66. package/ios/RecordingSettings.swift +12 -0
  67. package/package.json +2 -2
  68. package/src/AudioAnalysis/AudioAnalysis.types.ts +2 -2
  69. package/src/AudioDeviceManager.ts +571 -0
  70. package/src/AudioRecorder.provider.tsx +3 -0
  71. package/src/ExpoAudioStream.types.ts +97 -1
  72. package/src/ExpoAudioStream.web.ts +513 -63
  73. package/src/ExpoAudioStreamModule.ts +23 -0
  74. package/src/WebRecorder.web.ts +346 -81
  75. package/src/hooks/useAudioDevices.ts +180 -0
  76. package/src/index.ts +6 -0
  77. package/src/types/crc-32.d.ts +6 -6
  78. package/src/useAudioRecorder.tsx +27 -1
  79. package/src/utils/BlobFix.ts +6 -4
  80. package/src/workers/InlineFeaturesExtractor.web.tsx +27 -26
  81. package/src/workers/inlineAudioWebWorker.web.tsx +25 -1
@@ -1 +1 @@
1
- {"version":3,"file":"useAudioRecorder.js","sourceRoot":"","sources":["../src/useAudioRecorder.tsx"],"names":[],"mappings":"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","sourcesContent":["// src/useAudioRecorder.ts\nimport { EventSubscription, Platform } from 'expo-modules-core'\nimport { useCallback, useEffect, useReducer, useRef } from 'react'\n\nimport { AudioAnalysis } from './AudioAnalysis/AudioAnalysis.types'\nimport {\n AudioDataEvent,\n AudioRecording,\n AudioStreamStatus,\n CompressionInfo,\n ConsoleLike,\n RecordingConfig,\n StartRecordingResult,\n} from './ExpoAudioStream.types'\nimport ExpoAudioStreamModule from './ExpoAudioStreamModule'\nimport {\n addAudioAnalysisListener,\n addAudioEventListener,\n AudioEventPayload,\n addRecordingInterruptionListener,\n} from './events'\n\nexport interface UseAudioRecorderProps {\n logger?: ConsoleLike\n audioWorkletUrl?: string\n featuresExtratorUrl?: string\n}\n\nexport interface UseAudioRecorderState {\n startRecording: (_: RecordingConfig) => Promise<StartRecordingResult>\n stopRecording: () => Promise<AudioRecording>\n pauseRecording: () => Promise<void>\n resumeRecording: () => Promise<void>\n isRecording: boolean\n isPaused: boolean\n durationMs: number\n size: number\n compression?: CompressionInfo\n analysisData?: AudioAnalysis\n}\n\ninterface RecorderReducerState {\n isRecording: boolean\n isPaused: boolean\n durationMs: number\n size: number\n compression?: CompressionInfo\n analysisData?: AudioAnalysis\n}\n\ntype RecorderAction =\n | { type: 'START' | 'STOP' | 'PAUSE' | 'RESUME' }\n | {\n type: 'UPDATE_RECORDING_STATE'\n payload: {\n isRecording: boolean\n isPaused: boolean\n }\n }\n | {\n type: 'UPDATE_STATUS'\n payload: {\n durationMs: number\n size: number\n compression?: CompressionInfo\n }\n }\n | { type: 'UPDATE_ANALYSIS'; payload: AudioAnalysis }\n\nconst defaultAnalysis: AudioAnalysis = {\n segmentDurationMs: 100,\n bitDepth: 32,\n numberOfChannels: 1,\n durationMs: 0,\n sampleRate: 44100,\n samples: 0,\n dataPoints: [],\n rmsRange: {\n min: Number.POSITIVE_INFINITY,\n max: Number.NEGATIVE_INFINITY,\n },\n amplitudeRange: {\n min: Number.POSITIVE_INFINITY,\n max: Number.NEGATIVE_INFINITY,\n },\n}\n\nfunction audioRecorderReducer(\n state: RecorderReducerState,\n action: RecorderAction\n): RecorderReducerState {\n switch (action.type) {\n case 'START':\n return {\n ...state,\n isRecording: true,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined,\n analysisData: defaultAnalysis,\n }\n case 'STOP':\n return {\n ...state,\n isRecording: false,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined,\n analysisData: undefined,\n }\n case 'PAUSE':\n return { ...state, isPaused: true, isRecording: false }\n case 'RESUME':\n return { ...state, isPaused: false, isRecording: true }\n case 'UPDATE_RECORDING_STATE':\n return {\n ...state,\n isPaused: action.payload.isPaused,\n isRecording: action.payload.isRecording,\n }\n case 'UPDATE_STATUS': {\n const newState = {\n ...state,\n durationMs: action.payload.durationMs,\n size: action.payload.size,\n compression: action.payload.compression\n ? {\n size: action.payload.compression.size,\n mimeType: action.payload.compression.mimeType,\n bitrate: action.payload.compression.bitrate,\n format: action.payload.compression.format,\n }\n : undefined,\n }\n return newState\n }\n case 'UPDATE_ANALYSIS':\n return {\n ...state,\n analysisData: action.payload,\n }\n default:\n return state\n }\n}\n\ninterface HandleAudioAnalysisProps {\n analysis: AudioAnalysis\n visualizationDuration: number\n}\n\nexport function useAudioRecorder({\n logger,\n audioWorkletUrl,\n featuresExtratorUrl,\n}: UseAudioRecorderProps = {}): UseAudioRecorderState {\n const [state, dispatch] = useReducer(audioRecorderReducer, {\n isRecording: false,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined,\n analysisData: undefined,\n })\n\n const startResultRef = useRef<StartRecordingResult | null>(null)\n\n const analysisListenerRef = useRef<EventSubscription | null>(null)\n // analysisRef is the current analysis data (last 10 seconds by default)\n const analysisRef = useRef<AudioAnalysis>({ ...defaultAnalysis })\n // fullAnalysisRef is the full analysis data (all data points)\n const fullAnalysisRef = useRef<AudioAnalysis>({\n ...defaultAnalysis,\n })\n\n // Instantiate the module for web with URLs\n const ExpoAudioStream =\n Platform.OS === 'web'\n ? ExpoAudioStreamModule({\n audioWorkletUrl,\n featuresExtratorUrl,\n logger,\n })\n : ExpoAudioStreamModule\n\n const onAudioStreamRef = useRef<\n ((_: AudioDataEvent) => Promise<void>) | null\n >(null)\n\n const stateRef = useRef({\n isRecording: false,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined as CompressionInfo | undefined,\n })\n\n const recordingConfigRef = useRef<RecordingConfig | null>(null)\n\n const handleAudioAnalysis = useCallback(\n async ({\n analysis,\n visualizationDuration,\n }: HandleAudioAnalysisProps) => {\n const savedAnalysisData = analysisRef.current || {\n ...defaultAnalysis,\n }\n\n const maxDuration = visualizationDuration\n\n logger?.debug(\n `[handleAudioAnalysis] Received audio analysis: maxDuration=${maxDuration} analysis.dataPoints=${analysis.dataPoints.length} analysisData.dataPoints=${savedAnalysisData.dataPoints.length}`,\n analysis\n )\n\n // Combine data points\n const combinedDataPoints = [\n ...savedAnalysisData.dataPoints,\n ...analysis.dataPoints,\n ]\n\n const fullCombinedDataPoints = [\n ...(fullAnalysisRef.current?.dataPoints ?? []),\n ...analysis.dataPoints,\n ]\n\n // Calculate the new duration\n // The number of segments is based on how many segments of segmentDurationMs can fit in visualizationDuration\n const numberOfSegments = Math.ceil(\n visualizationDuration / analysis.segmentDurationMs\n )\n // maxDataPoints should be the number of data points, not milliseconds\n const maxDataPoints = numberOfSegments\n\n logger?.debug(\n `[handleAudioAnalysis] Combined data points before trimming: numberOfSegments=${numberOfSegments} visualizationDuration=${visualizationDuration} combinedDataPointsLength=${combinedDataPoints.length} vs maxDataPoints=${maxDataPoints}`\n )\n\n // Trim data points to keep within the maximum number of data points\n if (combinedDataPoints.length > maxDataPoints) {\n combinedDataPoints.splice(\n 0,\n combinedDataPoints.length - maxDataPoints\n )\n }\n\n // Keep the full data points\n fullAnalysisRef.current = {\n ...fullAnalysisRef.current,\n dataPoints: fullCombinedDataPoints,\n }\n fullAnalysisRef.current.durationMs =\n fullCombinedDataPoints.length * analysis.segmentDurationMs\n savedAnalysisData.dataPoints = combinedDataPoints\n savedAnalysisData.bitDepth =\n analysis.bitDepth || savedAnalysisData.bitDepth\n savedAnalysisData.durationMs =\n combinedDataPoints.length * analysis.segmentDurationMs\n\n // Update amplitude range\n const newMin = Math.min(\n savedAnalysisData.amplitudeRange.min,\n analysis.amplitudeRange.min\n )\n const newMax = Math.max(\n savedAnalysisData.amplitudeRange.max,\n analysis.amplitudeRange.max\n )\n\n savedAnalysisData.amplitudeRange = {\n min: newMin,\n max: newMax,\n }\n fullAnalysisRef.current.amplitudeRange = {\n min: newMin,\n max: newMax,\n }\n\n logger?.debug(\n `[handleAudioAnalysis] Updated analysis data: durationMs=${savedAnalysisData.durationMs}`,\n savedAnalysisData\n )\n\n // Call the onAudioAnalysis callback if it exists in the recording config\n if (recordingConfigRef.current?.onAudioAnalysis) {\n recordingConfigRef.current\n .onAudioAnalysis(analysis)\n .catch((error) => {\n logger?.warn(`Error processing audio analysis:`, error)\n })\n }\n\n // Update the ref\n analysisRef.current = savedAnalysisData\n\n // Dispatch the updated analysis data to state to trigger re-render\n dispatch({\n type: 'UPDATE_ANALYSIS',\n payload: { ...savedAnalysisData },\n })\n },\n [dispatch]\n )\n\n const handleAudioEvent = useCallback(\n async (eventData: AudioEventPayload) => {\n const {\n fileUri,\n deltaSize,\n totalSize,\n lastEmittedSize,\n position,\n streamUuid,\n encoded,\n mimeType,\n buffer,\n compression,\n } = eventData\n logger?.debug(`[handleAudioEvent] Received audio event:`, {\n fileUri,\n deltaSize,\n totalSize,\n position,\n mimeType,\n lastEmittedSize,\n streamUuid,\n encodedLength: encoded?.length,\n compression,\n })\n if (deltaSize === 0) {\n // Ignore packet with no data\n return\n }\n try {\n // Coming from native ( ios / android ) otherwise buffer is set\n if (Platform.OS !== 'web') {\n // Read the audio file as a base64 string for comparison\n if (!encoded) {\n logger?.error(`Encoded audio data is missing`)\n throw new Error('Encoded audio data is missing')\n }\n onAudioStreamRef.current?.({\n data: encoded,\n position,\n fileUri,\n eventDataSize: deltaSize,\n totalSize,\n compression:\n compression && startResultRef.current?.compression\n ? {\n data: compression.data,\n size: compression.totalSize,\n mimeType:\n startResultRef.current.compression\n ?.mimeType,\n bitrate:\n startResultRef.current.compression\n ?.bitrate,\n format: startResultRef.current.compression\n ?.format,\n }\n : undefined,\n })\n } else if (buffer) {\n // Coming from web\n const webEvent: AudioDataEvent = {\n data: buffer,\n position,\n fileUri,\n eventDataSize: deltaSize,\n totalSize,\n compression:\n compression && startResultRef.current?.compression\n ? {\n data: compression.data,\n size: compression.totalSize,\n mimeType:\n startResultRef.current.compression\n ?.mimeType,\n bitrate:\n startResultRef.current.compression\n ?.bitrate,\n format: startResultRef.current.compression\n ?.format,\n }\n : undefined,\n }\n onAudioStreamRef.current?.(webEvent)\n logger?.debug(\n `[handleAudioEvent] Audio data sent to onAudioStream`,\n webEvent\n )\n }\n } catch (error) {\n logger?.error(`Error processing audio event:`, error)\n }\n },\n []\n )\n\n const checkStatus = useCallback(async () => {\n try {\n const status: AudioStreamStatus = ExpoAudioStream.status()\n logger?.debug(\n `Status: paused: ${status.isPaused} isRecording: ${status.isRecording} durationMs: ${status.durationMs} size: ${status.size}`,\n status.compression\n )\n\n // Only dispatch if values actually changed\n if (\n status.isRecording !== stateRef.current.isRecording ||\n status.isPaused !== stateRef.current.isPaused\n ) {\n stateRef.current.isRecording = status.isRecording\n stateRef.current.isPaused = status.isPaused\n dispatch({\n type: 'UPDATE_RECORDING_STATE',\n payload: {\n isRecording: status.isRecording,\n isPaused: status.isPaused,\n },\n })\n }\n\n if (\n status.durationMs !== stateRef.current.durationMs ||\n status.size !== stateRef.current.size\n ) {\n stateRef.current.durationMs = status.durationMs\n stateRef.current.size = status.size\n stateRef.current.compression = status.compression\n dispatch({\n type: 'UPDATE_STATUS',\n payload: {\n durationMs: status.durationMs,\n size: status.size,\n compression: status.compression,\n },\n })\n }\n } catch (error) {\n logger?.error(`Error getting status:`, error)\n }\n }, [ExpoAudioStream, logger]) // Only depend on ExpoAudioStream and logger\n\n // Update ref when state changes\n useEffect(() => {\n stateRef.current = {\n isRecording: state.isRecording,\n isPaused: state.isPaused,\n durationMs: state.durationMs,\n size: state.size,\n compression: state.compression,\n }\n }, [\n state.isRecording,\n state.isPaused,\n state.durationMs,\n state.size,\n state.compression,\n ])\n\n const startRecording = useCallback(\n async (recordingOptions: RecordingConfig) => {\n recordingConfigRef.current = recordingOptions\n logger?.debug(`start recoding`, recordingOptions)\n\n analysisRef.current = { ...defaultAnalysis } // Reset analysis data\n fullAnalysisRef.current = { ...defaultAnalysis }\n const { onAudioStream, ...options } = recordingOptions\n const { enableProcessing } = options\n\n const maxRecentDataDuration = 10000 // TODO compute maxRecentDataDuration based on screen dimensions\n if (typeof onAudioStream === 'function') {\n onAudioStreamRef.current = onAudioStream\n } else {\n logger?.warn(`onAudioStream is not a function`, onAudioStream)\n onAudioStreamRef.current = null\n }\n const startResult: StartRecordingResult =\n await ExpoAudioStream.startRecording(options)\n dispatch({ type: 'START' })\n\n startResultRef.current = startResult\n\n if (enableProcessing) {\n logger?.debug(`Enabling audio analysis listener`)\n const listener = addAudioAnalysisListener(\n async (analysisData) => {\n try {\n await handleAudioAnalysis({\n analysis: analysisData,\n visualizationDuration: maxRecentDataDuration,\n })\n } catch (error) {\n logger?.warn(\n `Error processing audio analysis:`,\n error\n )\n }\n }\n )\n\n analysisListenerRef.current = listener\n }\n\n return startResult\n },\n [handleAudioAnalysis, dispatch]\n )\n\n const stopRecording = useCallback(async () => {\n logger?.debug(`stoping recording`)\n\n const stopResult: AudioRecording = await ExpoAudioStream.stopRecording()\n stopResult.analysisData = fullAnalysisRef.current\n\n if (analysisListenerRef.current) {\n analysisListenerRef.current.remove()\n analysisListenerRef.current = null\n }\n onAudioStreamRef.current = null\n logger?.debug(`recording stopped`, stopResult)\n dispatch({ type: 'STOP' })\n return stopResult\n }, [dispatch])\n\n const pauseRecording = useCallback(async () => {\n logger?.debug(`pause recording`)\n const pauseResult = await ExpoAudioStream.pauseRecording()\n dispatch({ type: 'PAUSE' })\n return pauseResult\n }, [dispatch])\n\n const resumeRecording = useCallback(async () => {\n logger?.debug(`resume recording`)\n const resumeResult = await ExpoAudioStream.resumeRecording()\n dispatch({ type: 'RESUME' })\n return resumeResult\n }, [dispatch])\n\n useEffect(() => {\n let intervalId: NodeJS.Timeout | undefined\n\n if (state.isRecording || state.isPaused) {\n // Immediately check status when starting\n checkStatus()\n\n // Start interval\n intervalId = setInterval(checkStatus, 1000)\n }\n\n return () => {\n if (intervalId) {\n clearInterval(intervalId)\n intervalId = undefined\n }\n }\n }, [checkStatus, state.isRecording, state.isPaused])\n\n useEffect(() => {\n logger?.debug(`Registering audio event listener`)\n const subscribeAudio = addAudioEventListener(handleAudioEvent)\n\n logger?.debug(\n `Subscribed to audio event listener and analysis listener`,\n {\n subscribeAudio,\n }\n )\n\n return () => {\n logger?.debug(`Removing audio event listener`)\n subscribeAudio.remove()\n }\n }, [handleAudioEvent, handleAudioAnalysis])\n\n useEffect(() => {\n // Add event subscription for recording interruptions\n logger?.debug('Setting up recording interruption listener')\n\n const subscription = addRecordingInterruptionListener((event) => {\n logger?.debug('Received recording interruption event:', event)\n\n // Check if we have a callback configured\n if (recordingConfigRef.current?.onRecordingInterrupted) {\n try {\n recordingConfigRef.current.onRecordingInterrupted(event)\n } catch (error) {\n logger?.error(\n 'Error in recording interruption callback:',\n error\n )\n }\n } else {\n logger?.warn('No recording interruption callback configured')\n }\n })\n\n return () => {\n logger?.debug('Removing recording interruption listener')\n subscription.remove()\n }\n }, []) // Empty dependency array since we want this to run once\n\n return {\n startRecording,\n stopRecording,\n pauseRecording,\n resumeRecording,\n isPaused: state.isPaused,\n isRecording: state.isRecording,\n durationMs: state.durationMs,\n size: state.size,\n compression: state.compression,\n analysisData: state.analysisData,\n }\n}\n"]}
1
+ {"version":3,"file":"useAudioRecorder.js","sourceRoot":"","sources":["../src/useAudioRecorder.tsx"],"names":[],"mappings":"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","sourcesContent":["// src/useAudioRecorder.ts\nimport { EventSubscription, Platform } from 'expo-modules-core'\nimport { useCallback, useEffect, useReducer, useRef } from 'react'\n\nimport { AudioAnalysis } from './AudioAnalysis/AudioAnalysis.types'\nimport {\n AudioDataEvent,\n AudioRecording,\n AudioStreamStatus,\n CompressionInfo,\n ConsoleLike,\n RecordingConfig,\n StartRecordingResult,\n} from './ExpoAudioStream.types'\nimport ExpoAudioStreamModule from './ExpoAudioStreamModule'\nimport {\n addAudioAnalysisListener,\n addAudioEventListener,\n AudioEventPayload,\n addRecordingInterruptionListener,\n} from './events'\n\nexport interface UseAudioRecorderProps {\n logger?: ConsoleLike\n audioWorkletUrl?: string\n featuresExtratorUrl?: string\n}\n\nexport interface UseAudioRecorderState {\n prepareRecording: (_: RecordingConfig) => Promise<void>\n startRecording: (_: RecordingConfig) => Promise<StartRecordingResult>\n stopRecording: () => Promise<AudioRecording>\n pauseRecording: () => Promise<void>\n resumeRecording: () => Promise<void>\n isRecording: boolean\n isPaused: boolean\n durationMs: number\n size: number\n compression?: CompressionInfo\n analysisData?: AudioAnalysis\n}\n\ninterface RecorderReducerState {\n isRecording: boolean\n isPaused: boolean\n durationMs: number\n size: number\n compression?: CompressionInfo\n analysisData?: AudioAnalysis\n}\n\ntype RecorderAction =\n | { type: 'START' | 'STOP' | 'PAUSE' | 'RESUME' }\n | {\n type: 'UPDATE_RECORDING_STATE'\n payload: {\n isRecording: boolean\n isPaused: boolean\n }\n }\n | {\n type: 'UPDATE_STATUS'\n payload: {\n durationMs: number\n size: number\n compression?: CompressionInfo\n }\n }\n | { type: 'UPDATE_ANALYSIS'; payload: AudioAnalysis }\n\nconst defaultAnalysis: AudioAnalysis = {\n segmentDurationMs: 100,\n bitDepth: 32,\n numberOfChannels: 1,\n durationMs: 0,\n sampleRate: 44100,\n samples: 0,\n dataPoints: [],\n rmsRange: {\n min: Number.POSITIVE_INFINITY,\n max: Number.NEGATIVE_INFINITY,\n },\n amplitudeRange: {\n min: Number.POSITIVE_INFINITY,\n max: Number.NEGATIVE_INFINITY,\n },\n}\n\nfunction audioRecorderReducer(\n state: RecorderReducerState,\n action: RecorderAction\n): RecorderReducerState {\n switch (action.type) {\n case 'START':\n return {\n ...state,\n isRecording: true,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined,\n analysisData: defaultAnalysis,\n }\n case 'STOP':\n return {\n ...state,\n isRecording: false,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined,\n analysisData: undefined,\n }\n case 'PAUSE':\n return { ...state, isPaused: true, isRecording: false }\n case 'RESUME':\n return { ...state, isPaused: false, isRecording: true }\n case 'UPDATE_RECORDING_STATE':\n return {\n ...state,\n isPaused: action.payload.isPaused,\n isRecording: action.payload.isRecording,\n }\n case 'UPDATE_STATUS': {\n const newState = {\n ...state,\n durationMs: action.payload.durationMs,\n size: action.payload.size,\n compression: action.payload.compression\n ? {\n size: action.payload.compression.size,\n mimeType: action.payload.compression.mimeType,\n bitrate: action.payload.compression.bitrate,\n format: action.payload.compression.format,\n }\n : undefined,\n }\n return newState\n }\n case 'UPDATE_ANALYSIS':\n return {\n ...state,\n analysisData: action.payload,\n }\n default:\n return state\n }\n}\n\ninterface HandleAudioAnalysisProps {\n analysis: AudioAnalysis\n visualizationDuration: number\n}\n\nexport function useAudioRecorder({\n logger,\n audioWorkletUrl,\n featuresExtratorUrl,\n}: UseAudioRecorderProps = {}): UseAudioRecorderState {\n const [state, dispatch] = useReducer(audioRecorderReducer, {\n isRecording: false,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined,\n analysisData: undefined,\n })\n\n const startResultRef = useRef<StartRecordingResult | null>(null)\n\n const analysisListenerRef = useRef<EventSubscription | null>(null)\n // analysisRef is the current analysis data (last 10 seconds by default)\n const analysisRef = useRef<AudioAnalysis>({ ...defaultAnalysis })\n // fullAnalysisRef is the full analysis data (all data points)\n const fullAnalysisRef = useRef<AudioAnalysis>({\n ...defaultAnalysis,\n })\n\n // Instantiate the module for web with URLs\n const ExpoAudioStream =\n Platform.OS === 'web'\n ? ExpoAudioStreamModule({\n audioWorkletUrl,\n featuresExtratorUrl,\n logger,\n })\n : ExpoAudioStreamModule\n\n const onAudioStreamRef = useRef<\n ((_: AudioDataEvent) => Promise<void>) | null\n >(null)\n\n const stateRef = useRef({\n isRecording: false,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined as CompressionInfo | undefined,\n })\n\n const recordingConfigRef = useRef<RecordingConfig | null>(null)\n\n const handleAudioAnalysis = useCallback(\n async ({\n analysis,\n visualizationDuration,\n }: HandleAudioAnalysisProps) => {\n const savedAnalysisData = analysisRef.current || {\n ...defaultAnalysis,\n }\n\n const maxDuration = visualizationDuration\n\n logger?.debug(\n `[handleAudioAnalysis] Received audio analysis: maxDuration=${maxDuration} analysis.dataPoints=${analysis.dataPoints.length} analysisData.dataPoints=${savedAnalysisData.dataPoints.length}`,\n analysis\n )\n\n // Combine data points\n const combinedDataPoints = [\n ...savedAnalysisData.dataPoints,\n ...analysis.dataPoints,\n ]\n\n const fullCombinedDataPoints = [\n ...(fullAnalysisRef.current?.dataPoints ?? []),\n ...analysis.dataPoints,\n ]\n\n // Calculate the new duration\n // The number of segments is based on how many segments of segmentDurationMs can fit in visualizationDuration\n const numberOfSegments = Math.ceil(\n visualizationDuration / analysis.segmentDurationMs\n )\n // maxDataPoints should be the number of data points, not milliseconds\n const maxDataPoints = numberOfSegments\n\n logger?.debug(\n `[handleAudioAnalysis] Combined data points before trimming: numberOfSegments=${numberOfSegments} visualizationDuration=${visualizationDuration} combinedDataPointsLength=${combinedDataPoints.length} vs maxDataPoints=${maxDataPoints}`\n )\n\n // Trim data points to keep within the maximum number of data points\n if (combinedDataPoints.length > maxDataPoints) {\n combinedDataPoints.splice(\n 0,\n combinedDataPoints.length - maxDataPoints\n )\n }\n\n // Keep the full data points\n fullAnalysisRef.current = {\n ...fullAnalysisRef.current,\n dataPoints: fullCombinedDataPoints,\n }\n fullAnalysisRef.current.durationMs =\n fullCombinedDataPoints.length * analysis.segmentDurationMs\n savedAnalysisData.dataPoints = combinedDataPoints\n savedAnalysisData.bitDepth =\n analysis.bitDepth || savedAnalysisData.bitDepth\n savedAnalysisData.durationMs =\n combinedDataPoints.length * analysis.segmentDurationMs\n\n // Update amplitude range\n const newMin = Math.min(\n savedAnalysisData.amplitudeRange.min,\n analysis.amplitudeRange.min\n )\n const newMax = Math.max(\n savedAnalysisData.amplitudeRange.max,\n analysis.amplitudeRange.max\n )\n\n savedAnalysisData.amplitudeRange = {\n min: newMin,\n max: newMax,\n }\n fullAnalysisRef.current.amplitudeRange = {\n min: newMin,\n max: newMax,\n }\n\n logger?.debug(\n `[handleAudioAnalysis] Updated analysis data: durationMs=${savedAnalysisData.durationMs}`,\n { dataPoints: savedAnalysisData.dataPoints.length }\n )\n\n // Call the onAudioAnalysis callback if it exists in the recording config\n if (recordingConfigRef.current?.onAudioAnalysis) {\n recordingConfigRef.current\n .onAudioAnalysis(analysis)\n .catch((error) => {\n logger?.warn(`Error processing audio analysis:`, error)\n })\n }\n\n // Update the ref\n analysisRef.current = savedAnalysisData\n\n // Dispatch the updated analysis data to state to trigger re-render\n dispatch({\n type: 'UPDATE_ANALYSIS',\n payload: { ...savedAnalysisData },\n })\n },\n [dispatch]\n )\n\n const handleAudioEvent = useCallback(\n async (eventData: AudioEventPayload) => {\n const {\n fileUri,\n deltaSize,\n totalSize,\n lastEmittedSize,\n position,\n streamUuid,\n encoded,\n mimeType,\n buffer,\n compression,\n } = eventData\n logger?.debug(`[handleAudioEvent] Received audio event:`, {\n fileUri,\n deltaSize,\n totalSize,\n position,\n mimeType,\n lastEmittedSize,\n streamUuid,\n encodedLength: encoded?.length,\n compression,\n })\n if (deltaSize === 0) {\n // Ignore packet with no data\n return\n }\n try {\n // Coming from native ( ios / android ) otherwise buffer is set\n if (Platform.OS !== 'web') {\n // Read the audio file as a base64 string for comparison\n if (!encoded) {\n logger?.error(`Encoded audio data is missing`)\n throw new Error('Encoded audio data is missing')\n }\n onAudioStreamRef.current?.({\n data: encoded,\n position,\n fileUri,\n eventDataSize: deltaSize,\n totalSize,\n compression:\n compression && startResultRef.current?.compression\n ? {\n data: compression.data,\n size: compression.totalSize,\n mimeType:\n startResultRef.current.compression\n ?.mimeType,\n bitrate:\n startResultRef.current.compression\n ?.bitrate,\n format: startResultRef.current.compression\n ?.format,\n }\n : undefined,\n })\n } else if (buffer) {\n // Coming from web\n const webEvent: AudioDataEvent = {\n data: buffer,\n position,\n fileUri,\n eventDataSize: deltaSize,\n totalSize,\n compression:\n compression && startResultRef.current?.compression\n ? {\n data: compression.data,\n size: compression.totalSize,\n mimeType:\n startResultRef.current.compression\n ?.mimeType,\n bitrate:\n startResultRef.current.compression\n ?.bitrate,\n format: startResultRef.current.compression\n ?.format,\n }\n : undefined,\n }\n onAudioStreamRef.current?.(webEvent)\n logger?.debug(\n `[handleAudioEvent] Audio data sent to onAudioStream`,\n webEvent\n )\n }\n } catch (error) {\n logger?.error(`Error processing audio event:`, error)\n }\n },\n []\n )\n\n const checkStatus = useCallback(async () => {\n try {\n const status: AudioStreamStatus = ExpoAudioStream.status()\n logger?.debug(\n `Status: paused: ${status.isPaused} isRecording: ${status.isRecording} durationMs: ${status.durationMs} size: ${status.size}`,\n status.compression\n )\n\n // Only dispatch if values actually changed\n if (\n status.isRecording !== stateRef.current.isRecording ||\n status.isPaused !== stateRef.current.isPaused\n ) {\n stateRef.current.isRecording = status.isRecording\n stateRef.current.isPaused = status.isPaused\n dispatch({\n type: 'UPDATE_RECORDING_STATE',\n payload: {\n isRecording: status.isRecording,\n isPaused: status.isPaused,\n },\n })\n }\n\n if (\n status.durationMs !== stateRef.current.durationMs ||\n status.size !== stateRef.current.size\n ) {\n stateRef.current.durationMs = status.durationMs\n stateRef.current.size = status.size\n stateRef.current.compression = status.compression\n dispatch({\n type: 'UPDATE_STATUS',\n payload: {\n durationMs: status.durationMs,\n size: status.size,\n compression: status.compression,\n },\n })\n }\n } catch (error) {\n logger?.error(`Error getting status:`, error)\n }\n }, [ExpoAudioStream, logger]) // Only depend on ExpoAudioStream and logger\n\n // Update ref when state changes\n useEffect(() => {\n stateRef.current = {\n isRecording: state.isRecording,\n isPaused: state.isPaused,\n durationMs: state.durationMs,\n size: state.size,\n compression: state.compression,\n }\n }, [\n state.isRecording,\n state.isPaused,\n state.durationMs,\n state.size,\n state.compression,\n ])\n\n const startRecording = useCallback(\n async (recordingOptions: RecordingConfig) => {\n recordingConfigRef.current = recordingOptions\n logger?.debug(`start recoding`, recordingOptions)\n\n analysisRef.current = { ...defaultAnalysis } // Reset analysis data\n fullAnalysisRef.current = { ...defaultAnalysis }\n const { onAudioStream, ...options } = recordingOptions\n const { enableProcessing } = options\n\n const maxRecentDataDuration = 10000 // TODO compute maxRecentDataDuration based on screen dimensions\n if (typeof onAudioStream === 'function') {\n onAudioStreamRef.current = onAudioStream\n } else {\n logger?.warn(`onAudioStream is not a function`, onAudioStream)\n onAudioStreamRef.current = null\n }\n const startResult: StartRecordingResult =\n await ExpoAudioStream.startRecording(options)\n dispatch({ type: 'START' })\n\n startResultRef.current = startResult\n\n if (enableProcessing) {\n logger?.debug(`Enabling audio analysis listener`)\n const listener = addAudioAnalysisListener(\n async (analysisData) => {\n try {\n await handleAudioAnalysis({\n analysis: analysisData,\n visualizationDuration: maxRecentDataDuration,\n })\n } catch (error) {\n logger?.warn(\n `Error processing audio analysis:`,\n error\n )\n }\n }\n )\n\n analysisListenerRef.current = listener\n }\n\n return startResult\n },\n [handleAudioAnalysis, dispatch]\n )\n\n const prepareRecording = useCallback(\n async (recordingOptions: RecordingConfig) => {\n recordingConfigRef.current = recordingOptions\n logger?.debug(`preparing recording`, recordingOptions)\n\n analysisRef.current = { ...defaultAnalysis } // Reset analysis data\n fullAnalysisRef.current = { ...defaultAnalysis }\n const { onAudioStream, ...options } = recordingOptions\n\n // Store onAudioStream for later use when recording starts\n if (typeof onAudioStream === 'function') {\n onAudioStreamRef.current = onAudioStream\n } else {\n logger?.warn(`onAudioStream is not a function`, onAudioStream)\n onAudioStreamRef.current = null\n }\n\n // Call the native prepareRecording method\n await ExpoAudioStream.prepareRecording(options)\n logger?.debug(`recording prepared successfully`)\n },\n []\n )\n\n const stopRecording = useCallback(async () => {\n logger?.debug(`stoping recording`)\n\n const stopResult: AudioRecording = await ExpoAudioStream.stopRecording()\n stopResult.analysisData = fullAnalysisRef.current\n\n if (analysisListenerRef.current) {\n analysisListenerRef.current.remove()\n analysisListenerRef.current = null\n }\n onAudioStreamRef.current = null\n logger?.debug(`recording stopped`, stopResult)\n dispatch({ type: 'STOP' })\n return stopResult\n }, [dispatch])\n\n const pauseRecording = useCallback(async () => {\n logger?.debug(`pause recording`)\n const pauseResult = await ExpoAudioStream.pauseRecording()\n dispatch({ type: 'PAUSE' })\n return pauseResult\n }, [dispatch])\n\n const resumeRecording = useCallback(async () => {\n logger?.debug(`resume recording`)\n const resumeResult = await ExpoAudioStream.resumeRecording()\n dispatch({ type: 'RESUME' })\n return resumeResult\n }, [dispatch])\n\n useEffect(() => {\n let intervalId: NodeJS.Timeout | undefined\n\n if (state.isRecording || state.isPaused) {\n // Immediately check status when starting\n checkStatus()\n\n // Start interval\n intervalId = setInterval(checkStatus, 1000)\n }\n\n return () => {\n if (intervalId) {\n clearInterval(intervalId)\n intervalId = undefined\n }\n }\n }, [checkStatus, state.isRecording, state.isPaused])\n\n useEffect(() => {\n logger?.debug(`Registering audio event listener`)\n const subscribeAudio = addAudioEventListener(handleAudioEvent)\n\n logger?.debug(\n `Subscribed to audio event listener and analysis listener`,\n {\n subscribeAudio,\n }\n )\n\n return () => {\n logger?.debug(`Removing audio event listener`)\n subscribeAudio.remove()\n }\n }, [handleAudioEvent, handleAudioAnalysis])\n\n useEffect(() => {\n // Add event subscription for recording interruptions\n logger?.debug('Setting up recording interruption listener')\n\n const subscription = addRecordingInterruptionListener((event) => {\n logger?.debug('Received recording interruption event:', event)\n\n // Check if we have a callback configured\n if (recordingConfigRef.current?.onRecordingInterrupted) {\n try {\n recordingConfigRef.current.onRecordingInterrupted(event)\n } catch (error) {\n logger?.error(\n 'Error in recording interruption callback:',\n error\n )\n }\n } else {\n logger?.warn('No recording interruption callback configured')\n }\n })\n\n return () => {\n logger?.debug('Removing recording interruption listener')\n subscription.remove()\n }\n }, []) // Empty dependency array since we want this to run once\n\n return {\n prepareRecording,\n startRecording,\n stopRecording,\n pauseRecording,\n resumeRecording,\n isPaused: state.isPaused,\n isRecording: state.isRecording,\n durationMs: state.durationMs,\n size: state.size,\n compression: state.compression,\n analysisData: state.analysisData,\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"BlobFix.d.ts","sourceRoot":"","sources":["../../src/utils/BlobFix.ts"],"names":[],"mappings":"AAugBA;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,SAClB,IAAI,YACA,MAAM,oBAEjB,QAAQ,IAAI,CA4Bd,CAAA"}
1
+ {"version":3,"file":"BlobFix.d.ts","sourceRoot":"","sources":["../../src/utils/BlobFix.ts"],"names":[],"mappings":"AAygBA;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,SAClB,IAAI,YACA,MAAM,oBAEjB,QAAQ,IAAI,CA4Bd,CAAA"}
@@ -236,10 +236,10 @@ const sections = {
236
236
  0x485: { name: 'TagBinary', type: 'Binary' },
237
237
  };
238
238
  class WebmBase {
239
- name;
240
- type;
241
239
  source;
242
240
  data;
241
+ name;
242
+ type;
243
243
  constructor(name = 'Unknown', type = 'Unknown') {
244
244
  this.name = name;
245
245
  this.type = type;
@@ -1 +1 @@
1
- {"version":3,"file":"BlobFix.js","sourceRoot":"","sources":["../../src/utils/BlobFix.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * There is a bug where `navigator.mediaDevices.getUserMedia` + `MediaRecorder`\n * creates WEBM files without duration metadata. See:\n * - https://bugs.chromium.org/p/chromium/issues/detail?id=642012\n * - https://stackoverflow.com/a/39971175/13989043\n *\n * This file contains a function that fixes the duration metadata of a WEBM file.\n * - Answer found: https://stackoverflow.com/a/75218309/13989043\n * - Code adapted from: https://github.com/mat-sz/webm-fix-duration\n * (forked from https://github.com/yusitnikov/fix-webm-duration)\n */\n\n/*\n * This is the list of possible WEBM file sections by their IDs.\n * Possible types: Container, Binary, Uint, Int, String, Float, Date\n */\ninterface Section {\n name: string\n type: string\n}\n\nconst sections: Record<number, Section> = {\n 0xa45dfa3: { name: 'EBML', type: 'Container' },\n 0x286: { name: 'EBMLVersion', type: 'Uint' },\n 0x2f7: { name: 'EBMLReadVersion', type: 'Uint' },\n 0x2f2: { name: 'EBMLMaxIDLength', type: 'Uint' },\n 0x2f3: { name: 'EBMLMaxSizeLength', type: 'Uint' },\n 0x282: { name: 'DocType', type: 'String' },\n 0x287: { name: 'DocTypeVersion', type: 'Uint' },\n 0x285: { name: 'DocTypeReadVersion', type: 'Uint' },\n 0x6c: { name: 'Void', type: 'Binary' },\n 0x3f: { name: 'CRC-32', type: 'Binary' },\n 0xb538667: { name: 'SignatureSlot', type: 'Container' },\n 0x3e8a: { name: 'SignatureAlgo', type: 'Uint' },\n 0x3e9a: { name: 'SignatureHash', type: 'Uint' },\n 0x3ea5: { name: 'SignaturePublicKey', type: 'Binary' },\n 0x3eb5: { name: 'Signature', type: 'Binary' },\n 0x3e5b: { name: 'SignatureElements', type: 'Container' },\n 0x3e7b: { name: 'SignatureElementList', type: 'Container' },\n 0x2532: { name: 'SignedElement', type: 'Binary' },\n 0x8538067: { name: 'Segment', type: 'Container' },\n 0x14d9b74: { name: 'SeekHead', type: 'Container' },\n 0xdbb: { name: 'Seek', type: 'Container' },\n 0x13ab: { name: 'SeekID', type: 'Binary' },\n 0x13ac: { name: 'SeekPosition', type: 'Uint' },\n 0x549a966: { name: 'Info', type: 'Container' },\n 0x33a4: { name: 'SegmentUID', type: 'Binary' },\n 0x3384: { name: 'SegmentFilename', type: 'String' },\n 0x1cb923: { name: 'PrevUID', type: 'Binary' },\n 0x1c83ab: { name: 'PrevFilename', type: 'String' },\n 0x1eb923: { name: 'NextUID', type: 'Binary' },\n 0x1e83bb: { name: 'NextFilename', type: 'String' },\n 0x444: { name: 'SegmentFamily', type: 'Binary' },\n 0x2924: { name: 'ChapterTranslate', type: 'Container' },\n 0x29fc: { name: 'ChapterTranslateEditionUID', type: 'Uint' },\n 0x29bf: { name: 'ChapterTranslateCodec', type: 'Uint' },\n 0x29a5: { name: 'ChapterTranslateID', type: 'Binary' },\n 0xad7b1: { name: 'TimecodeScale', type: 'Uint' },\n 0x489: { name: 'Duration', type: 'Float' },\n 0x461: { name: 'DateUTC', type: 'Date' },\n 0x3ba9: { name: 'Title', type: 'String' },\n 0xd80: { name: 'MuxingApp', type: 'String' },\n 0x1741: { name: 'WritingApp', type: 'String' },\n // 0xf43b675: { name: 'Cluster', type: 'Container' },\n 0x67: { name: 'Timecode', type: 'Uint' },\n 0x1854: { name: 'SilentTracks', type: 'Container' },\n 0x18d7: { name: 'SilentTrackNumber', type: 'Uint' },\n 0x27: { name: 'Position', type: 'Uint' },\n 0x2b: { name: 'PrevSize', type: 'Uint' },\n 0x23: { name: 'SimpleBlock', type: 'Binary' },\n 0x20: { name: 'BlockGroup', type: 'Container' },\n 0x21: { name: 'Block', type: 'Binary' },\n 0x22: { name: 'BlockVirtual', type: 'Binary' },\n 0x35a1: { name: 'BlockAdditions', type: 'Container' },\n 0x26: { name: 'BlockMore', type: 'Container' },\n 0x6e: { name: 'BlockAddID', type: 'Uint' },\n 0x25: { name: 'BlockAdditional', type: 'Binary' },\n 0x1b: { name: 'BlockDuration', type: 'Uint' },\n 0x7a: { name: 'ReferencePriority', type: 'Uint' },\n 0x7b: { name: 'ReferenceBlock', type: 'Int' },\n 0x7d: { name: 'ReferenceVirtual', type: 'Int' },\n 0x24: { name: 'CodecState', type: 'Binary' },\n 0x35a2: { name: 'DiscardPadding', type: 'Int' },\n 0xe: { name: 'Slices', type: 'Container' },\n 0x68: { name: 'TimeSlice', type: 'Container' },\n 0x4c: { name: 'LaceNumber', type: 'Uint' },\n 0x4d: { name: 'FrameNumber', type: 'Uint' },\n 0x4b: { name: 'BlockAdditionID', type: 'Uint' },\n 0x4e: { name: 'Delay', type: 'Uint' },\n 0x4f: { name: 'SliceDuration', type: 'Uint' },\n 0x48: { name: 'ReferenceFrame', type: 'Container' },\n 0x49: { name: 'ReferenceOffset', type: 'Uint' },\n 0x4a: { name: 'ReferenceTimeCode', type: 'Uint' },\n 0x2f: { name: 'EncryptedBlock', type: 'Binary' },\n 0x654ae6b: { name: 'Tracks', type: 'Container' },\n 0x2e: { name: 'TrackEntry', type: 'Container' },\n 0x57: { name: 'TrackNumber', type: 'Uint' },\n 0x33c5: { name: 'TrackUID', type: 'Uint' },\n 0x3: { name: 'TrackType', type: 'Uint' },\n 0x39: { name: 'FlagEnabled', type: 'Uint' },\n 0x8: { name: 'FlagDefault', type: 'Uint' },\n 0x15aa: { name: 'FlagForced', type: 'Uint' },\n 0x1c: { name: 'FlagLacing', type: 'Uint' },\n 0x2de7: { name: 'MinCache', type: 'Uint' },\n 0x2df8: { name: 'MaxCache', type: 'Uint' },\n 0x3e383: { name: 'DefaultDuration', type: 'Uint' },\n 0x34e7a: { name: 'DefaultDecodedFieldDuration', type: 'Uint' },\n 0x3314f: { name: 'TrackTimecodeScale', type: 'Float' },\n 0x137f: { name: 'TrackOffset', type: 'Int' },\n 0x15ee: { name: 'MaxBlockAdditionID', type: 'Uint' },\n 0x136e: { name: 'Name', type: 'String' },\n 0x2b59c: { name: 'Language', type: 'String' },\n 0x6: { name: 'CodecID', type: 'String' },\n 0x23a2: { name: 'CodecPrivate', type: 'Binary' },\n 0x58688: { name: 'CodecName', type: 'String' },\n 0x3446: { name: 'AttachmentLink', type: 'Uint' },\n 0x1a9697: { name: 'CodecSettings', type: 'String' },\n 0x1b4040: { name: 'CodecInfoURL', type: 'String' },\n 0x6b240: { name: 'CodecDownloadURL', type: 'String' },\n 0x2a: { name: 'CodecDecodeAll', type: 'Uint' },\n 0x2fab: { name: 'TrackOverlay', type: 'Uint' },\n 0x16aa: { name: 'CodecDelay', type: 'Uint' },\n 0x16bb: { name: 'SeekPreRoll', type: 'Uint' },\n 0x2624: { name: 'TrackTranslate', type: 'Container' },\n 0x26fc: { name: 'TrackTranslateEditionUID', type: 'Uint' },\n 0x26bf: { name: 'TrackTranslateCodec', type: 'Uint' },\n 0x26a5: { name: 'TrackTranslateTrackID', type: 'Binary' },\n 0x60: { name: 'Video', type: 'Container' },\n 0x1a: { name: 'FlagInterlaced', type: 'Uint' },\n 0x13b8: { name: 'StereoMode', type: 'Uint' },\n 0x13c0: { name: 'AlphaMode', type: 'Uint' },\n 0x13b9: { name: 'OldStereoMode', type: 'Uint' },\n 0x30: { name: 'PixelWidth', type: 'Uint' },\n 0x3a: { name: 'PixelHeight', type: 'Uint' },\n 0x14aa: { name: 'PixelCropBottom', type: 'Uint' },\n 0x14bb: { name: 'PixelCropTop', type: 'Uint' },\n 0x14cc: { name: 'PixelCropLeft', type: 'Uint' },\n 0x14dd: { name: 'PixelCropRight', type: 'Uint' },\n 0x14b0: { name: 'DisplayWidth', type: 'Uint' },\n 0x14ba: { name: 'DisplayHeight', type: 'Uint' },\n 0x14b2: { name: 'DisplayUnit', type: 'Uint' },\n 0x14b3: { name: 'AspectRatioType', type: 'Uint' },\n 0xeb524: { name: 'ColourSpace', type: 'Binary' },\n 0xfb523: { name: 'GammaValue', type: 'Float' },\n 0x383e3: { name: 'FrameRate', type: 'Float' },\n 0x61: { name: 'Audio', type: 'Container' },\n 0x35: { name: 'SamplingFrequency', type: 'Float' },\n 0x38b5: { name: 'OutputSamplingFrequency', type: 'Float' },\n 0x1f: { name: 'Channels', type: 'Uint' },\n 0x3d7b: { name: 'ChannelPositions', type: 'Binary' },\n 0x2264: { name: 'BitDepth', type: 'Uint' },\n 0x62: { name: 'TrackOperation', type: 'Container' },\n 0x63: { name: 'TrackCombinePlanes', type: 'Container' },\n 0x64: { name: 'TrackPlane', type: 'Container' },\n 0x65: { name: 'TrackPlaneUID', type: 'Uint' },\n 0x66: { name: 'TrackPlaneType', type: 'Uint' },\n 0x69: { name: 'TrackJoinBlocks', type: 'Container' },\n 0x6d: { name: 'TrackJoinUID', type: 'Uint' },\n 0x40: { name: 'TrickTrackUID', type: 'Uint' },\n 0x41: { name: 'TrickTrackSegmentUID', type: 'Binary' },\n 0x46: { name: 'TrickTrackFlag', type: 'Uint' },\n 0x47: { name: 'TrickMasterTrackUID', type: 'Uint' },\n 0x44: { name: 'TrickMasterTrackSegmentUID', type: 'Binary' },\n 0x2d80: { name: 'ContentEncodings', type: 'Container' },\n 0x2240: { name: 'ContentEncoding', type: 'Container' },\n 0x1031: { name: 'ContentEncodingOrder', type: 'Uint' },\n 0x1032: { name: 'ContentEncodingScope', type: 'Uint' },\n 0x1033: { name: 'ContentEncodingType', type: 'Uint' },\n 0x1034: { name: 'ContentCompression', type: 'Container' },\n 0x254: { name: 'ContentCompAlgo', type: 'Uint' },\n 0x255: { name: 'ContentCompSettings', type: 'Binary' },\n 0x1035: { name: 'ContentEncryption', type: 'Container' },\n 0x7e1: { name: 'ContentEncAlgo', type: 'Uint' },\n 0x7e2: { name: 'ContentEncKeyID', type: 'Binary' },\n 0x7e3: { name: 'ContentSignature', type: 'Binary' },\n 0x7e4: { name: 'ContentSigKeyID', type: 'Binary' },\n 0x7e5: { name: 'ContentSigAlgo', type: 'Uint' },\n 0x7e6: { name: 'ContentSigHashAlgo', type: 'Uint' },\n 0xc53bb6b: { name: 'Cues', type: 'Container' },\n 0x3b: { name: 'CuePoint', type: 'Container' },\n 0x33: { name: 'CueTime', type: 'Uint' },\n 0x37: { name: 'CueTrackPositions', type: 'Container' },\n 0x77: { name: 'CueTrack', type: 'Uint' },\n 0x71: { name: 'CueClusterPosition', type: 'Uint' },\n 0x70: { name: 'CueRelativePosition', type: 'Uint' },\n 0x32: { name: 'CueDuration', type: 'Uint' },\n 0x1378: { name: 'CueBlockNumber', type: 'Uint' },\n 0x6a: { name: 'CueCodecState', type: 'Uint' },\n 0x5b: { name: 'CueReference', type: 'Container' },\n 0x16: { name: 'CueRefTime', type: 'Uint' },\n 0x17: { name: 'CueRefCluster', type: 'Uint' },\n 0x135f: { name: 'CueRefNumber', type: 'Uint' },\n 0x6b: { name: 'CueRefCodecState', type: 'Uint' },\n 0x941a469: { name: 'Attachments', type: 'Container' },\n 0x21a7: { name: 'AttachedFile', type: 'Container' },\n 0x67e: { name: 'FileDescription', type: 'String' },\n 0x66e: { name: 'FileName', type: 'String' },\n 0x660: { name: 'FileMimeType', type: 'String' },\n 0x65c: { name: 'FileData', type: 'Binary' },\n 0x6ae: { name: 'FileUID', type: 'Uint' },\n 0x675: { name: 'FileReferral', type: 'Binary' },\n 0x661: { name: 'FileUsedStartTime', type: 'Uint' },\n 0x662: { name: 'FileUsedEndTime', type: 'Uint' },\n 0x43a770: { name: 'Chapters', type: 'Container' },\n 0x5b9: { name: 'EditionEntry', type: 'Container' },\n 0x5bc: { name: 'EditionUID', type: 'Uint' },\n 0x5bd: { name: 'EditionFlagHidden', type: 'Uint' },\n 0x5db: { name: 'EditionFlagDefault', type: 'Uint' },\n 0x5dd: { name: 'EditionFlagOrdered', type: 'Uint' },\n 0x36: { name: 'ChapterAtom', type: 'Container' },\n 0x33c4: { name: 'ChapterUID', type: 'Uint' },\n 0x1654: { name: 'ChapterStringUID', type: 'String' },\n 0x11: { name: 'ChapterTimeStart', type: 'Uint' },\n 0x12: { name: 'ChapterTimeEnd', type: 'Uint' },\n 0x18: { name: 'ChapterFlagHidden', type: 'Uint' },\n 0x598: { name: 'ChapterFlagEnabled', type: 'Uint' },\n 0x2e67: { name: 'ChapterSegmentUID', type: 'Binary' },\n 0x2ebc: { name: 'ChapterSegmentEditionUID', type: 'Uint' },\n 0x23c3: { name: 'ChapterPhysicalEquiv', type: 'Uint' },\n 0xf: { name: 'ChapterTrack', type: 'Container' },\n 0x9: { name: 'ChapterTrackNumber', type: 'Uint' },\n 0x0: { name: 'ChapterDisplay', type: 'Container' },\n 0x5: { name: 'ChapString', type: 'String' },\n 0x37c: { name: 'ChapLanguage', type: 'String' },\n 0x37e: { name: 'ChapCountry', type: 'String' },\n 0x2944: { name: 'ChapProcess', type: 'Container' },\n 0x2955: { name: 'ChapProcessCodecID', type: 'Uint' },\n 0x50d: { name: 'ChapProcessPrivate', type: 'Binary' },\n 0x2911: { name: 'ChapProcessCommand', type: 'Container' },\n 0x2922: { name: 'ChapProcessTime', type: 'Uint' },\n 0x2933: { name: 'ChapProcessData', type: 'Binary' },\n 0x254c367: { name: 'Tags', type: 'Container' },\n 0x3373: { name: 'Tag', type: 'Container' },\n 0x23c0: { name: 'Targets', type: 'Container' },\n 0x28ca: { name: 'TargetTypeValue', type: 'Uint' },\n 0x23ca: { name: 'TargetType', type: 'String' },\n 0x23c5: { name: 'TagTrackUID', type: 'Uint' },\n 0x23c9: { name: 'TagEditionUID', type: 'Uint' },\n 0x23c4: { name: 'TagChapterUID', type: 'Uint' },\n 0x23c6: { name: 'TagAttachmentUID', type: 'Uint' },\n 0x27c8: { name: 'SimpleTag', type: 'Container' },\n 0x5a3: { name: 'TagName', type: 'String' },\n 0x47a: { name: 'TagLanguage', type: 'String' },\n 0x484: { name: 'TagDefault', type: 'Uint' },\n 0x487: { name: 'TagString', type: 'String' },\n 0x485: { name: 'TagBinary', type: 'Binary' },\n}\n\nclass WebmBase<T> {\n source?: Uint8Array\n data?: T\n\n constructor(\n private name = 'Unknown',\n private type = 'Unknown'\n ) {}\n\n updateBySource() {}\n\n setSource(source: Uint8Array) {\n this.source = source\n this.updateBySource()\n }\n\n updateByData() {}\n\n setData(data: T) {\n this.data = data\n this.updateByData()\n }\n}\n\nclass WebmUint extends WebmBase<string> {\n constructor(name: string, type: string) {\n super(name, type || 'Uint')\n }\n\n updateBySource() {\n // use hex representation of a number instead of number value\n this.data = ''\n for (let i = 0; i < this.source!.length; i++) {\n const hex = this.source![i].toString(16)\n this.data += padHex(hex)\n }\n }\n\n updateByData() {\n const length = this.data!.length / 2\n this.source = new Uint8Array(length)\n for (let i = 0; i < length; i++) {\n const hex = this.data!.substr(i * 2, 2)\n this.source[i] = parseInt(hex, 16)\n }\n }\n\n getValue() {\n return parseInt(this.data!, 16)\n }\n\n setValue(value: number) {\n this.setData(padHex(value.toString(16)))\n }\n}\n\nfunction padHex(hex: string) {\n return hex.length % 2 === 1 ? '0' + hex : hex\n}\n\nclass WebmFloat extends WebmBase<number> {\n constructor(name: string, type: string) {\n super(name, type || 'Float')\n }\n\n getFloatArrayType() {\n return this.source && this.source.length === 4\n ? Float32Array\n : Float64Array\n }\n updateBySource() {\n const byteArray = this.source!.reverse()\n const floatArrayType = this.getFloatArrayType()\n const buffer = new ArrayBuffer(byteArray.buffer.byteLength)\n new Uint8Array(buffer).set(new Uint8Array(byteArray.buffer))\n const floatArray = new floatArrayType(buffer)\n this.data! = floatArray[0]\n }\n updateByData() {\n const floatArrayType = this.getFloatArrayType()\n const floatArray = new floatArrayType([this.data!])\n const byteArray = new Uint8Array(floatArray.buffer)\n this.source = byteArray.reverse()\n }\n getValue() {\n return this.data\n }\n setValue(value: number) {\n this.setData(value)\n }\n}\n\ninterface ContainerData {\n id: number\n idHex?: string\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n data: WebmBase<any>\n}\n\nclass WebmContainer extends WebmBase<ContainerData[]> {\n offset: number = 0\n data: ContainerData[] = []\n\n constructor(name: string, type: string) {\n super(name, type || 'Container')\n }\n\n readByte() {\n return this.source![this.offset++]\n }\n readUint() {\n const firstByte = this.readByte()\n const bytes = 8 - firstByte.toString(2).length\n let value = firstByte - (1 << (7 - bytes))\n for (let i = 0; i < bytes; i++) {\n // don't use bit operators to support x86\n value *= 256\n value += this.readByte()\n }\n return value\n }\n updateBySource() {\n let end: number | undefined = undefined\n this.data = []\n for (\n this.offset = 0;\n this.offset < this.source!.length;\n this.offset = end\n ) {\n const id = this.readUint()\n const len = this.readUint()\n end = Math.min(this.offset + len, this.source!.length)\n const data = this.source!.slice(this.offset, end)\n\n const info = sections[id] || { name: 'Unknown', type: 'Unknown' }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let ctr: any = WebmBase\n switch (info.type) {\n case 'Container':\n ctr = WebmContainer\n break\n case 'Uint':\n ctr = WebmUint\n break\n case 'Float':\n ctr = WebmFloat\n break\n }\n const section = new ctr(info.name, info.type)\n section.setSource(data)\n this.data.push({\n id,\n idHex: id.toString(16),\n data: section,\n })\n }\n }\n writeUint(x: number, draft = false) {\n let flag = 0x80\n let bytes = 1\n // eslint-disable-next-line no-empty\n for (; x >= flag && bytes < 8; bytes++, flag *= 0x80) {}\n\n if (!draft) {\n let value = flag + x\n for (let i = bytes - 1; i >= 0; i--) {\n // don't use bit operators to support x86\n const c = value % 256\n this.source![this.offset! + i] = c\n value = (value - c) / 256\n }\n }\n\n this.offset += bytes\n }\n\n writeSections(draft = false) {\n this.offset = 0\n for (let i = 0; i < this.data.length; i++) {\n const section = this.data[i],\n content = section.data.source,\n contentLength = content!.length\n this.writeUint(section.id, draft)\n this.writeUint(contentLength, draft)\n if (!draft) {\n this.source!.set(content!, this.offset)\n }\n this.offset += contentLength\n }\n return this.offset\n }\n\n updateByData() {\n // run without accessing this.source to determine total length - need to know it to create Uint8Array\n const length = this.writeSections(true)\n this.source = new Uint8Array(length)\n // now really write data\n this.writeSections()\n }\n\n getSectionById(id: number) {\n for (let i = 0; i < this.data.length; i++) {\n const section = this.data[i]\n if (section.id === id) {\n return section.data\n }\n }\n\n return undefined\n }\n}\n\nclass WebmFile extends WebmContainer {\n constructor(source: Uint8Array) {\n super('File', 'File')\n this.setSource(source)\n }\n\n fixDuration(duration: number) {\n const segmentSection = this.getSectionById(0x8538067) as WebmContainer\n if (!segmentSection) {\n return false\n }\n\n const infoSection = segmentSection.getSectionById(\n 0x549a966\n ) as WebmContainer\n if (!infoSection) {\n return false\n }\n\n const timeScaleSection = infoSection.getSectionById(\n 0xad7b1\n ) as WebmFloat\n if (!timeScaleSection) {\n return false\n }\n\n let durationSection = infoSection.getSectionById(0x489) as WebmFloat\n if (durationSection) {\n if (durationSection.getValue()! <= 0) {\n durationSection.setValue(duration)\n } else {\n return false\n }\n } else {\n // append Duration section\n durationSection = new WebmFloat('Duration', 'Float')\n durationSection.setValue(duration)\n infoSection.data.push({\n id: 0x489,\n data: durationSection,\n })\n }\n\n // set default time scale to 1 millisecond (1000000 nanoseconds)\n timeScaleSection.setValue(1000000)\n infoSection.updateByData()\n segmentSection.updateByData()\n this.updateByData()\n\n return true\n }\n\n toBlob(type = 'video/webm') {\n const buffer = new ArrayBuffer(this.source!.buffer.byteLength)\n new Uint8Array(buffer).set(new Uint8Array(this.source!.buffer))\n return new Blob([buffer], { type })\n }\n}\n\n/**\n * Fixes duration on MediaRecorder output.\n * @param blob Input Blob with incorrect duration.\n * @param duration Correct duration (in milliseconds).\n * @param type Output blob mimetype (default: video/webm).\n * @returns\n */\nexport const webmFixDuration = (\n blob: Blob,\n duration: number,\n type = 'video/webm'\n): Promise<Blob> => {\n return new Promise((resolve, reject) => {\n try {\n const reader = new FileReader()\n\n reader.addEventListener('loadend', () => {\n try {\n const result = reader.result as ArrayBuffer\n const file = new WebmFile(new Uint8Array(result))\n if (file.fixDuration(duration)) {\n resolve(file.toBlob(type))\n } else {\n resolve(blob)\n }\n } catch (ex) {\n reject(ex)\n }\n })\n\n reader.addEventListener('error', () =>\n reject(new Error('FileReader error'))\n )\n\n reader.readAsArrayBuffer(blob)\n } catch (ex) {\n reject(ex)\n }\n })\n}\n"]}
1
+ {"version":3,"file":"BlobFix.js","sourceRoot":"","sources":["../../src/utils/BlobFix.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * There is a bug where `navigator.mediaDevices.getUserMedia` + `MediaRecorder`\n * creates WEBM files without duration metadata. See:\n * - https://bugs.chromium.org/p/chromium/issues/detail?id=642012\n * - https://stackoverflow.com/a/39971175/13989043\n *\n * This file contains a function that fixes the duration metadata of a WEBM file.\n * - Answer found: https://stackoverflow.com/a/75218309/13989043\n * - Code adapted from: https://github.com/mat-sz/webm-fix-duration\n * (forked from https://github.com/yusitnikov/fix-webm-duration)\n */\n\n/*\n * This is the list of possible WEBM file sections by their IDs.\n * Possible types: Container, Binary, Uint, Int, String, Float, Date\n */\ninterface Section {\n name: string\n type: string\n}\n\nconst sections: Record<number, Section> = {\n 0xa45dfa3: { name: 'EBML', type: 'Container' },\n 0x286: { name: 'EBMLVersion', type: 'Uint' },\n 0x2f7: { name: 'EBMLReadVersion', type: 'Uint' },\n 0x2f2: { name: 'EBMLMaxIDLength', type: 'Uint' },\n 0x2f3: { name: 'EBMLMaxSizeLength', type: 'Uint' },\n 0x282: { name: 'DocType', type: 'String' },\n 0x287: { name: 'DocTypeVersion', type: 'Uint' },\n 0x285: { name: 'DocTypeReadVersion', type: 'Uint' },\n 0x6c: { name: 'Void', type: 'Binary' },\n 0x3f: { name: 'CRC-32', type: 'Binary' },\n 0xb538667: { name: 'SignatureSlot', type: 'Container' },\n 0x3e8a: { name: 'SignatureAlgo', type: 'Uint' },\n 0x3e9a: { name: 'SignatureHash', type: 'Uint' },\n 0x3ea5: { name: 'SignaturePublicKey', type: 'Binary' },\n 0x3eb5: { name: 'Signature', type: 'Binary' },\n 0x3e5b: { name: 'SignatureElements', type: 'Container' },\n 0x3e7b: { name: 'SignatureElementList', type: 'Container' },\n 0x2532: { name: 'SignedElement', type: 'Binary' },\n 0x8538067: { name: 'Segment', type: 'Container' },\n 0x14d9b74: { name: 'SeekHead', type: 'Container' },\n 0xdbb: { name: 'Seek', type: 'Container' },\n 0x13ab: { name: 'SeekID', type: 'Binary' },\n 0x13ac: { name: 'SeekPosition', type: 'Uint' },\n 0x549a966: { name: 'Info', type: 'Container' },\n 0x33a4: { name: 'SegmentUID', type: 'Binary' },\n 0x3384: { name: 'SegmentFilename', type: 'String' },\n 0x1cb923: { name: 'PrevUID', type: 'Binary' },\n 0x1c83ab: { name: 'PrevFilename', type: 'String' },\n 0x1eb923: { name: 'NextUID', type: 'Binary' },\n 0x1e83bb: { name: 'NextFilename', type: 'String' },\n 0x444: { name: 'SegmentFamily', type: 'Binary' },\n 0x2924: { name: 'ChapterTranslate', type: 'Container' },\n 0x29fc: { name: 'ChapterTranslateEditionUID', type: 'Uint' },\n 0x29bf: { name: 'ChapterTranslateCodec', type: 'Uint' },\n 0x29a5: { name: 'ChapterTranslateID', type: 'Binary' },\n 0xad7b1: { name: 'TimecodeScale', type: 'Uint' },\n 0x489: { name: 'Duration', type: 'Float' },\n 0x461: { name: 'DateUTC', type: 'Date' },\n 0x3ba9: { name: 'Title', type: 'String' },\n 0xd80: { name: 'MuxingApp', type: 'String' },\n 0x1741: { name: 'WritingApp', type: 'String' },\n // 0xf43b675: { name: 'Cluster', type: 'Container' },\n 0x67: { name: 'Timecode', type: 'Uint' },\n 0x1854: { name: 'SilentTracks', type: 'Container' },\n 0x18d7: { name: 'SilentTrackNumber', type: 'Uint' },\n 0x27: { name: 'Position', type: 'Uint' },\n 0x2b: { name: 'PrevSize', type: 'Uint' },\n 0x23: { name: 'SimpleBlock', type: 'Binary' },\n 0x20: { name: 'BlockGroup', type: 'Container' },\n 0x21: { name: 'Block', type: 'Binary' },\n 0x22: { name: 'BlockVirtual', type: 'Binary' },\n 0x35a1: { name: 'BlockAdditions', type: 'Container' },\n 0x26: { name: 'BlockMore', type: 'Container' },\n 0x6e: { name: 'BlockAddID', type: 'Uint' },\n 0x25: { name: 'BlockAdditional', type: 'Binary' },\n 0x1b: { name: 'BlockDuration', type: 'Uint' },\n 0x7a: { name: 'ReferencePriority', type: 'Uint' },\n 0x7b: { name: 'ReferenceBlock', type: 'Int' },\n 0x7d: { name: 'ReferenceVirtual', type: 'Int' },\n 0x24: { name: 'CodecState', type: 'Binary' },\n 0x35a2: { name: 'DiscardPadding', type: 'Int' },\n 0xe: { name: 'Slices', type: 'Container' },\n 0x68: { name: 'TimeSlice', type: 'Container' },\n 0x4c: { name: 'LaceNumber', type: 'Uint' },\n 0x4d: { name: 'FrameNumber', type: 'Uint' },\n 0x4b: { name: 'BlockAdditionID', type: 'Uint' },\n 0x4e: { name: 'Delay', type: 'Uint' },\n 0x4f: { name: 'SliceDuration', type: 'Uint' },\n 0x48: { name: 'ReferenceFrame', type: 'Container' },\n 0x49: { name: 'ReferenceOffset', type: 'Uint' },\n 0x4a: { name: 'ReferenceTimeCode', type: 'Uint' },\n 0x2f: { name: 'EncryptedBlock', type: 'Binary' },\n 0x654ae6b: { name: 'Tracks', type: 'Container' },\n 0x2e: { name: 'TrackEntry', type: 'Container' },\n 0x57: { name: 'TrackNumber', type: 'Uint' },\n 0x33c5: { name: 'TrackUID', type: 'Uint' },\n 0x3: { name: 'TrackType', type: 'Uint' },\n 0x39: { name: 'FlagEnabled', type: 'Uint' },\n 0x8: { name: 'FlagDefault', type: 'Uint' },\n 0x15aa: { name: 'FlagForced', type: 'Uint' },\n 0x1c: { name: 'FlagLacing', type: 'Uint' },\n 0x2de7: { name: 'MinCache', type: 'Uint' },\n 0x2df8: { name: 'MaxCache', type: 'Uint' },\n 0x3e383: { name: 'DefaultDuration', type: 'Uint' },\n 0x34e7a: { name: 'DefaultDecodedFieldDuration', type: 'Uint' },\n 0x3314f: { name: 'TrackTimecodeScale', type: 'Float' },\n 0x137f: { name: 'TrackOffset', type: 'Int' },\n 0x15ee: { name: 'MaxBlockAdditionID', type: 'Uint' },\n 0x136e: { name: 'Name', type: 'String' },\n 0x2b59c: { name: 'Language', type: 'String' },\n 0x6: { name: 'CodecID', type: 'String' },\n 0x23a2: { name: 'CodecPrivate', type: 'Binary' },\n 0x58688: { name: 'CodecName', type: 'String' },\n 0x3446: { name: 'AttachmentLink', type: 'Uint' },\n 0x1a9697: { name: 'CodecSettings', type: 'String' },\n 0x1b4040: { name: 'CodecInfoURL', type: 'String' },\n 0x6b240: { name: 'CodecDownloadURL', type: 'String' },\n 0x2a: { name: 'CodecDecodeAll', type: 'Uint' },\n 0x2fab: { name: 'TrackOverlay', type: 'Uint' },\n 0x16aa: { name: 'CodecDelay', type: 'Uint' },\n 0x16bb: { name: 'SeekPreRoll', type: 'Uint' },\n 0x2624: { name: 'TrackTranslate', type: 'Container' },\n 0x26fc: { name: 'TrackTranslateEditionUID', type: 'Uint' },\n 0x26bf: { name: 'TrackTranslateCodec', type: 'Uint' },\n 0x26a5: { name: 'TrackTranslateTrackID', type: 'Binary' },\n 0x60: { name: 'Video', type: 'Container' },\n 0x1a: { name: 'FlagInterlaced', type: 'Uint' },\n 0x13b8: { name: 'StereoMode', type: 'Uint' },\n 0x13c0: { name: 'AlphaMode', type: 'Uint' },\n 0x13b9: { name: 'OldStereoMode', type: 'Uint' },\n 0x30: { name: 'PixelWidth', type: 'Uint' },\n 0x3a: { name: 'PixelHeight', type: 'Uint' },\n 0x14aa: { name: 'PixelCropBottom', type: 'Uint' },\n 0x14bb: { name: 'PixelCropTop', type: 'Uint' },\n 0x14cc: { name: 'PixelCropLeft', type: 'Uint' },\n 0x14dd: { name: 'PixelCropRight', type: 'Uint' },\n 0x14b0: { name: 'DisplayWidth', type: 'Uint' },\n 0x14ba: { name: 'DisplayHeight', type: 'Uint' },\n 0x14b2: { name: 'DisplayUnit', type: 'Uint' },\n 0x14b3: { name: 'AspectRatioType', type: 'Uint' },\n 0xeb524: { name: 'ColourSpace', type: 'Binary' },\n 0xfb523: { name: 'GammaValue', type: 'Float' },\n 0x383e3: { name: 'FrameRate', type: 'Float' },\n 0x61: { name: 'Audio', type: 'Container' },\n 0x35: { name: 'SamplingFrequency', type: 'Float' },\n 0x38b5: { name: 'OutputSamplingFrequency', type: 'Float' },\n 0x1f: { name: 'Channels', type: 'Uint' },\n 0x3d7b: { name: 'ChannelPositions', type: 'Binary' },\n 0x2264: { name: 'BitDepth', type: 'Uint' },\n 0x62: { name: 'TrackOperation', type: 'Container' },\n 0x63: { name: 'TrackCombinePlanes', type: 'Container' },\n 0x64: { name: 'TrackPlane', type: 'Container' },\n 0x65: { name: 'TrackPlaneUID', type: 'Uint' },\n 0x66: { name: 'TrackPlaneType', type: 'Uint' },\n 0x69: { name: 'TrackJoinBlocks', type: 'Container' },\n 0x6d: { name: 'TrackJoinUID', type: 'Uint' },\n 0x40: { name: 'TrickTrackUID', type: 'Uint' },\n 0x41: { name: 'TrickTrackSegmentUID', type: 'Binary' },\n 0x46: { name: 'TrickTrackFlag', type: 'Uint' },\n 0x47: { name: 'TrickMasterTrackUID', type: 'Uint' },\n 0x44: { name: 'TrickMasterTrackSegmentUID', type: 'Binary' },\n 0x2d80: { name: 'ContentEncodings', type: 'Container' },\n 0x2240: { name: 'ContentEncoding', type: 'Container' },\n 0x1031: { name: 'ContentEncodingOrder', type: 'Uint' },\n 0x1032: { name: 'ContentEncodingScope', type: 'Uint' },\n 0x1033: { name: 'ContentEncodingType', type: 'Uint' },\n 0x1034: { name: 'ContentCompression', type: 'Container' },\n 0x254: { name: 'ContentCompAlgo', type: 'Uint' },\n 0x255: { name: 'ContentCompSettings', type: 'Binary' },\n 0x1035: { name: 'ContentEncryption', type: 'Container' },\n 0x7e1: { name: 'ContentEncAlgo', type: 'Uint' },\n 0x7e2: { name: 'ContentEncKeyID', type: 'Binary' },\n 0x7e3: { name: 'ContentSignature', type: 'Binary' },\n 0x7e4: { name: 'ContentSigKeyID', type: 'Binary' },\n 0x7e5: { name: 'ContentSigAlgo', type: 'Uint' },\n 0x7e6: { name: 'ContentSigHashAlgo', type: 'Uint' },\n 0xc53bb6b: { name: 'Cues', type: 'Container' },\n 0x3b: { name: 'CuePoint', type: 'Container' },\n 0x33: { name: 'CueTime', type: 'Uint' },\n 0x37: { name: 'CueTrackPositions', type: 'Container' },\n 0x77: { name: 'CueTrack', type: 'Uint' },\n 0x71: { name: 'CueClusterPosition', type: 'Uint' },\n 0x70: { name: 'CueRelativePosition', type: 'Uint' },\n 0x32: { name: 'CueDuration', type: 'Uint' },\n 0x1378: { name: 'CueBlockNumber', type: 'Uint' },\n 0x6a: { name: 'CueCodecState', type: 'Uint' },\n 0x5b: { name: 'CueReference', type: 'Container' },\n 0x16: { name: 'CueRefTime', type: 'Uint' },\n 0x17: { name: 'CueRefCluster', type: 'Uint' },\n 0x135f: { name: 'CueRefNumber', type: 'Uint' },\n 0x6b: { name: 'CueRefCodecState', type: 'Uint' },\n 0x941a469: { name: 'Attachments', type: 'Container' },\n 0x21a7: { name: 'AttachedFile', type: 'Container' },\n 0x67e: { name: 'FileDescription', type: 'String' },\n 0x66e: { name: 'FileName', type: 'String' },\n 0x660: { name: 'FileMimeType', type: 'String' },\n 0x65c: { name: 'FileData', type: 'Binary' },\n 0x6ae: { name: 'FileUID', type: 'Uint' },\n 0x675: { name: 'FileReferral', type: 'Binary' },\n 0x661: { name: 'FileUsedStartTime', type: 'Uint' },\n 0x662: { name: 'FileUsedEndTime', type: 'Uint' },\n 0x43a770: { name: 'Chapters', type: 'Container' },\n 0x5b9: { name: 'EditionEntry', type: 'Container' },\n 0x5bc: { name: 'EditionUID', type: 'Uint' },\n 0x5bd: { name: 'EditionFlagHidden', type: 'Uint' },\n 0x5db: { name: 'EditionFlagDefault', type: 'Uint' },\n 0x5dd: { name: 'EditionFlagOrdered', type: 'Uint' },\n 0x36: { name: 'ChapterAtom', type: 'Container' },\n 0x33c4: { name: 'ChapterUID', type: 'Uint' },\n 0x1654: { name: 'ChapterStringUID', type: 'String' },\n 0x11: { name: 'ChapterTimeStart', type: 'Uint' },\n 0x12: { name: 'ChapterTimeEnd', type: 'Uint' },\n 0x18: { name: 'ChapterFlagHidden', type: 'Uint' },\n 0x598: { name: 'ChapterFlagEnabled', type: 'Uint' },\n 0x2e67: { name: 'ChapterSegmentUID', type: 'Binary' },\n 0x2ebc: { name: 'ChapterSegmentEditionUID', type: 'Uint' },\n 0x23c3: { name: 'ChapterPhysicalEquiv', type: 'Uint' },\n 0xf: { name: 'ChapterTrack', type: 'Container' },\n 0x9: { name: 'ChapterTrackNumber', type: 'Uint' },\n 0x0: { name: 'ChapterDisplay', type: 'Container' },\n 0x5: { name: 'ChapString', type: 'String' },\n 0x37c: { name: 'ChapLanguage', type: 'String' },\n 0x37e: { name: 'ChapCountry', type: 'String' },\n 0x2944: { name: 'ChapProcess', type: 'Container' },\n 0x2955: { name: 'ChapProcessCodecID', type: 'Uint' },\n 0x50d: { name: 'ChapProcessPrivate', type: 'Binary' },\n 0x2911: { name: 'ChapProcessCommand', type: 'Container' },\n 0x2922: { name: 'ChapProcessTime', type: 'Uint' },\n 0x2933: { name: 'ChapProcessData', type: 'Binary' },\n 0x254c367: { name: 'Tags', type: 'Container' },\n 0x3373: { name: 'Tag', type: 'Container' },\n 0x23c0: { name: 'Targets', type: 'Container' },\n 0x28ca: { name: 'TargetTypeValue', type: 'Uint' },\n 0x23ca: { name: 'TargetType', type: 'String' },\n 0x23c5: { name: 'TagTrackUID', type: 'Uint' },\n 0x23c9: { name: 'TagEditionUID', type: 'Uint' },\n 0x23c4: { name: 'TagChapterUID', type: 'Uint' },\n 0x23c6: { name: 'TagAttachmentUID', type: 'Uint' },\n 0x27c8: { name: 'SimpleTag', type: 'Container' },\n 0x5a3: { name: 'TagName', type: 'String' },\n 0x47a: { name: 'TagLanguage', type: 'String' },\n 0x484: { name: 'TagDefault', type: 'Uint' },\n 0x487: { name: 'TagString', type: 'String' },\n 0x485: { name: 'TagBinary', type: 'Binary' },\n}\n\nclass WebmBase<T> {\n source?: Uint8Array\n data?: T\n name: string\n type: string\n\n constructor(name = 'Unknown', type = 'Unknown') {\n this.name = name\n this.type = type\n }\n\n updateBySource() {}\n\n setSource(source: Uint8Array) {\n this.source = source\n this.updateBySource()\n }\n\n updateByData() {}\n\n setData(data: T) {\n this.data = data\n this.updateByData()\n }\n}\n\nclass WebmUint extends WebmBase<string> {\n constructor(name: string, type: string) {\n super(name, type || 'Uint')\n }\n\n updateBySource() {\n // use hex representation of a number instead of number value\n this.data = ''\n for (let i = 0; i < this.source!.length; i++) {\n const hex = this.source![i].toString(16)\n this.data += padHex(hex)\n }\n }\n\n updateByData() {\n const length = this.data!.length / 2\n this.source = new Uint8Array(length)\n for (let i = 0; i < length; i++) {\n const hex = this.data!.substr(i * 2, 2)\n this.source[i] = parseInt(hex, 16)\n }\n }\n\n getValue() {\n return parseInt(this.data!, 16)\n }\n\n setValue(value: number) {\n this.setData(padHex(value.toString(16)))\n }\n}\n\nfunction padHex(hex: string) {\n return hex.length % 2 === 1 ? '0' + hex : hex\n}\n\nclass WebmFloat extends WebmBase<number> {\n constructor(name: string, type: string) {\n super(name, type || 'Float')\n }\n\n getFloatArrayType() {\n return this.source && this.source.length === 4\n ? Float32Array\n : Float64Array\n }\n updateBySource() {\n const byteArray = this.source!.reverse()\n const floatArrayType = this.getFloatArrayType()\n const buffer = new ArrayBuffer(byteArray.buffer.byteLength)\n new Uint8Array(buffer).set(new Uint8Array(byteArray.buffer))\n const floatArray = new floatArrayType(buffer)\n this.data! = floatArray[0]\n }\n updateByData() {\n const floatArrayType = this.getFloatArrayType()\n const floatArray = new floatArrayType([this.data!])\n const byteArray = new Uint8Array(floatArray.buffer)\n this.source = byteArray.reverse()\n }\n getValue() {\n return this.data\n }\n setValue(value: number) {\n this.setData(value)\n }\n}\n\ninterface ContainerData {\n id: number\n idHex?: string\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n data: WebmBase<any>\n}\n\nclass WebmContainer extends WebmBase<ContainerData[]> {\n offset: number = 0\n data: ContainerData[] = []\n\n constructor(name: string, type: string) {\n super(name, type || 'Container')\n }\n\n readByte() {\n return this.source![this.offset++]\n }\n readUint() {\n const firstByte = this.readByte()\n const bytes = 8 - firstByte.toString(2).length\n let value = firstByte - (1 << (7 - bytes))\n for (let i = 0; i < bytes; i++) {\n // don't use bit operators to support x86\n value *= 256\n value += this.readByte()\n }\n return value\n }\n updateBySource() {\n let end: number | undefined = undefined\n this.data = []\n for (\n this.offset = 0;\n this.offset < this.source!.length;\n this.offset = end\n ) {\n const id = this.readUint()\n const len = this.readUint()\n end = Math.min(this.offset + len, this.source!.length)\n const data = this.source!.slice(this.offset, end)\n\n const info = sections[id] || { name: 'Unknown', type: 'Unknown' }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let ctr: any = WebmBase\n switch (info.type) {\n case 'Container':\n ctr = WebmContainer\n break\n case 'Uint':\n ctr = WebmUint\n break\n case 'Float':\n ctr = WebmFloat\n break\n }\n const section = new ctr(info.name, info.type)\n section.setSource(data)\n this.data.push({\n id,\n idHex: id.toString(16),\n data: section,\n })\n }\n }\n writeUint(x: number, draft = false) {\n let flag = 0x80\n let bytes = 1\n // eslint-disable-next-line no-empty\n for (; x >= flag && bytes < 8; bytes++, flag *= 0x80) {}\n\n if (!draft) {\n let value = flag + x\n for (let i = bytes - 1; i >= 0; i--) {\n // don't use bit operators to support x86\n const c = value % 256\n this.source![this.offset! + i] = c\n value = (value - c) / 256\n }\n }\n\n this.offset += bytes\n }\n\n writeSections(draft = false) {\n this.offset = 0\n for (let i = 0; i < this.data.length; i++) {\n const section = this.data[i],\n content = section.data.source,\n contentLength = content!.length\n this.writeUint(section.id, draft)\n this.writeUint(contentLength, draft)\n if (!draft) {\n this.source!.set(content!, this.offset)\n }\n this.offset += contentLength\n }\n return this.offset\n }\n\n updateByData() {\n // run without accessing this.source to determine total length - need to know it to create Uint8Array\n const length = this.writeSections(true)\n this.source = new Uint8Array(length)\n // now really write data\n this.writeSections()\n }\n\n getSectionById(id: number) {\n for (let i = 0; i < this.data.length; i++) {\n const section = this.data[i]\n if (section.id === id) {\n return section.data\n }\n }\n\n return undefined\n }\n}\n\nclass WebmFile extends WebmContainer {\n constructor(source: Uint8Array) {\n super('File', 'File')\n this.setSource(source)\n }\n\n fixDuration(duration: number) {\n const segmentSection = this.getSectionById(0x8538067) as WebmContainer\n if (!segmentSection) {\n return false\n }\n\n const infoSection = segmentSection.getSectionById(\n 0x549a966\n ) as WebmContainer\n if (!infoSection) {\n return false\n }\n\n const timeScaleSection = infoSection.getSectionById(\n 0xad7b1\n ) as WebmFloat\n if (!timeScaleSection) {\n return false\n }\n\n let durationSection = infoSection.getSectionById(0x489) as WebmFloat\n if (durationSection) {\n if (durationSection.getValue()! <= 0) {\n durationSection.setValue(duration)\n } else {\n return false\n }\n } else {\n // append Duration section\n durationSection = new WebmFloat('Duration', 'Float')\n durationSection.setValue(duration)\n infoSection.data.push({\n id: 0x489,\n data: durationSection,\n })\n }\n\n // set default time scale to 1 millisecond (1000000 nanoseconds)\n timeScaleSection.setValue(1000000)\n infoSection.updateByData()\n segmentSection.updateByData()\n this.updateByData()\n\n return true\n }\n\n toBlob(type = 'video/webm') {\n const buffer = new ArrayBuffer(this.source!.buffer.byteLength)\n new Uint8Array(buffer).set(new Uint8Array(this.source!.buffer))\n return new Blob([buffer], { type })\n }\n}\n\n/**\n * Fixes duration on MediaRecorder output.\n * @param blob Input Blob with incorrect duration.\n * @param duration Correct duration (in milliseconds).\n * @param type Output blob mimetype (default: video/webm).\n * @returns\n */\nexport const webmFixDuration = (\n blob: Blob,\n duration: number,\n type = 'video/webm'\n): Promise<Blob> => {\n return new Promise((resolve, reject) => {\n try {\n const reader = new FileReader()\n\n reader.addEventListener('loadend', () => {\n try {\n const result = reader.result as ArrayBuffer\n const file = new WebmFile(new Uint8Array(result))\n if (file.fixDuration(duration)) {\n resolve(file.toBlob(type))\n } else {\n resolve(blob)\n }\n } catch (ex) {\n reject(ex)\n }\n })\n\n reader.addEventListener('error', () =>\n reject(new Error('FileReader error'))\n )\n\n reader.readAsArrayBuffer(blob)\n } catch (ex) {\n reject(ex)\n }\n })\n}\n"]}
@@ -1,2 +1,2 @@
1
- export declare const InlineFeaturesExtractor = "\n// Constants\nconst N_FFT = 1024; // Default FFT size\nconst MAX_FFT_SIZE = 8192; // Maximum FFT size to prevent memory issues\nconst N_CHROMA = 12;\n\n// FFT Implementation with normalized Hann window\nfunction FFT(n) {\n this.n = n;\n this.cosTable = new Float32Array(n / 2);\n this.sinTable = new Float32Array(n / 2);\n this.hannWindow = new Float32Array(n);\n \n // Match Android implementation with precomputed tables\n const normalizationFactor = Math.sqrt(2.0 / n);\n for (var i = 0; i < n / 2; i++) {\n this.cosTable[i] = Math.cos(2.0 * Math.PI * i / n);\n this.sinTable[i] = Math.sin(2.0 * Math.PI * i / n);\n }\n \n // Precompute normalized Hann window to match Android\n for (var i = 0; i < n; i++) {\n this.hannWindow[i] = normalizationFactor * 0.5 * (1 - Math.cos(2.0 * Math.PI * i / (n - 1)));\n }\n}\n\nFFT.prototype.transform = function(data) {\n const n = data.length;\n \n // Validate input length is power of 2\n if ((n & (n - 1)) !== 0) {\n throw new Error('FFT length must be power of 2');\n }\n\n // Use iterative bit reversal instead of recursive\n const bitReversedIndices = new Uint32Array(n);\n for (let i = 0; i < n; i++) {\n let reversed = 0;\n let j = i;\n let bits = Math.log2(n);\n while (bits--) {\n reversed = (reversed << 1) | (j & 1);\n j >>= 1;\n }\n bitReversedIndices[i] = reversed;\n }\n\n // Apply bit reversal\n for (let i = 0; i < n; i++) {\n const j = bitReversedIndices[i];\n if (i < j) {\n const temp = data[i];\n data[i] = data[j];\n data[j] = temp;\n }\n }\n\n // Iterative FFT computation with optimized memory usage\n for (let step = 1; step < n; step <<= 1) {\n const jump = step << 1;\n const angleStep = Math.PI / step;\n\n for (let group = 0; group < n; group += jump) {\n for (let pair = group; pair < group + step; pair++) {\n const match = pair + step;\n const angle = angleStep * (pair - group);\n \n const currentCos = Math.cos(angle);\n const currentSin = Math.sin(angle);\n\n const real = currentCos * data[match] - currentSin * data[match + 1];\n const imag = currentCos * data[match + 1] + currentSin * data[match];\n\n data[match] = data[pair] - real;\n data[match + 1] = data[pair + 1] - imag;\n data[pair] += real;\n data[pair + 1] += imag;\n }\n }\n }\n};\n\n// Add realInverse method\nFFT.prototype.realInverse = function(powerSpectrum, output) {\n const n = powerSpectrum.length;\n const complexData = new Float32Array(n * 2);\n \n // Copy power spectrum to complex format\n for (let i = 0; i < n/2 + 1; i++) {\n complexData[2 * i] = powerSpectrum[i];\n if (2 * i + 1 < complexData.length) {\n complexData[2 * i + 1] = 0;\n }\n }\n \n // Conjugate for inverse FFT\n for (let i = 0; i < n; i++) {\n if (2 * i + 1 < complexData.length) {\n complexData[2 * i + 1] = -complexData[2 * i + 1];\n }\n }\n \n this.transform(complexData);\n \n // Copy real part to output and scale\n for (let i = 0; i < n; i++) {\n output[i] = complexData[2 * i] / n;\n }\n};\n\n// Add helper functions to match Android\nfunction nextPowerOfTwo(n) {\n let value = 1;\n while (value < n) {\n value *= 2;\n }\n return value;\n}\n\nfunction applyHannWindow(samples) {\n const output = new Float32Array(samples.length);\n for (let i = 0; i < samples.length; i++) {\n const multiplier = 0.5 * (1 - Math.cos(2 * Math.PI * i / (samples.length - 1)));\n output[i] = samples[i] * multiplier;\n }\n return output;\n}\n\n// Update spectral feature computation to match Android\nfunction computeSpectralFeatures(segment, sampleRate, featureOptions = {}) {\n try {\n // Early return if no spectral features are requested\n if (!featureOptions.spectralCentroid && \n !featureOptions.spectralFlatness && \n !featureOptions.spectralRollOff && \n !featureOptions.spectralBandwidth &&\n !featureOptions.magnitudeSpectrum) {\n return {\n centroid: 0,\n flatness: 0,\n rollOff: 0,\n bandwidth: 0,\n magnitudeSpectrum: []\n };\n }\n\n // Ensure we have valid data\n if (!segment || segment.length === 0) {\n throw new Error('Invalid segment data');\n }\n\n // Process in fixed-size chunks\n const chunkSize = N_FFT;\n const numChunks = Math.ceil(segment.length / chunkSize);\n \n let results = {\n centroid: 0,\n flatness: 0,\n rollOff: 0,\n bandwidth: 0,\n magnitudeSpectrum: new Float32Array(N_FFT / 2 + 1).fill(0)\n };\n \n let validChunks = 0;\n \n // Iterate through chunks\n for (let i = 0; i < numChunks; i++) {\n const start = i * chunkSize;\n const end = Math.min(start + chunkSize, segment.length);\n const chunk = segment.slice(start, end);\n \n if (chunk.length < N_FFT / 4) continue; // Skip very small chunks\n\n // Process the chunk\n const paddedChunk = new Float32Array(N_FFT);\n paddedChunk.set(applyHannWindow(chunk));\n\n const fft = new FFT(N_FFT);\n fft.transform(paddedChunk);\n\n // Calculate magnitude spectrum\n const chunkMagnitudeSpectrum = new Float32Array(N_FFT / 2 + 1);\n let hasSignal = false;\n \n for (let j = 0; j < N_FFT / 2; j++) {\n const re = paddedChunk[2 * j];\n const im = paddedChunk[2 * j + 1];\n const magnitude = Math.sqrt(re * re + im * im);\n chunkMagnitudeSpectrum[j] = magnitude;\n if (magnitude > Number.EPSILON) hasSignal = true;\n }\n \n if (!hasSignal) continue;\n validChunks++;\n\n // Accumulate results\n if (featureOptions.spectralCentroid) {\n const centroid = computeSpectralCentroid(chunkMagnitudeSpectrum, sampleRate);\n if (!isNaN(centroid)) results.centroid += centroid;\n }\n \n if (featureOptions.spectralFlatness) {\n const flatness = computeSpectralFlatness(chunkMagnitudeSpectrum);\n if (!isNaN(flatness)) results.flatness += flatness;\n }\n \n if (featureOptions.spectralRollOff) {\n const rolloff = computeSpectralRollOff(chunkMagnitudeSpectrum, sampleRate);\n if (!isNaN(rolloff)) results.rollOff += rolloff;\n }\n \n if (featureOptions.spectralBandwidth && !isNaN(results.centroid)) {\n const bandwidth = computeSpectralBandwidth(chunkMagnitudeSpectrum, sampleRate, results.centroid);\n if (!isNaN(bandwidth)) results.bandwidth += bandwidth;\n }\n \n if (featureOptions.magnitudeSpectrum) {\n for (let j = 0; j < results.magnitudeSpectrum.length; j++) {\n results.magnitudeSpectrum[j] += chunkMagnitudeSpectrum[j];\n }\n }\n }\n\n // Average the accumulated results\n if (validChunks > 0) {\n results.centroid /= validChunks;\n results.flatness /= validChunks;\n results.rollOff /= validChunks;\n results.bandwidth /= validChunks;\n \n if (featureOptions.magnitudeSpectrum) {\n for (let i = 0; i < results.magnitudeSpectrum.length; i++) {\n results.magnitudeSpectrum[i] /= validChunks;\n }\n }\n }\n\n return results;\n } catch (error) {\n console.error('[Worker] Spectral feature computation error:', error);\n return {\n centroid: 0,\n flatness: 0,\n rollOff: 0,\n bandwidth: 0,\n magnitudeSpectrum: []\n };\n }\n}\n\nfunction computeSpectralCentroid(magnitudeSpectrum, sampleRate) {\n const sum = magnitudeSpectrum.reduce((a, b) => a + (b || 0), 0);\n if (sum <= Number.EPSILON) return 0;\n \n const weightedSum = magnitudeSpectrum.reduce((acc, value, index) => \n acc + (index * (sampleRate / N_FFT) * (value || 0)), 0);\n \n return weightedSum / sum;\n}\n\nfunction computeSpectralFlatness(powerSpectrum) {\n // Add small epsilon to avoid log(0)\n const epsilon = Number.EPSILON;\n const validSpectrum = powerSpectrum.map(v => Math.max(v, epsilon));\n \n const geometricMean = Math.exp(\n validSpectrum\n .map(v => Math.log(v))\n .reduce((a, b) => a + b) / validSpectrum.length\n );\n \n const arithmeticMean =\n validSpectrum.reduce((a, b) => a + b) / validSpectrum.length;\n \n return geometricMean / arithmeticMean;\n}\n\nfunction computeSpectralRollOff(magnitudeSpectrum, sampleRate) {\n const totalEnergy = magnitudeSpectrum.reduce((a, b) => a + b, 0);\n const rollOffThreshold = totalEnergy * 0.85;\n let cumulativeEnergy = 0;\n\n for (let i = 0; i < magnitudeSpectrum.length; i++) {\n cumulativeEnergy += magnitudeSpectrum[i];\n if (cumulativeEnergy >= rollOffThreshold) {\n return (i / magnitudeSpectrum.length) * (sampleRate / 2);\n }\n }\n\n return 0;\n}\n\nfunction computeSpectralBandwidth(magnitudeSpectrum, sampleRate, centroid) {\n const sum = magnitudeSpectrum.reduce((a, b) => a + (b || 0), 0);\n if (sum <= Number.EPSILON) return 0;\n\n const weightedSum = magnitudeSpectrum.reduce(\n (acc, value, index) => {\n const freq = index * sampleRate / (2 * magnitudeSpectrum.length);\n return acc + (value || 0) * Math.pow(freq - centroid, 2);\n }, 0\n );\n\n return Math.sqrt(weightedSum / sum);\n}\n\nfunction computeChroma(segmentData, sampleRate) {\n // Ensure we have valid input data\n if (!segmentData || segmentData.length === 0) {\n return new Array(N_CHROMA).fill(0);\n }\n\n const fftLength = nextPowerOfTwo(Math.max(segmentData.length, N_FFT));\n const windowed = applyHannWindow(segmentData);\n const padded = new Float32Array(fftLength);\n padded.set(windowed.slice(0, Math.min(windowed.length, fftLength)));\n\n const fft = new FFT(fftLength);\n try {\n fft.transform(padded);\n } catch (e) {\n console.error('[Worker] FFT transform failed in chromagram:', e);\n return new Array(N_CHROMA).fill(0);\n }\n\n const chroma = new Float32Array(N_CHROMA).fill(0);\n const freqsPerBin = sampleRate / fftLength;\n let totalEnergy = 0;\n\n // First pass: compute magnitudes and total energy\n for (let i = 0; i < fftLength / 2; i++) {\n const freq = i * freqsPerBin;\n if (freq > 20) { // Only consider frequencies above 20 Hz\n const re = padded[2 * i];\n const im = padded[2 * i + 1] || 0;\n const magnitude = Math.sqrt(re * re + im * im);\n \n if (magnitude > Number.EPSILON) {\n // Use a more stable pitch class calculation\n const midiNote = 69 + 12 * Math.log2(freq / 440.0);\n const pitchClass = Math.round(midiNote) % 12;\n \n if (pitchClass >= 0 && pitchClass < 12) {\n chroma[pitchClass] += magnitude;\n totalEnergy += magnitude;\n }\n }\n }\n }\n\n // Normalize chroma values only if we have energy\n if (totalEnergy > Number.EPSILON) {\n for (let i = 0; i < N_CHROMA; i++) {\n chroma[i] = chroma[i] / totalEnergy;\n }\n }\n\n // Convert to regular array and ensure no NaN values\n return Array.from(chroma, v => isNaN(v) ? 0 : v);\n}\n\nfunction extractHNR(segmentData) {\n const frameSize = segmentData.length;\n const autocorrelation = new Float32Array(frameSize);\n\n // Compute the autocorrelation iteratively\n for (let i = 0; i < frameSize; i++) {\n let sum = 0;\n for (let j = 0; j < frameSize - i; j++) {\n sum += segmentData[j] * segmentData[j + i];\n }\n autocorrelation[i] = sum;\n }\n\n // Find the maximum autocorrelation value iteratively\n let maxAutocorrelation = -Infinity;\n for (let i = 1; i < autocorrelation.length; i++) {\n if (autocorrelation[i] > maxAutocorrelation) {\n maxAutocorrelation = autocorrelation[i];\n }\n }\n\n // Compute the HNR\n return autocorrelation[0] !== 0\n ? 10 * Math.log10(maxAutocorrelation / (autocorrelation[0] - maxAutocorrelation))\n : 0;\n}\n\nfunction estimatePitch(segment, sampleRate) {\n // Early validation\n if (!segment || segment.length < 2 || !sampleRate) return 0;\n\n try {\n // Apply Hann window\n const windowed = applyHannWindow(segment);\n\n // Pad for FFT\n const fftLength = nextPowerOfTwo(segment.length * 2);\n const padded = new Float32Array(fftLength);\n padded.set(windowed);\n\n // Perform FFT\n const fft = new FFT(fftLength);\n fft.transform(padded);\n\n // Compute power spectrum\n const powerSpectrum = new Float32Array(fftLength / 2 + 1);\n for (let i = 0; i <= fftLength / 2; i++) {\n const re = padded[2 * i];\n const im = padded[2 * i + 1] || 0;\n powerSpectrum[i] = re * re + im * im;\n }\n\n // Find peak frequency\n let maxPower = 0;\n let peakIndex = 0;\n const minFreq = 50; // Minimum frequency to consider (Hz)\n const maxFreq = 1000; // Maximum frequency to consider (Hz)\n const minBin = Math.floor(minFreq * fftLength / sampleRate);\n const maxBin = Math.ceil(maxFreq * fftLength / sampleRate);\n\n for (let i = minBin; i <= maxBin; i++) {\n if (powerSpectrum[i] > maxPower) {\n maxPower = powerSpectrum[i];\n peakIndex = i;\n }\n }\n\n // Convert peak index to frequency\n const fundamentalFreq = peakIndex * sampleRate / fftLength;\n\n // Return 0 if the detected frequency is outside reasonable bounds\n return (fundamentalFreq >= minFreq && fundamentalFreq <= maxFreq) ? \n fundamentalFreq : 0;\n\n } catch (error) {\n console.error('[Worker] Pitch estimation error:', error);\n return 0;\n }\n}\n\n// Unique ID counter\nlet uniqueIdCounter = 0\nlet accumulatedDataPoints = []\nlet lastEmitTime = Date.now()\n\nself.onmessage = function (event) {\n // Check if this is a reset command\n if (event.data.command === 'resetCounter') {\n uniqueIdCounter = event.data.startCounterFrom || 0;\n console.log('[Worker] Reset counter to', uniqueIdCounter);\n return; // Exit early, don't process audio\n }\n\n // Regular audio processing\n const {\n channelData,\n sampleRate,\n segmentDurationMs,\n algorithm,\n bitDepth,\n fullAudioDurationMs,\n numberOfChannels,\n features: _features,\n intervalAnalysis = 500,\n enableLogging,\n resetCounter,\n startCounterFrom,\n } = event.data\n\n // Also handle reset as part of regular message\n if (resetCounter) {\n uniqueIdCounter = startCounterFrom || 0;\n }\n\n // Calculate subChunkStartTime safely, defaulting to 0 if fullAudioDurationMs is not a valid number\n const subChunkStartTime = (typeof fullAudioDurationMs === 'number' && !isNaN(fullAudioDurationMs) && fullAudioDurationMs >= 0)\n ? fullAudioDurationMs / 1000\n : 0;\n\n \n // Create a simple logger that only logs when enabled\n const logger = enableLogging ? {\n debug: (...args) => console.debug('[Worker]', ...args),\n log: (...args) => console.log('[Worker]', ...args),\n error: (...args) => console.error('[Worker]', ...args)\n } : {\n debug: () => {},\n log: () => {},\n error: () => {}\n }\n logger.log('[Worker] START Feature Extractor - hasData: ' + (event.data ? true : false) + ', channelData: ' + (event.data.channelData ? event.data.channelData.length : 0) + ', fullAudioDurationMs: ' + (event.data.fullAudioDurationMs || 0) + ', sampleRate: ' + (event.data.sampleRate || 0) + ', segmentDurationMs: ' + (event.data.segmentDurationMs || 0) + ', algorithm: ' + (event.data.algorithm || 'none') + ', bitDepth: ' + (event.data.bitDepth || 0) + ', numberOfChannels: ' + (event.data.numberOfChannels || 0) + ', features: ' + (event.data.features ? Object.keys(event.data.features).length : 0) + ', intervalAnalysis: ' + (event.data.intervalAnalysis || 0) + ', dataKeys: ' + (event.data ? Object.keys(event.data).join(',') : ''));\n \n const features = _features || {}\n const bytesPerSample = bitDepth / 8; // Calculate bytes per sample\n\n const SILENCE_THRESHOLD = 0.01\n const MIN_SILENCE_DURATION = 1.5 * sampleRate // 1.5 seconds of silence\n const SPEECH_INERTIA_DURATION = 0.1 * sampleRate // Speech inertia duration in samples\n const RMS_THRESHOLD = 0.01\n const ZCR_THRESHOLD = 0.1\n\n // Placeholder functions for feature extraction\n const extractMFCC = (segmentData, sampleRate) => {\n // Implement MFCC extraction logic here\n return []\n }\n\n const extractSpectralCentroid = (segmentData, sampleRate) => {\n const magnitudeSpectrum = segmentData.map((v) => v * v)\n const sum = magnitudeSpectrum.reduce((a, b) => a + b, 0)\n if (sum === 0) return 0\n\n const weightedSum = magnitudeSpectrum.reduce(\n (acc, value, index) => acc + index * value,\n 0\n )\n return (\n ((weightedSum / sum) * (sampleRate / 2)) / magnitudeSpectrum.length\n )\n }\n\n const extractSpectralFlatness = (segmentData) => {\n const magnitudeSpectrum = segmentData.map((v) => Math.abs(v))\n const geometricMean = Math.exp(\n magnitudeSpectrum\n .map((v) => Math.log(v + Number.MIN_VALUE))\n .reduce((a, b) => a + b) / magnitudeSpectrum.length\n )\n const arithmeticMean =\n magnitudeSpectrum.reduce((a, b) => a + b) / magnitudeSpectrum.length\n return arithmeticMean === 0 ? 0 : geometricMean / arithmeticMean\n }\n\n const extractSpectralRollOff = (segmentData, sampleRate) => {\n const magnitudeSpectrum = segmentData.map((v) => Math.abs(v))\n const totalEnergy = magnitudeSpectrum.reduce((a, b) => a + b, 0)\n const rollOffThreshold = totalEnergy * 0.85\n let cumulativeEnergy = 0\n\n for (let i = 0; i < magnitudeSpectrum.length; i++) {\n cumulativeEnergy += magnitudeSpectrum[i]\n if (cumulativeEnergy >= rollOffThreshold) {\n return (i / magnitudeSpectrum.length) * (sampleRate / 2)\n }\n }\n\n return 0\n }\n\n const extractSpectralBandwidth = (segmentData, sampleRate) => {\n const centroid = extractSpectralCentroid(segmentData, sampleRate)\n const magnitudeSpectrum = segmentData.map((v) => Math.abs(v))\n const sum = magnitudeSpectrum.reduce((a, b) => a + b, 0)\n if (sum === 0) return 0\n\n const weightedSum = magnitudeSpectrum.reduce(\n (acc, value, index) => acc + value * Math.pow(index - centroid, 2),\n 0\n )\n return Math.sqrt(weightedSum / sum)\n }\n\n const extractChromagram = (segmentData, sampleRate) => {\n return [] // TODO implement\n }\n\n /**\n * Creates a features object based on requested features\n */\n function createFeaturesObject(\n features,\n maxAmp,\n rms,\n sumSquares,\n zeroCrossings,\n remainingSamples,\n spectralFeatures,\n channelData,\n startIdx,\n endIdx,\n sampleRate,\n numberOfChannels,\n bytesPerSample\n ) {\n // If no features are requested, return undefined\n if (!Object.values(features).some(function(v) { return v; })) {\n return undefined;\n }\n\n const result = {};\n \n if (features.energy) {\n result.energy = sumSquares;\n }\n if (features.rms) {\n result.rms = rms;\n }\n // Always include min/max amplitude if any features are requested\n result.minAmplitude = -maxAmp;\n result.maxAmplitude = maxAmp;\n \n if (features.zcr) {\n result.zcr = zeroCrossings / remainingSamples;\n }\n if (features.spectralCentroid) {\n result.spectralCentroid = spectralFeatures.centroid;\n }\n if (features.spectralFlatness) {\n result.spectralFlatness = spectralFeatures.flatness;\n }\n if (features.spectralRolloff) {\n result.spectralRolloff = spectralFeatures.rollOff;\n }\n if (features.spectralBandwidth) {\n result.spectralBandwidth = spectralFeatures.bandwidth;\n }\n if (features.chromagram) {\n result.chromagram = computeChroma(channelData.slice(startIdx, endIdx), sampleRate);\n }\n if (features.hnr) {\n result.hnr = extractHNR(channelData.slice(startIdx, endIdx));\n }\n if (features.pitch) {\n result.pitch = estimatePitch(channelData.slice(startIdx, endIdx), sampleRate);\n }\n \n return result;\n }\n\n function extractWaveform(\n channelData,\n sampleRate,\n segmentDurationMs,\n numberOfChannels,\n bytesPerSample\n ) {\n const logger = enableLogging ? {\n debug: (...args) => console.debug('[Worker]', ...args),\n log: (...args) => console.log('[Worker]', ...args),\n error: (...args) => console.error('[Worker]', ...args)\n } : {\n debug: () => {},\n log: () => {},\n error: () => {}\n }\n\n // Calculate amplitude range\n let min = Infinity\n let max = -Infinity\n for (let i = 0; i < channelData.length; i++) {\n min = Math.min(min, channelData[i])\n max = Math.max(max, channelData[i])\n }\n\n const totalSamples = channelData.length\n const durationMs = (totalSamples / sampleRate) * 1000\n \n // Calculate fixed segment sizes\n const samplesPerSegment = Math.floor(sampleRate * (segmentDurationMs / 1000));\n const numPoints = Math.floor(totalSamples / samplesPerSegment);\n const remainingSamples = totalSamples % samplesPerSegment;\n\n const dataPoints = []\n\n // Process full segments\n for (let i = 0; i < numPoints; i++) {\n const startIdx = i * samplesPerSegment\n const endIdx = startIdx + samplesPerSegment\n \n let sumSquares = 0\n let maxAmp = 0\n let zeroCrossings = 0\n\n // Calculate segment features\n for (let j = startIdx; j < endIdx; j++) {\n const value = channelData[j]\n sumSquares += value * value\n maxAmp = Math.max(maxAmp, Math.abs(value))\n if (j > 0 && value * channelData[j - 1] < 0) {\n zeroCrossings++\n }\n }\n\n const rms = Math.sqrt(sumSquares / samplesPerSegment)\n const startTime = subChunkStartTime + (startIdx / sampleRate)\n const endTime = subChunkStartTime + (endIdx / sampleRate)\n // Calculate byte positions correctly based on numberOfChannels and bytesPerSample\n const startPosition = startIdx * numberOfChannels * bytesPerSample\n const endPosition = endIdx * numberOfChannels * bytesPerSample\n\n var spectralFeatures = computeSpectralFeatures(channelData.slice(startIdx, endIdx), sampleRate, features);\n\n const dataPoint = {\n id: uniqueIdCounter++,\n amplitude: maxAmp,\n rms,\n startTime,\n endTime,\n dB: 20 * Math.log10(rms + 1e-6),\n silent: rms < 0.01,\n startPosition,\n endPosition,\n samples: samplesPerSegment,\n }\n\n // Extract features if any are requested\n const extractedFeatures = createFeaturesObject(\n features,\n maxAmp,\n rms,\n sumSquares,\n zeroCrossings,\n samplesPerSegment,\n spectralFeatures,\n channelData,\n startIdx,\n endIdx,\n sampleRate,\n numberOfChannels,\n bytesPerSample\n );\n \n if (extractedFeatures) {\n dataPoint.features = extractedFeatures;\n }\n\n dataPoints.push(dataPoint)\n }\n\n // Handle remaining samples if they exist and are enough to process\n if (remainingSamples > samplesPerSegment / 4) { // Only process if we have at least 1/4 of a segment\n const startIdx = numPoints * samplesPerSegment\n const endIdx = totalSamples\n \n let sumSquares = 0\n let maxAmp = 0\n let zeroCrossings = 0\n\n for (let j = startIdx; j < endIdx; j++) {\n const value = channelData[j]\n sumSquares += value * value\n maxAmp = Math.max(maxAmp, Math.abs(value))\n if (j > 0 && value * channelData[j - 1] < 0) {\n zeroCrossings++\n }\n }\n\n const rms = Math.sqrt(sumSquares / remainingSamples)\n const startTime = subChunkStartTime + (startIdx / sampleRate);\n const endTime = subChunkStartTime + (endIdx / sampleRate);\n // Calculate byte positions correctly based on numberOfChannels and bytesPerSample\n const startPosition = startIdx * numberOfChannels * bytesPerSample\n const endPosition = endIdx * numberOfChannels * bytesPerSample\n\n var spectralFeatures = computeSpectralFeatures(channelData.slice(startIdx, endIdx), sampleRate, features);\n\n const dataPoint = {\n id: uniqueIdCounter++,\n amplitude: maxAmp,\n rms,\n startTime,\n endTime,\n dB: 20 * Math.log10(rms + 1e-6),\n silent: rms < 0.01,\n startPosition,\n endPosition,\n samples: remainingSamples,\n }\n\n logger.log('[Worker] extractWaveform - dataPoint', dataPoint)\n // Extract features if any are requested\n const extractedFeatures = createFeaturesObject(\n features,\n maxAmp,\n rms,\n sumSquares,\n zeroCrossings,\n remainingSamples,\n spectralFeatures,\n channelData,\n startIdx,\n endIdx,\n sampleRate,\n numberOfChannels,\n bytesPerSample\n );\n \n if (extractedFeatures) {\n dataPoint.features = extractedFeatures;\n }\n\n dataPoints.push(dataPoint)\n }\n\n return {\n durationMs,\n dataPoints,\n amplitudeRange: { min, max },\n rmsRange: {\n min: 0,\n max: Math.max(Math.abs(min), Math.abs(max))\n },\n extractionTimeMs: Date.now() - lastEmitTime\n }\n }\n\n try {\n const result = extractWaveform(\n channelData,\n sampleRate,\n segmentDurationMs,\n numberOfChannels || 1, // Default to 1 channel if not provided\n bytesPerSample\n )\n\n // Send complete result immediately\n self.postMessage({\n command: 'features',\n result: {\n bitDepth,\n samples: channelData.length,\n numberOfChannels,\n sampleRate,\n segmentDurationMs,\n durationMs: result.durationMs,\n dataPoints: result.dataPoints,\n amplitudeRange: result.amplitudeRange,\n rmsRange: result.rmsRange,\n }\n })\n } catch (error) {\n console.error('[Worker] Error', {\n message: error.message,\n stack: error.stack\n });\n \n self.postMessage({ \n error: {\n message: error.message,\n stack: error.stack,\n name: error.name\n }\n });\n }\n}\n";
1
+ export declare const InlineFeaturesExtractor = "\n// Constants\nconst N_FFT = 1024; // Default FFT size\nconst MAX_FFT_SIZE = 8192; // Maximum FFT size to prevent memory issues\nconst N_CHROMA = 12;\n\n// FFT Implementation with normalized Hann window\nfunction FFT(n) {\n this.n = n;\n this.cosTable = new Float32Array(n / 2);\n this.sinTable = new Float32Array(n / 2);\n this.hannWindow = new Float32Array(n);\n \n // Match Android implementation with precomputed tables\n const normalizationFactor = Math.sqrt(2.0 / n);\n for (var i = 0; i < n / 2; i++) {\n this.cosTable[i] = Math.cos(2.0 * Math.PI * i / n);\n this.sinTable[i] = Math.sin(2.0 * Math.PI * i / n);\n }\n \n // Precompute normalized Hann window to match Android\n for (var i = 0; i < n; i++) {\n this.hannWindow[i] = normalizationFactor * 0.5 * (1 - Math.cos(2.0 * Math.PI * i / (n - 1)));\n }\n}\n\nFFT.prototype.transform = function(data) {\n const n = data.length;\n \n // Validate input length is power of 2\n if ((n & (n - 1)) !== 0) {\n throw new Error('FFT length must be power of 2');\n }\n\n // Use iterative bit reversal instead of recursive\n const bitReversedIndices = new Uint32Array(n);\n for (let i = 0; i < n; i++) {\n let reversed = 0;\n let j = i;\n let bits = Math.log2(n);\n while (bits--) {\n reversed = (reversed << 1) | (j & 1);\n j >>= 1;\n }\n bitReversedIndices[i] = reversed;\n }\n\n // Apply bit reversal\n for (let i = 0; i < n; i++) {\n const j = bitReversedIndices[i];\n if (i < j) {\n const temp = data[i];\n data[i] = data[j];\n data[j] = temp;\n }\n }\n\n // Iterative FFT computation with optimized memory usage\n for (let step = 1; step < n; step <<= 1) {\n const jump = step << 1;\n const angleStep = Math.PI / step;\n\n for (let group = 0; group < n; group += jump) {\n for (let pair = group; pair < group + step; pair++) {\n const match = pair + step;\n const angle = angleStep * (pair - group);\n \n const currentCos = Math.cos(angle);\n const currentSin = Math.sin(angle);\n\n const real = currentCos * data[match] - currentSin * data[match + 1];\n const imag = currentCos * data[match + 1] + currentSin * data[match];\n\n data[match] = data[pair] - real;\n data[match + 1] = data[pair + 1] - imag;\n data[pair] += real;\n data[pair + 1] += imag;\n }\n }\n }\n};\n\n// Add realInverse method\nFFT.prototype.realInverse = function(powerSpectrum, output) {\n const n = powerSpectrum.length;\n const complexData = new Float32Array(n * 2);\n \n // Copy power spectrum to complex format\n for (let i = 0; i < n/2 + 1; i++) {\n complexData[2 * i] = powerSpectrum[i];\n if (2 * i + 1 < complexData.length) {\n complexData[2 * i + 1] = 0;\n }\n }\n \n // Conjugate for inverse FFT\n for (let i = 0; i < n; i++) {\n if (2 * i + 1 < complexData.length) {\n complexData[2 * i + 1] = -complexData[2 * i + 1];\n }\n }\n \n this.transform(complexData);\n \n // Copy real part to output and scale\n for (let i = 0; i < n; i++) {\n output[i] = complexData[2 * i] / n;\n }\n};\n\n// Add helper functions to match Android\nfunction nextPowerOfTwo(n) {\n let value = 1;\n while (value < n) {\n value *= 2;\n }\n return value;\n}\n\nfunction applyHannWindow(samples) {\n const output = new Float32Array(samples.length);\n for (let i = 0; i < samples.length; i++) {\n const multiplier = 0.5 * (1 - Math.cos(2 * Math.PI * i / (samples.length - 1)));\n output[i] = samples[i] * multiplier;\n }\n return output;\n}\n\n// Update spectral feature computation to match Android\nfunction computeSpectralFeatures(segment, sampleRate, featureOptions = {}) {\n try {\n // Early return if no spectral features are requested\n if (!featureOptions.spectralCentroid && \n !featureOptions.spectralFlatness && \n !featureOptions.spectralRollOff && \n !featureOptions.spectralBandwidth &&\n !featureOptions.magnitudeSpectrum) {\n return {\n centroid: 0,\n flatness: 0,\n rollOff: 0,\n bandwidth: 0,\n magnitudeSpectrum: []\n };\n }\n\n // Ensure we have valid data\n if (!segment || segment.length === 0) {\n throw new Error('Invalid segment data');\n }\n\n // Process in fixed-size chunks\n const chunkSize = N_FFT;\n const numChunks = Math.ceil(segment.length / chunkSize);\n \n let results = {\n centroid: 0,\n flatness: 0,\n rollOff: 0,\n bandwidth: 0,\n magnitudeSpectrum: new Float32Array(N_FFT / 2 + 1).fill(0)\n };\n \n let validChunks = 0;\n \n // Iterate through chunks\n for (let i = 0; i < numChunks; i++) {\n const start = i * chunkSize;\n const end = Math.min(start + chunkSize, segment.length);\n const chunk = segment.slice(start, end);\n \n if (chunk.length < N_FFT / 4) continue; // Skip very small chunks\n\n // Process the chunk\n const paddedChunk = new Float32Array(N_FFT);\n paddedChunk.set(applyHannWindow(chunk));\n\n const fft = new FFT(N_FFT);\n fft.transform(paddedChunk);\n\n // Calculate magnitude spectrum\n const chunkMagnitudeSpectrum = new Float32Array(N_FFT / 2 + 1);\n let hasSignal = false;\n \n for (let j = 0; j < N_FFT / 2; j++) {\n const re = paddedChunk[2 * j];\n const im = paddedChunk[2 * j + 1];\n const magnitude = Math.sqrt(re * re + im * im);\n chunkMagnitudeSpectrum[j] = magnitude;\n if (magnitude > Number.EPSILON) hasSignal = true;\n }\n \n if (!hasSignal) continue;\n validChunks++;\n\n // Accumulate results\n if (featureOptions.spectralCentroid) {\n const centroid = computeSpectralCentroid(chunkMagnitudeSpectrum, sampleRate);\n if (!isNaN(centroid)) results.centroid += centroid;\n }\n \n if (featureOptions.spectralFlatness) {\n const flatness = computeSpectralFlatness(chunkMagnitudeSpectrum);\n if (!isNaN(flatness)) results.flatness += flatness;\n }\n \n if (featureOptions.spectralRollOff) {\n const rolloff = computeSpectralRollOff(chunkMagnitudeSpectrum, sampleRate);\n if (!isNaN(rolloff)) results.rollOff += rolloff;\n }\n \n if (featureOptions.spectralBandwidth && !isNaN(results.centroid)) {\n const bandwidth = computeSpectralBandwidth(chunkMagnitudeSpectrum, sampleRate, results.centroid);\n if (!isNaN(bandwidth)) results.bandwidth += bandwidth;\n }\n \n if (featureOptions.magnitudeSpectrum) {\n for (let j = 0; j < results.magnitudeSpectrum.length; j++) {\n results.magnitudeSpectrum[j] += chunkMagnitudeSpectrum[j];\n }\n }\n }\n\n // Average the accumulated results\n if (validChunks > 0) {\n results.centroid /= validChunks;\n results.flatness /= validChunks;\n results.rollOff /= validChunks;\n results.bandwidth /= validChunks;\n \n if (featureOptions.magnitudeSpectrum) {\n for (let i = 0; i < results.magnitudeSpectrum.length; i++) {\n results.magnitudeSpectrum[i] /= validChunks;\n }\n }\n }\n\n return results;\n } catch (error) {\n console.error('[Worker] Spectral feature computation error:', error);\n return {\n centroid: 0,\n flatness: 0,\n rollOff: 0,\n bandwidth: 0,\n magnitudeSpectrum: []\n };\n }\n}\n\nfunction computeSpectralCentroid(magnitudeSpectrum, sampleRate) {\n const sum = magnitudeSpectrum.reduce((a, b) => a + (b || 0), 0);\n if (sum <= Number.EPSILON) return 0;\n \n const weightedSum = magnitudeSpectrum.reduce((acc, value, index) => \n acc + (index * (sampleRate / N_FFT) * (value || 0)), 0);\n \n return weightedSum / sum;\n}\n\nfunction computeSpectralFlatness(powerSpectrum) {\n // Add small epsilon to avoid log(0)\n const epsilon = Number.EPSILON;\n const validSpectrum = powerSpectrum.map(v => Math.max(v, epsilon));\n \n const geometricMean = Math.exp(\n validSpectrum\n .map(v => Math.log(v))\n .reduce((a, b) => a + b) / validSpectrum.length\n );\n \n const arithmeticMean =\n validSpectrum.reduce((a, b) => a + b) / validSpectrum.length;\n \n return geometricMean / arithmeticMean;\n}\n\nfunction computeSpectralRollOff(magnitudeSpectrum, sampleRate) {\n const totalEnergy = magnitudeSpectrum.reduce((a, b) => a + b, 0);\n const rollOffThreshold = totalEnergy * 0.85;\n let cumulativeEnergy = 0;\n\n for (let i = 0; i < magnitudeSpectrum.length; i++) {\n cumulativeEnergy += magnitudeSpectrum[i];\n if (cumulativeEnergy >= rollOffThreshold) {\n return (i / magnitudeSpectrum.length) * (sampleRate / 2);\n }\n }\n\n return 0;\n}\n\nfunction computeSpectralBandwidth(magnitudeSpectrum, sampleRate, centroid) {\n const sum = magnitudeSpectrum.reduce((a, b) => a + (b || 0), 0);\n if (sum <= Number.EPSILON) return 0;\n\n const weightedSum = magnitudeSpectrum.reduce(\n (acc, value, index) => {\n const freq = index * sampleRate / (2 * magnitudeSpectrum.length);\n return acc + (value || 0) * Math.pow(freq - centroid, 2);\n }, 0\n );\n\n return Math.sqrt(weightedSum / sum);\n}\n\nfunction computeChroma(segmentData, sampleRate) {\n // Ensure we have valid input data\n if (!segmentData || segmentData.length === 0) {\n return new Array(N_CHROMA).fill(0);\n }\n\n const fftLength = nextPowerOfTwo(Math.max(segmentData.length, N_FFT));\n const windowed = applyHannWindow(segmentData);\n const padded = new Float32Array(fftLength);\n padded.set(windowed.slice(0, Math.min(windowed.length, fftLength)));\n\n const fft = new FFT(fftLength);\n try {\n fft.transform(padded);\n } catch (e) {\n console.error('[Worker] FFT transform failed in chromagram:', e);\n return new Array(N_CHROMA).fill(0);\n }\n\n const chroma = new Float32Array(N_CHROMA).fill(0);\n const freqsPerBin = sampleRate / fftLength;\n let totalEnergy = 0;\n\n // First pass: compute magnitudes and total energy\n for (let i = 0; i < fftLength / 2; i++) {\n const freq = i * freqsPerBin;\n if (freq > 20) { // Only consider frequencies above 20 Hz\n const re = padded[2 * i];\n const im = padded[2 * i + 1] || 0;\n const magnitude = Math.sqrt(re * re + im * im);\n \n if (magnitude > Number.EPSILON) {\n // Use a more stable pitch class calculation\n const midiNote = 69 + 12 * Math.log2(freq / 440.0);\n const pitchClass = Math.round(midiNote) % 12;\n \n if (pitchClass >= 0 && pitchClass < 12) {\n chroma[pitchClass] += magnitude;\n totalEnergy += magnitude;\n }\n }\n }\n }\n\n // Normalize chroma values only if we have energy\n if (totalEnergy > Number.EPSILON) {\n for (let i = 0; i < N_CHROMA; i++) {\n chroma[i] = chroma[i] / totalEnergy;\n }\n }\n\n // Convert to regular array and ensure no NaN values\n return Array.from(chroma, v => isNaN(v) ? 0 : v);\n}\n\nfunction extractHNR(segmentData) {\n const frameSize = segmentData.length;\n const autocorrelation = new Float32Array(frameSize);\n\n // Compute the autocorrelation iteratively\n for (let i = 0; i < frameSize; i++) {\n let sum = 0;\n for (let j = 0; j < frameSize - i; j++) {\n sum += segmentData[j] * segmentData[j + i];\n }\n autocorrelation[i] = sum;\n }\n\n // Find the maximum autocorrelation value iteratively\n let maxAutocorrelation = -Infinity;\n for (let i = 1; i < autocorrelation.length; i++) {\n if (autocorrelation[i] > maxAutocorrelation) {\n maxAutocorrelation = autocorrelation[i];\n }\n }\n\n // Compute the HNR\n return autocorrelation[0] !== 0\n ? 10 * Math.log10(maxAutocorrelation / (autocorrelation[0] - maxAutocorrelation))\n : 0;\n}\n\nfunction estimatePitch(segment, sampleRate) {\n // Early validation\n if (!segment || segment.length < 2 || !sampleRate) return 0;\n\n try {\n // Apply Hann window\n const windowed = applyHannWindow(segment);\n\n // Pad for FFT\n const fftLength = nextPowerOfTwo(segment.length * 2);\n const padded = new Float32Array(fftLength);\n padded.set(windowed);\n\n // Perform FFT\n const fft = new FFT(fftLength);\n fft.transform(padded);\n\n // Compute power spectrum\n const powerSpectrum = new Float32Array(fftLength / 2 + 1);\n for (let i = 0; i <= fftLength / 2; i++) {\n const re = padded[2 * i];\n const im = padded[2 * i + 1] || 0;\n powerSpectrum[i] = re * re + im * im;\n }\n\n // Find peak frequency\n let maxPower = 0;\n let peakIndex = 0;\n const minFreq = 50; // Minimum frequency to consider (Hz)\n const maxFreq = 1000; // Maximum frequency to consider (Hz)\n const minBin = Math.floor(minFreq * fftLength / sampleRate);\n const maxBin = Math.ceil(maxFreq * fftLength / sampleRate);\n\n for (let i = minBin; i <= maxBin; i++) {\n if (powerSpectrum[i] > maxPower) {\n maxPower = powerSpectrum[i];\n peakIndex = i;\n }\n }\n\n // Convert peak index to frequency\n const fundamentalFreq = peakIndex * sampleRate / fftLength;\n\n // Return 0 if the detected frequency is outside reasonable bounds\n return (fundamentalFreq >= minFreq && fundamentalFreq <= maxFreq) ? \n fundamentalFreq : 0;\n\n } catch (error) {\n console.error('[Worker] Pitch estimation error:', error);\n return 0;\n }\n}\n\n// Unique ID counter - the only state we need to maintain\nlet uniqueIdCounter = 0\nlet lastEmitTime = Date.now()\n\nself.onmessage = function (event) {\n // Extract enableLogging early so we can use it consistently\n const enableLogging = event.data.enableLogging || false;\n \n // Create consistent logger that only logs when enabled\n const logger = enableLogging ? {\n debug: (...args) => console.debug('[Worker]', ...args),\n log: (...args) => console.log('[Worker]', ...args),\n warn: (...args) => console.warn('[Worker]', ...args),\n error: (...args) => console.error('[Worker]', ...args)\n } : {\n debug: () => {},\n log: () => {},\n warn: () => {},\n error: () => {}\n };\n \n // Check if this is a reset command\n if (event.data.command === 'resetCounter') {\n const newValue = event.data.value;\n logger.log('Reset counter request received with value:', newValue);\n \n // Always respect explicit resets through the resetCounter command\n uniqueIdCounter = typeof newValue === 'number' ? newValue : 0;\n logger.log('Counter explicitly set to:', uniqueIdCounter);\n \n return; // Exit early, don't process audio\n }\n\n // Regular audio processing\n const {\n channelData,\n sampleRate,\n segmentDurationMs,\n algorithm,\n bitDepth,\n fullAudioDurationMs,\n numberOfChannels,\n features: _features,\n intervalAnalysis = 500,\n } = event.data\n\n // Calculate subChunkStartTime safely, defaulting to 0 if fullAudioDurationMs is not a valid number\n const subChunkStartTime = (typeof fullAudioDurationMs === 'number' && !isNaN(fullAudioDurationMs) && fullAudioDurationMs >= 0)\n ? fullAudioDurationMs / 1000\n : 0;\n\n const features = _features || {}\n const bytesPerSample = bitDepth / 8; // Calculate bytes per sample\n\n const SILENCE_THRESHOLD = 0.01\n const MIN_SILENCE_DURATION = 1.5 * sampleRate // 1.5 seconds of silence\n const SPEECH_INERTIA_DURATION = 0.1 * sampleRate // Speech inertia duration in samples\n const RMS_THRESHOLD = 0.01\n const ZCR_THRESHOLD = 0.1\n\n // Placeholder functions for feature extraction\n const extractMFCC = (segmentData, sampleRate) => {\n // Implement MFCC extraction logic here\n return []\n }\n\n const extractSpectralCentroid = (segmentData, sampleRate) => {\n const magnitudeSpectrum = segmentData.map((v) => v * v)\n const sum = magnitudeSpectrum.reduce((a, b) => a + b, 0)\n if (sum === 0) return 0\n\n const weightedSum = magnitudeSpectrum.reduce(\n (acc, value, index) => acc + index * value,\n 0\n )\n return (\n ((weightedSum / sum) * (sampleRate / 2)) / magnitudeSpectrum.length\n )\n }\n\n const extractSpectralFlatness = (segmentData) => {\n const magnitudeSpectrum = segmentData.map((v) => Math.abs(v))\n const geometricMean = Math.exp(\n magnitudeSpectrum\n .map((v) => Math.log(v + Number.MIN_VALUE))\n .reduce((a, b) => a + b) / magnitudeSpectrum.length\n )\n const arithmeticMean =\n magnitudeSpectrum.reduce((a, b) => a + b) / magnitudeSpectrum.length\n return arithmeticMean === 0 ? 0 : geometricMean / arithmeticMean\n }\n\n const extractSpectralRollOff = (segmentData, sampleRate) => {\n const magnitudeSpectrum = segmentData.map((v) => Math.abs(v))\n const totalEnergy = magnitudeSpectrum.reduce((a, b) => a + b, 0)\n const rollOffThreshold = totalEnergy * 0.85\n let cumulativeEnergy = 0\n\n for (let i = 0; i < magnitudeSpectrum.length; i++) {\n cumulativeEnergy += magnitudeSpectrum[i]\n if (cumulativeEnergy >= rollOffThreshold) {\n return (i / magnitudeSpectrum.length) * (sampleRate / 2)\n }\n }\n\n return 0\n }\n\n const extractSpectralBandwidth = (segmentData, sampleRate) => {\n const centroid = extractSpectralCentroid(segmentData, sampleRate)\n const magnitudeSpectrum = segmentData.map((v) => Math.abs(v))\n const sum = magnitudeSpectrum.reduce((a, b) => a + b, 0)\n if (sum === 0) return 0\n\n const weightedSum = magnitudeSpectrum.reduce(\n (acc, value, index) => acc + value * Math.pow(index - centroid, 2),\n 0\n )\n return Math.sqrt(weightedSum / sum)\n }\n\n const extractChromagram = (segmentData, sampleRate) => {\n return [] // TODO implement\n }\n\n /**\n * Creates a features object based on requested features\n */\n function createFeaturesObject(\n features,\n maxAmp,\n rms,\n sumSquares,\n zeroCrossings,\n remainingSamples,\n spectralFeatures,\n channelData,\n startIdx,\n endIdx,\n sampleRate,\n numberOfChannels,\n bytesPerSample\n ) {\n // If no features are requested, return undefined\n if (!Object.values(features).some(function(v) { return v; })) {\n return undefined;\n }\n\n const result = {};\n \n if (features.energy) {\n result.energy = sumSquares;\n }\n if (features.rms) {\n result.rms = rms;\n }\n // Always include min/max amplitude if any features are requested\n result.minAmplitude = -maxAmp;\n result.maxAmplitude = maxAmp;\n \n if (features.zcr) {\n result.zcr = zeroCrossings / remainingSamples;\n }\n if (features.spectralCentroid) {\n result.spectralCentroid = spectralFeatures.centroid;\n }\n if (features.spectralFlatness) {\n result.spectralFlatness = spectralFeatures.flatness;\n }\n if (features.spectralRolloff) {\n result.spectralRolloff = spectralFeatures.rollOff;\n }\n if (features.spectralBandwidth) {\n result.spectralBandwidth = spectralFeatures.bandwidth;\n }\n if (features.chromagram) {\n result.chromagram = computeChroma(channelData.slice(startIdx, endIdx), sampleRate);\n }\n if (features.hnr) {\n result.hnr = extractHNR(channelData.slice(startIdx, endIdx));\n }\n if (features.pitch) {\n result.pitch = estimatePitch(channelData.slice(startIdx, endIdx), sampleRate);\n }\n \n return result;\n }\n\n function extractWaveform(\n channelData,\n sampleRate,\n segmentDurationMs,\n numberOfChannels,\n bytesPerSample\n ) {\n const logger = enableLogging ? {\n debug: (...args) => console.debug('[Worker]', ...args),\n log: (...args) => console.log('[Worker]', ...args),\n error: (...args) => console.error('[Worker]', ...args)\n } : {\n debug: () => {},\n log: () => {},\n error: () => {}\n }\n\n // Calculate amplitude range\n let min = Infinity\n let max = -Infinity\n for (let i = 0; i < channelData.length; i++) {\n min = Math.min(min, channelData[i])\n max = Math.max(max, channelData[i])\n }\n\n const totalSamples = channelData.length\n const durationMs = (totalSamples / sampleRate) * 1000\n \n // Calculate fixed segment sizes\n const samplesPerSegment = Math.floor(sampleRate * (segmentDurationMs / 1000));\n const numPoints = Math.floor(totalSamples / samplesPerSegment);\n const remainingSamples = totalSamples % samplesPerSegment;\n\n const dataPoints = []\n\n // Process full segments\n for (let i = 0; i < numPoints; i++) {\n const startIdx = i * samplesPerSegment\n const endIdx = startIdx + samplesPerSegment\n \n let sumSquares = 0\n let maxAmp = 0\n let zeroCrossings = 0\n\n // Calculate segment features\n for (let j = startIdx; j < endIdx; j++) {\n const value = channelData[j]\n sumSquares += value * value\n maxAmp = Math.max(maxAmp, Math.abs(value))\n if (j > 0 && value * channelData[j - 1] < 0) {\n zeroCrossings++\n }\n }\n\n const rms = Math.sqrt(sumSquares / samplesPerSegment)\n const startTime = subChunkStartTime + (startIdx / sampleRate)\n const endTime = subChunkStartTime + (endIdx / sampleRate)\n // Calculate byte positions correctly based on numberOfChannels and bytesPerSample\n const startPosition = startIdx * numberOfChannels * bytesPerSample\n const endPosition = endIdx * numberOfChannels * bytesPerSample\n\n var spectralFeatures = computeSpectralFeatures(channelData.slice(startIdx, endIdx), sampleRate, features);\n\n // Simply use the counter, increment after assigning\n const dataPoint = {\n id: uniqueIdCounter++,\n amplitude: maxAmp,\n rms,\n startTime,\n endTime,\n dB: 20 * Math.log10(rms + 1e-6),\n silent: rms < 0.01,\n startPosition,\n endPosition,\n samples: samplesPerSegment,\n }\n\n // Extract features if any are requested\n const extractedFeatures = createFeaturesObject(\n features,\n maxAmp,\n rms,\n sumSquares,\n zeroCrossings,\n samplesPerSegment,\n spectralFeatures,\n channelData,\n startIdx,\n endIdx,\n sampleRate,\n numberOfChannels,\n bytesPerSample\n );\n \n if (extractedFeatures) {\n dataPoint.features = extractedFeatures;\n }\n\n dataPoints.push(dataPoint)\n }\n\n // Handle remaining samples if they exist and are enough to process\n if (remainingSamples > samplesPerSegment / 4) { // Only process if we have at least 1/4 of a segment\n const startIdx = numPoints * samplesPerSegment\n const endIdx = totalSamples\n \n let sumSquares = 0\n let maxAmp = 0\n let zeroCrossings = 0\n\n for (let j = startIdx; j < endIdx; j++) {\n const value = channelData[j]\n sumSquares += value * value\n maxAmp = Math.max(maxAmp, Math.abs(value))\n if (j > 0 && value * channelData[j - 1] < 0) {\n zeroCrossings++\n }\n }\n\n const rms = Math.sqrt(sumSquares / remainingSamples)\n const startTime = subChunkStartTime + (startIdx / sampleRate);\n const endTime = subChunkStartTime + (endIdx / sampleRate);\n // Calculate byte positions correctly based on numberOfChannels and bytesPerSample\n const startPosition = startIdx * numberOfChannels * bytesPerSample\n const endPosition = endIdx * numberOfChannels * bytesPerSample\n\n var spectralFeatures = computeSpectralFeatures(channelData.slice(startIdx, endIdx), sampleRate, features);\n\n // Simply use the counter, increment after assigning\n const dataPoint = {\n id: uniqueIdCounter++,\n amplitude: maxAmp,\n rms,\n startTime,\n endTime,\n dB: 20 * Math.log10(rms + 1e-6),\n silent: rms < 0.01,\n startPosition,\n endPosition,\n samples: remainingSamples,\n }\n\n logger.debug('extractWaveform - dataPoint', dataPoint);\n // Extract features if any are requested\n const extractedFeatures = createFeaturesObject(\n features,\n maxAmp,\n rms,\n sumSquares,\n zeroCrossings,\n remainingSamples,\n spectralFeatures,\n channelData,\n startIdx,\n endIdx,\n sampleRate,\n numberOfChannels,\n bytesPerSample\n );\n \n if (extractedFeatures) {\n dataPoint.features = extractedFeatures;\n }\n\n dataPoints.push(dataPoint)\n }\n\n return {\n durationMs,\n dataPoints,\n amplitudeRange: { min, max },\n rmsRange: {\n min: 0,\n max: Math.max(Math.abs(min), Math.abs(max))\n },\n extractionTimeMs: Date.now() - lastEmitTime\n }\n }\n\n try {\n const result = extractWaveform(\n channelData,\n sampleRate,\n segmentDurationMs,\n numberOfChannels || 1, // Default to 1 channel if not provided\n bytesPerSample\n )\n\n // Send complete result immediately\n self.postMessage({\n command: 'features',\n result: {\n bitDepth,\n samples: channelData.length,\n numberOfChannels,\n sampleRate,\n segmentDurationMs,\n durationMs: result.durationMs,\n dataPoints: result.dataPoints,\n amplitudeRange: result.amplitudeRange,\n rmsRange: result.rmsRange,\n }\n })\n } catch (error) {\n console.error('[Worker] Error', {\n message: error.message,\n stack: error.stack\n });\n \n self.postMessage({ \n error: {\n message: error.message,\n stack: error.stack,\n name: error.name\n }\n });\n }\n}\n";
2
2
  //# sourceMappingURL=InlineFeaturesExtractor.web.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"InlineFeaturesExtractor.web.d.ts","sourceRoot":"","sources":["../../src/workers/InlineFeaturesExtractor.web.tsx"],"names":[],"mappings":"AACA,eAAO,MAAM,uBAAuB,om6BA80BnC,CAAA"}
1
+ {"version":3,"file":"InlineFeaturesExtractor.web.d.ts","sourceRoot":"","sources":["../../src/workers/InlineFeaturesExtractor.web.tsx"],"names":[],"mappings":"AACA,eAAO,MAAM,uBAAuB,4u5BA+0BnC,CAAA"}