|
1 | 1 | (() => { |
2 | 2 | const audioContextCtor = window.AudioContext || window.webkitAudioContext; |
| 3 | + const audibleAudioProbeTimeoutMs = 1500; |
| 4 | + const audibleAudioPollDelayMs = 100; |
3 | 5 | const harnessGlobalName = "__prompterOneRecordingFileHarness"; |
4 | 6 | const audioSampleWaitMs = 100; |
5 | 7 | const blobMimeFallback = "video/webm"; |
6 | 8 | const minimumAudibleFrequencyValue = 8; |
| 9 | + const minimumAudibleWaveDelta = 2; |
7 | 10 | const minimumVisibleChannelValue = 12; |
8 | 11 | const minimumVisiblePixelCount = 16; |
9 | 12 | const visibleVideoProbeTimeoutMs = 1500; |
|
71 | 74 |
|
72 | 75 | try { |
73 | 76 | await audioContext.resume().catch(() => {}); |
74 | | - await new Promise(resolve => window.setTimeout(resolve, audioSampleWaitMs)); |
| 77 | + const frequencySamples = new Uint8Array(analyser.frequencyBinCount); |
| 78 | + const waveformSamples = new Uint8Array(analyser.fftSize); |
| 79 | + const deadline = Date.now() + audibleAudioProbeTimeoutMs; |
| 80 | + |
| 81 | + while (Date.now() <= deadline) { |
| 82 | + await new Promise(resolve => window.setTimeout(resolve, audioSampleWaitMs)); |
75 | 83 |
|
76 | | - const samples = new Uint8Array(analyser.frequencyBinCount); |
77 | | - analyser.getByteFrequencyData(samples); |
78 | | - return samples.some(value => value >= minimumAudibleFrequencyValue); |
| 84 | + analyser.getByteFrequencyData(frequencySamples); |
| 85 | + if (frequencySamples.some(value => value >= minimumAudibleFrequencyValue)) { |
| 86 | + return true; |
| 87 | + } |
| 88 | + |
| 89 | + analyser.getByteTimeDomainData(waveformSamples); |
| 90 | + if (waveformSamples.some(value => Math.abs(value - 128) >= minimumAudibleWaveDelta)) { |
| 91 | + return true; |
| 92 | + } |
| 93 | + |
| 94 | + await new Promise(resolve => window.setTimeout(resolve, audibleAudioPollDelayMs)); |
| 95 | + } |
| 96 | + |
| 97 | + return false; |
79 | 98 | } |
80 | 99 | finally { |
81 | 100 | sourceNode.disconnect(); |
|
0 commit comments