Tuesday, July 23, 2024

Mic and Camera Test Online tool script

 

Mic and Camera Testing

Online tool script for Mic Test and Camera Test

It is feasible to write code in JavaScript, HTML, and CSS to test a computer or laptop's microphone and camera. We can use the WebRTC API, which provides powerful tools for accessing media devices (like cameras and microphones) in modern web browsers. Before we even dive into further exploring the solution, there are some important consideration to be noted here.

Important Considerations

  1. Ensure Styles Don't Conflict: Make sure the CSS styles for the mic and camera test are scoped properly (e.g., using IDs) to avoid any conflict with your website or blog's existing styles.
  2. Check Browser Compatibility: Ensure your users are using modern browsers that support the WebRTC API.
  3. User Permissions: Users will need to grant permission for the browser to access their camera and microphone.
While thinking on primary functionality, we also give a thought to provide some advanced options for users to choose specific microphones and cameras. This way, the user interface can list available media devices and allow the users to select the desired camera and microphone. 

Below script we can say, it is simple, but a sort of enhanced version that includes device selection options. Additionally, it's a good idea to provide users with the option to stop the mic testing or camera testing. Hence, to make the UI more user interactive, we can add a "Stop Test" button that stops the media stream and any ongoing audio visualization.

So, let's go through below code components segregated in HTML, JavaScript and CSS for Mic and Camera Test.

HTML


<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Mic and Camera Test</title>

    <link rel="stylesheet" href="styles.css">

</head>

<body>

    <div id="mic-camera-test">

        <h1>Mic and Camera Test</h1>

        <div class="device-selection">

            <label for="audioSource">Select Microphone:</label>

            <select id="audioSource"></select>

        </div>

        <div class="device-selection">

            <label for="videoSource">Select Camera:</label>

            <select id="videoSource"></select>

        </div>

        <button id="startButton">Start Test</button>

        <button id="stopButton" disabled>Stop Test</button>

        <video id="video" width="640" height="480" autoplay></video>

        <div id="micTest">

            <p>Speak into the microphone...</p>

            <canvas id="canvas" width="640" height="100"></canvas>

        </div>

    </div>

    <div id="instructions">

        <h2>Instructions:</h2>

        <ol>

            <li>Select your preferred microphone from the "Select Microphone" dropdown.</li>

            <li>Select your preferred camera from the "Select Camera" dropdown.</li>

            <li>Click the "Start Test" button to begin testing.</li>

            <li>To stop the test, click the "Stop Test" button.</li>

        </ol>

    </div>

    <script src="script.js"></script>

</body>

</html> 


CSS (styles.css)


body {

    font-family: Arial, sans-serif;

    background-color: #1560BD; /* Denim blue background */

    color: #FFFFFF; /* White font color for contrast */

    text-align: center;

    margin: 0;

    padding: 0;

} 

#mic-camera-test {

    padding: 20px;

} 

.device-selection {

    margin-bottom: 15px;

} 

label {

    margin-right: 10px;

} 

video {

    margin-top: 20px;

    border: 1px solid black;

} 

#micTest {

    margin-top: 20px;

} 

canvas {

    border: 1px solid black;

} 

button {

    margin: 10px;

    padding: 10px 20px;

    border: none;

    background-color: #FFFFFF; /* White background for buttons */

    color: #1560BD; /* Denim blue font color for buttons */

    font-size: 16px;

    cursor: pointer;

} 

button:disabled {

    background-color: #CCCCCC;

    cursor: not-allowed;

} 

#instructions {

    margin-top: 30px;

    text-align: left;

    padding: 20px;

    background-color: #1E90FF; /* Dodger blue background for instructions */

    color: #FFFFFF;

    border-radius: 5px;

    width: 80%;

    margin-left: auto;

    margin-right: auto;

} 


JavaScript (script.js)


const startButton = document.getElementById('startButton');

const stopButton = document.getElementById('stopButton');

const video = document.getElementById('video');

const canvas = document.getElementById('canvas');

const canvasContext = canvas.getContext('2d');

const audioSelect = document.getElementById('audioSource');

const videoSelect = document.getElementById('videoSource');

let stream = null;

let drawAnimationFrame = null; 

async function getDevices() {

    const devices = await navigator.mediaDevices.enumerateDevices();

    const audioDevices = devices.filter(device => device.kind === 'audioinput');

    const videoDevices = devices.filter(device => device.kind === 'videoinput'); 

    audioDevices.forEach(device => {

        const option = document.createElement('option');

        option.value = device.deviceId;

        option.text = device.label || `Microphone ${audioSelect.length + 1}`;

        audioSelect.appendChild(option);

    });

 

    videoDevices.forEach(device => {

        const option = document.createElement('option');

        option.value = device.deviceId;

        option.text = device.label || `Camera ${videoSelect.length + 1}`;

        videoSelect.appendChild(option);

    });

} 

getDevices(); 

startButton.addEventListener('click', async () => {

    const audioSource = audioSelect.value;

    const videoSource = videoSelect.value;

    const constraints = {

        audio: { deviceId: audioSource ? { exact: audioSource } : undefined },

        video: { deviceId: videoSource ? { exact: videoSource } : undefined }

    }; 

    try {

        stream = await navigator.mediaDevices.getUserMedia(constraints);

        video.srcObject = stream; 

        const audioContext = new (window.AudioContext || window.webkitAudioContext)();

        const audioSourceNode = audioContext.createMediaStreamSource(stream);

        const analyser = audioContext.createAnalyser();

        audioSourceNode.connect(analyser); 

        analyser.fftSize = 256;

        const bufferLength = analyser.frequencyBinCount;

        const dataArray = new Uint8Array(bufferLength); 

        const draw = () => {

            drawAnimationFrame = requestAnimationFrame(draw); 

            analyser.getByteFrequencyData(dataArray); 

            canvasContext.fillStyle = 'rgb(0, 0, 0)';

            canvasContext.fillRect(0, 0, canvas.width, canvas.height);

 

            const barWidth = (canvas.width / bufferLength) * 2.5;

            let barHeight;

            let x = 0; 

            for (let i = 0; i < bufferLength; i++) {

                barHeight = dataArray[i];

 

                canvasContext.fillStyle = 'rgb(' + (barHeight + 100) + ',50,50)';

                canvasContext.fillRect(x, canvas.height - barHeight / 2, barWidth, barHeight / 2); 

                x += barWidth + 1;

            }

        }; 

        draw(); 

        startButton.disabled = true;

        stopButton.disabled = false;

    } catch (error) {

        console.error('Error accessing media devices.', error);

    }

}); 

stopButton.addEventListener('click', () => {

    if (stream) {

        stream.getTracks().forEach(track => track.stop());

        video.srcObject = null;

        cancelAnimationFrame(drawAnimationFrame); 

        canvasContext.clearRect(0, 0, canvas.width, canvas.height); 

        startButton.disabled = false;

        stopButton.disabled = true;

    }

}); 

 

Above sample code solution can be explained step wise as follows:

HTML Section

The HTML part of the code defines the structure of the web page and its elements.

  1. Mic and Camera Test Section:

    • <div id="mic-camera-test">: This is a container for the entire mic and camera test tool.
    • <h1>Mic and Camera Test</h1>: A heading for the tool.
    • Microphone Selection:
      • <div class="device-selection">: Container for microphone selection.
      • <label for="audioSource">Select Microphone:</label>: Label for microphone selection dropdown.
      • <select id="audioSource"></select>: Dropdown menu for selecting a microphone.
    • Camera Selection:
      • <div class="device-selection">: Container for camera selection.
      • <label for="videoSource">Select Camera:</label>: Label for camera selection dropdown.
      • <select id="videoSource"></select>: Dropdown menu for selecting a camera.
    • Start and Stop Buttons:
      • <button id="startButton">Start Test</button>: Button to start the test.
      • <button id="stopButton" disabled>Stop Test</button>: Button to stop the test (initially disabled).
    • Video Display:
      • <video id="video" width="640" height="480" autoplay></video>: Video element to display camera feed.
    • Microphone Test:
      • <div id="micTest">: Container for microphone test visualization.
      • <p>Speak into the microphone...</p>: Instruction for microphone test.
      • <canvas id="canvas" width="640" height="100"></canvas>: Canvas element to visualize microphone input.
  2. Instructions Section:

    • <div id="instructions">: Container for instructions.
    • <h2>Instructions:</h2>: Heading for instructions.
    • <ol>: Ordered list for step-by-step instructions.

CSS Section

The CSS part of the code styles the HTML elements.

  1. Body:

    • font-family: Arial, sans-serif;: Sets the font family.
    • background-color: #1560BD;: Sets the background color to denim blue.
    • color: #FFFFFF;: Sets the text color to white.
    • text-align: center;: Centers the text.
    • margin: 0; padding: 0;: Removes default margin and padding.
  2. Mic and Camera Test Section:

    • #mic-camera-test: Styles the mic and camera test container with padding.
    • .device-selection: Adds margin below each device selection container.
    • label: Adds margin to the right of each label.
    • video: Adds margin and a border to the video element.
    • #micTest: Adds margin to the microphone test container.
    • canvas: Adds a border to the canvas element.
    • button: Styles the buttons with margin, padding, no border, white background, denim blue text color, font size, and cursor pointer.
    • button:disabled: Styles disabled buttons with a gray background and no pointer cursor.
  3. Instructions Section:

    • #instructions: Styles the instructions container with margin, text alignment, padding, background color (dodger blue), text color, border radius, and width.

JavaScript Section

The JavaScript part of the code handles the functionality of the tool.

  1. Variable Declarations:

    • startButton, stopButton, video, canvas, canvasContext, audioSelect, videoSelect: Selects the HTML elements by their IDs.
    • stream: Variable to store the media stream.
    • drawAnimationFrame: Variable to store the animation frame ID for drawing on the canvas.
  2. Get Devices Function:

    • async function getDevices(): Asynchronous function to get available audio and video devices.
    • const devices = await navigator.mediaDevices.enumerateDevices();: Fetches the list of all connected media devices.
    • const audioDevices = devices.filter(device => device.kind === 'audioinput');: Filters the audio input devices (microphones).
    • const videoDevices = devices.filter(device => device.kind === 'videoinput');: Filters the video input devices (cameras).
    • audioDevices.forEach(device => {...});: Loops through each audio device and adds it to the microphone dropdown.
    • videoDevices.forEach(device => {...});: Loops through each video device and adds it to the camera dropdown.
  3. Event Listener for Start Button:

    • startButton.addEventListener('click', async () => {...});: Adds a click event listener to the start button.
    • const audioSource = audioSelect.value;: Gets the selected audio source.
    • const videoSource = videoSelect.value;: Gets the selected video source.
    • const constraints = {...};: Defines the constraints for media stream with the selected devices.
    • stream = await navigator.mediaDevices.getUserMedia(constraints);: Requests access to the media devices with the specified constraints.
    • video.srcObject = stream;: Sets the video element's source to the media stream.
    • Audio Visualization:
      • const audioContext = new (window.AudioContext || window.webkitAudioContext)();: Creates a new audio context.
      • const audioSourceNode = audioContext.createMediaStreamSource(stream);: Creates an audio source node from the media stream.
      • const analyser = audioContext.createAnalyser();: Creates an analyser node.
      • audioSourceNode.connect(analyser);: Connects the audio source node to the analyser.
      • analyser.fftSize = 256;: Sets the FFT size for the analyser.
      • const bufferLength = analyser.frequencyBinCount;: Gets the frequency bin count from the analyser.
      • const dataArray = new Uint8Array(bufferLength);: Creates a data array to hold the frequency data.
      • const draw = () => {...};: Function to draw the audio visualization on the canvas.
      • draw();: Calls the draw function.
    • startButton.disabled = true;: Disables the start button.
    • stopButton.disabled = false;: Enables the stop button.
  4. Event Listener for Stop Button:

    • stopButton.addEventListener('click', () => {...});: Adds a click event listener to the stop button.
    • if (stream) {...}: Checks if there is an active media stream.
    • stream.getTracks().forEach(track => track.stop());: Stops all tracks in the media stream.
    • video.srcObject = null;: Sets the video element's source to null.
    • cancelAnimationFrame(drawAnimationFrame);: Cancels the animation frame for the canvas drawing.
    • canvasContext.clearRect(0, 0, canvas.width, canvas.height);: Clears the canvas.
    • startButton.disabled = false;: Enables the start button.
    • stopButton.disabled = true;: Disables the stop button.

This code provides a complete tool for testing a user's microphone and camera, with options to select different devices, start and stop the test, and visualize the microphone input on a canvas.

This version of the script can be enhanced to include microphone and camera selections on separate lines and improved styling with a professional color background, and clear user instructions displayed below the tool.

2 comments:

  1. I have learned many things from this article which are very important. Thanks for telling me these things.

    ReplyDelete
  2. I have learned many things from this article which are very

    important. Thanks for telling me these things.
    mictesters

    ReplyDelete

Popular Posts