update this code to add js library to handle audio chunks . ""import { useCallback, useRef, useState } from 'react';

interface AudioConfig {
  echoCancellation: boolean;
  noiseSuppression: boolean;
  sampleRate: number;
}

const DEFAULT_AUDIO_CONFIG: AudioConfig = {
  echoCancellation: true,
  noiseSuppression: true,
  sampleRate: 16000, // Whisper works best with 16kHz sample rate
};

// Helper function to ensure audio format compatibility
const getSupportedMimeType = () => {
  const types = [
    'audio/webm',
    'audio/webm;codecs=opus',
    'audio/ogg;codecs=opus',
  ];
  return types.find(type => MediaRecorder.isTypeSupported(type)) || 'audio/webm';
};

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 chunksRef = useRef<Blob[]>([]);

  const startRecording = useCallback(async () => {
    
    try {
      const stream = await navigator.mediaDevices.getDisplayMedia({
        video: true,
        audio: {
          ...DEFAULT_AUDIO_CONFIG,
          channelCount: 1, // Mono audio (preferred by Whisper)
        },
      });

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

      // Create audio context to handle sample rate conversion if needed
      const audioContext = new AudioContext({
        sampleRate: DEFAULT_AUDIO_CONFIG.sampleRate,
      });
      
      // Create media stream source
      const sourceNode = audioContext.createMediaStreamSource(new MediaStream([audioTrack]));
      
      // Create script processor for potential sample rate conversion
      const processor = audioContext.createScriptProcessor(4096, 1, 1);
      
      // Connect the nodes
      sourceNode.connect(processor);
      processor.connect(audioContext.destination);

      // Create a new stream with the processed audio
      const audioStream = new MediaStream([audioTrack]);
      streamRef.current = stream;

      // Clear previous chunks
      chunksRef.current = [];

      const mediaRecorder = new MediaRecorder(audioStream, {
        mimeType: getSupportedMimeType(),
      });

      mediaRecorderRef.current = mediaRecorder;
      let i=0;
      mediaRecorder.ondataavailable = async (e) => {
        if (e.data.size > 0) {
          chunksRef.current.push(e.data);
          try {
          const blobUrl = URL.createObjectURL(e.data);
          const a = document.createElement('a');
          a.style.display = 'none';
          a.href = blobUrl;
          a.download = `audio_chunk_${i++}.webm`;
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          URL.revokeObjectURL(blobUrl);
            await onAudioChunk(e.data);
          } catch (error) {
            console.error('Error processing audio chunk:', error);
          }
        }
      };

      mediaRecorder.onerror = (event) => {
        console.error('MediaRecorder error:', event);
        stopRecording();
      };

      // Handle stream stop event
      stream.getTracks().forEach(track => {
        track.onended = () => {
          stopRecording();
        };
      });

      mediaRecorder.start(3000); // Create chunks every 3 seconds
      
      setIsRecording(true);

      // Cleanup function for audio context
      return () => {
        processor.disconnect();
        sourceNode.disconnect();
        audioContext.close();
      };
    } catch (error) {
      console.error('Error starting recording:', error);
      throw new Error('Failed to start recording');
    }
  }, [onAudioChunk]);

  // Function to get the complete recording
  const getCompleteRecording = useCallback(async (): Promise<Blob> => {
    if (chunksRef.current.length === 0) {
      throw new Error('No recording available');
    }
    return new Blob(chunksRef.current, { type: getSupportedMimeType() });
  }, []);

  const stopRecording = useCallback(async () => {
    if (mediaRecorderRef.current && isRecording) {
      try {
        // Request the final chunk
        mediaRecorderRef.current.requestData();
        
        // Stop the media recorder
        mediaRecorderRef.current.stop();
        
        // Stop all tracks in the stream
        if (streamRef.current) {
          streamRef.current.getTracks().forEach(track => track.stop());
          streamRef.current = null;
        }
        
        // Get the complete recording before clearing
        const finalRecording = await getCompleteRecording();
        
        // Reset the media recorder and chunks
        mediaRecorderRef.current = null;
        chunksRef.current = [];
        setIsRecording(false);

        return finalRecording;
      } catch (error) {
        console.error('Error stopping recording:', error);
        throw error;
      }
    }
  }, [isRecording, getCompleteRecording]);

  return {
    isRecording,
    startRecording,
    stopRecording,
    getCompleteRecording,
  };
}
""