fix this script ''' import { useCallback, useRef, useState } from 'react';
import { AudioConfig } from '../types';

const DEFAULT_AUDIO_CONFIG: AudioConfig = {
  echoCancellation: true,
  noiseSuppression: true,
  sampleRate: 44100,
};

function writeString(s, a, offset) {
  for (let i = 0; i < s.length; ++i) {
    a[offset + i] = s.charCodeAt(i);
  }
}

function writeInt16(n, a, offset) {
  n = Math.floor(n);

  const b1 = n & 255;
  const b2 = (n >> 8) & 255;

  a[offset + 0] = b1;
  a[offset + 1] = b2;
}

function writeInt32(n, a, offset) {
  n = Math.floor(n);
  const b1 = n & 255;
  const b2 = (n >> 8) & 255;
  const b3 = (n >> 16) & 255;
  const b4 = (n >> 24) & 255;

  a[offset + 0] = b1;
  a[offset + 1] = b2;
  a[offset + 2] = b3;
  a[offset + 3] = b4;
}

// Return the bits of the float as a 32-bit integer value.  This
// produces the raw bits; no intepretation of the value is done.
function floatBits(f) {
  const buf = new ArrayBuffer(4);
  new Float32Array(buf)[0] = f;
  const bits = new Uint32Array(buf)[0];
  // Return as a signed integer.
  return bits | 0;
}

function writeAudioBuffer(audioBuffer, a, offset, asFloat) {
  // let n = audioBuffer.length;
  const n = audioBuffer.reduce((a, b) => a + b.length, 0);
  // let channels = audioBuffer.numberOfChannels;
  const channels = audioBuffer.length;

  for (let i = 0; i < n; ++i) {
    for (let k = 0; k < channels; ++k) {
      // let buffer = audioBuffer.getChannelData(k);
      const buffer = audioBuffer[k];
      if (asFloat) {
        const sample = floatBits(buffer[i]);
        writeInt32(sample, a, offset);
        offset += 4;
      } else {
        let sample = buffer[i] * 32768.0;

        // Clip samples to the limitations of 16-bit.
        // If we don't do this then we'll get nasty wrap-around distortion.
        if (sample < -32768) sample = -32768;
        if (sample > 32767) sample = 32767;

        writeInt16(sample, a, offset);
        offset += 2;
      }
    }
  }
}

// See http://soundfile.sapp.org/doc/WaveFormat/ and
// http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
// for a quick introduction to the WAVE PCM format.
function createWaveFileData(audioBuffer:any, asFloat:any, sampleRate:any) {
  const bytesPerSample = asFloat ? 4 : 2;
  const frameLength = audioBuffer[0].length; //audioBuffer.length;
  const numberOfChannels = audioBuffer.length; // audioBuffer.numberOfChannels;
  // let sampleRate = audioBuffer.sampleRate;
  const bitsPerSample = 8 * bytesPerSample;
  const byteRate = (sampleRate * numberOfChannels * bitsPerSample) / 8;
  const blockAlign = (numberOfChannels * bitsPerSample) / 8;
  const wavDataByteLength = frameLength * numberOfChannels * bytesPerSample;
  const headerByteLength = 44;
  const totalLength = headerByteLength + wavDataByteLength;
  const waveFileData = new Uint8Array(totalLength);
  const subChunk1Size = 16; // for linear PCM
  const subChunk2Size = wavDataByteLength;
  const chunkSize = 4 + (8 + subChunk1Size) + (8 + subChunk2Size);
  writeString('RIFF', waveFileData, 0);
  writeInt32(chunkSize, waveFileData, 4);
  writeString('WAVE', waveFileData, 8);
  writeString('fmt ', waveFileData, 12);
  writeInt32(subChunk1Size, waveFileData, 16); // SubChunk1Size (4)
  // The format tag value is 1 for integer PCM data and 3 for IEEE
  // float data.
  writeInt16(asFloat ? 3 : 1, waveFileData, 20); // AudioFormat (2)
  writeInt16(numberOfChannels, waveFileData, 22); // NumChannels (2)
  writeInt32(sampleRate, waveFileData, 24); // SampleRate (4)
  writeInt32(byteRate, waveFileData, 28); // ByteRate (4)
  writeInt16(blockAlign, waveFileData, 32); // BlockAlign (2)
  writeInt32(bitsPerSample, waveFileData, 34); // BitsPerSample (4)
  writeString('data', waveFileData, 36);
  writeInt32(subChunk2Size, waveFileData, 40); // SubChunk2Size (4)
  // Write actual audio data starting at offset 44.
  writeAudioBuffer(audioBuffer, waveFileData, 44, asFloat);

  return waveFileData;
}

function createAudioData(audioBuffer:any, asFloat:any, sampleRate:any) {
  return createWaveFileData(audioBuffer, asFloat, sampleRate);
}

// Save the given |audioBuffer| to a WAV file using the name given by
// |filename|.  This is intended to be run from a browser.  The
// developer is expected to use the console to run downloadAudioBuffer
// when necessary to create a new reference file for a test.  If
// |asFloat| is given and is true, the WAV file produced uses 32-bit
// float format (full WebAudio resolution).  Otherwise a 16-bit PCM
// WAV file is produced.
function downloadAudioBuffer(
  audioBuffer:any,
  /* filename, */ asFloat,
  sampleRate:any
) {
  console.log(audioBuffer, asFloat, sampleRate);
  const wavData = createAudioData(
    audioBuffer,
    /* filename, */ asFloat,
    sampleRate
  );
  const blob = new Blob([wavData], { type: 'audio/wav' });
  return blob;
}

function audioInputToWav(audioInput:any, asFloat = false) {
  // TODO handle possible audio inputs
  let mediaElement,
    mediaStream,
    mediaStreamTrack,
    blob,
    file,
    blobURL,
    mediaFragmentURI,
    url,
    audioBuffer,
    array,
    typedArray;
  switch (Object.getPrototypeOf(audioInput).constructor.name) {
    case 'AudioBuffer':
      console.log(audioInput);
    case 'HTMLAudioElement':
    case 'HTMLVideoElement':
      console.log(audioInput);
      break;
    case 'MediaStream':
      console.log(audioInput);
      break;
    case 'MediaStreamTrack':
      console.log(audioInput);
      break;
    case 'Blob':
    case 'File':
      console.log(audioInput);
      break;
    case 'String':
      console.log(audioInput);
      break;
    case 'Array':
      console.log(audioInput);
      break;
    case 'Float32Array':
      console.log(audioInput);
      break;
    case 'ArrayBuffer':
      console.log(audioInput);
      break;
    case 'Uint8Array':
      console.log(audioInput);
      break;
    case 'Uint16Array':
      console.log(audioInput);
      break;
    default:
      break;
  }
}

export function useAudioRecorder(onAudioChunk: (blob: Blob) => Promise<void>) {
  const [isRecording, setIsRecording] = useState(false);
  const mediaRecorderRef = useRef<MediaRecorder | null>(null);
  const streamRef = useRef<MediaStream | null>(null);

  
  const startRecording = useCallback(async () => {
    try {
      const stream = await navigator.mediaDevices.getDisplayMedia({
        video: true,
        audio: DEFAULT_AUDIO_CONFIG,
      });

      const audioTrack = stream.getAudioTracks()[0];
      if (!audioTrack) {
        throw new Error('No audio track found in the shared content');
      }

      const audioStream = new MediaStream([audioTrack]);
      streamRef.current = stream;
      
      const mediaRecorder = new MediaRecorder(audioStream, {
        mimeType: 'audio/webm',
      });
      
      mediaRecorderRef.current = mediaRecorder;

      mediaRecorder.ondataavailable = async (e) => {
        if (e.data.size > 0) {
          const blobb = downloadAudioBuffer(e.data, false, 44100);
          await onAudioChunk(blobb);
        }
      };

      mediaRecorder.start(3000);
      setIsRecording(true);
    } catch (error) {
      console.error('Error starting recording:', error);
      throw new Error('Failed to start recording');
    }
  }, []);

  const stopRecording = useCallback(() => {
    if (mediaRecorderRef.current && isRecording) {
      mediaRecorderRef.current.stop();
      if (streamRef.current) {
        streamRef.current.getTracks().forEach(track => track.stop());
      }
      setIsRecording(false);
    }
  }, [isRecording]);

  return {
    isRecording,
    startRecording,
    stopRecording,
  };
}''' i got this error in   const frameLength = audioBuffer[0].length; //audioBuffer.length; ''useAudioRecorder.ts:83 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'length')''