Distinguishing between a video or image when uploading files in JavaScript

I've been researching whether JavaScript can determine if a file is a video or an image. However, most of the information I found only shows how to accept these types using the input tag.

What I really need is for JS to identify the file type and then display the file URL in either an image or video HTML tag.

Currently, when a user uploads a file, I am using the following file upload input:

<input accept="image/*,video/*" multiple="multiple"  onchange='openFile(event)' style="display: none" type="file" id="selectedFile" />

Instead of having the user manually select whether it's a video or image, I want the browser to detect the file type and assign the file source to the respective element automatically.

My current code generates a data:url for the uploaded image or video file, which is then sent through a socket to be displayed to other users on the site:


var openFile = function(file) {
    var input = file.target;
    var reader = new FileReader();
    reader.onload = function() {
        try {
            var file = reader.result;

            Toast.fire({
                title: 'Uploading your File...',
                text: " ",
                didOpen: () => {
                    Swal.showLoading()
                },
            })

socket.emit('message', `

//
//
// However how can it differentiate which tag to use and use the uploaded data URL??
//
//

<video controls autoplay="1" alt="Video Uploaded" style="cursor: zoom-in; border-radius: 4px; width: 16rem" src="${file}">

<img alt="Image Uploaded" style="cursor: zoom-in; border-radius: 4px; width: 16rem" src="${file}">
`);
        }
        catch (err) {

        }
    };
    reader.readAsDataURL(input.files[0]);
};

*I'm not using a blob for the file as it will not show for other users when sent through the socket. I also would rather use on file input button as I'm trying to keep things as simple for the user as possible.

TL;DR:

  1. User clicks a "Upload file" button
  2. User can upload either video or image files from the same input button
  3. JS create a dataURL link and finds the file format
  4. JS assigns which attribute tag ( or ) the file will display in
  5. Sends through socket for others to see

If anyone can provide assistance, it would be greatly appreciated! Thanks.

Answer №1

When you access the reader.result, you can extract the MIME type of the file, allowing you to determine if it's an image, a video, or something else:

var openFile = function(file) {
    var input = file.target;
    var reader = new FileReader();
    reader.onload = function() {
        try {
            var file = reader.result;

            Toast.fire({
                title: 'Uploading your File...',
                text: " ",
                didOpen: () => {
                    Swal.showLoading()
                },
            })
var match = reader.result.match(/^data:([^/]+)\/([^;]+);/) || [];
var type = match[1];
var format = match[2];
if (type == "video")
{
  socket.emit('message', `
<video controls autoplay="1" alt="Video Uploaded" style="cursor: zoom-in; border-radius: 4px; width: 16rem" src="${file}">
`);
}
else if (type == "image")
{
  socket.emit('message', `
<img alt="Image Uploaded" style="cursor: zoom-in; border-radius: 4px; width: 16rem" src="${file}">
`);
}
        }
        catch (err) {

        }
    };
    reader.readAsDataURL(input.files[0]);
};

Furthermore, you have the option to fine-tune this process by filtering based on the format (which represents the type of image/video rather than a traditional file extension, e.g., .mov = quicktime).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

JavaScript function to toggle the visibility of navigation with a click of a button

I'm attempting to create a functionality in my code where the Open navigation button hides when the side navigation opens upon clicking. The desired behavior is for the openNav button to be hidden when it's clicked and then shown again when close ...

Show the Select component in a grid format with a list view, displaying three items per row

Within my react Dropdown component, there is currently a list view displayed when an item is selected. However, I am looking to modify it so that the items are arranged in a grid format with 3 items per row. Sample Code: import { Dropdown } from 'pri ...

Removing the day name from an input date in React without relying on Moment.js

I have successfully implemented code to validate dates, but I am unsure how to retrieve the name of the day for a given date input in the field. For instance: if the date input is 12/01/1994, it should display "Wednesday". function isValidDate(inputDate) ...

"Creating a HTML Table with Merged Cells using colspan and rowspan

Creating an HTML table with a unique layout is my latest project. I envision it to look like this: +-------+---+ | | | +-------+ + | | | +-----+-----+ | | | +-----+-----+ To achieve this, I'm utilizing a colgroup to split t ...

Using VueLoaderPlugin() results in an 'undefined error for 'findIndex' function

Currently, I am in the process of integrating a Vue CLI app into another web project that we are actively developing. The Vue app functions without any issues when utilizing the development server bundled with Vue CLI. Due to the presence of .vue files wi ...

Sliding Toggle: Panel Revealed with Button Slide

Currently, I am working on implementing a jquery slide tab feature. The functionality is working fine on button click. However, I want the button to stick with the panel and slide along with it. At the moment, the button remains fixed while the panel slide ...

JavaScript Plugins for Cordova

The more I delve into the inner workings of Cordova, the clearer it becomes to me. Yet, one area that continues to perplex me is the structure of JavaScript plugins. Typically, I write my JavaScript code as follows, adhering to what I believe is the stand ...

Fabric JS i-text cursor malfunctioning when loading JSON data

When I initially create a fabricjs i-text object in a new window, the cursor works perfectly. However, upon loading a saved JSON file, the cursor no longer functions as expected. I am utilizing the league_gothic font. Please refer to the image below showi ...

Creating the CSS styles for input fields

Here is an example of a form: <form class="mystyle" ...> <input name="test1" type="text"> <input name="test2" type="text"> ... </form> I want to apply CSS styling to all the input elements in this form: .mystyle input[type="text" ...

What is the best way to position two text fields next to each other on a webpage?

As I design a form for a landing page, my goal is to arrange the text input fields side by side in order to avoid making the form too lengthy. I am striving to achieve a layout similar to this: https://i.sstatic.net/PTCr4.png However, the task seems quit ...

Issues encountered while attempting to convert HTML Image and Canvas Tags to PDF within Angular 2

I am currently facing an issue with my code. My requirement is to download HTML content as a PDF file. I have been successful in downloading text elements like the <p> tag, but I am encountering difficulties when trying to download images and canvas ...

Issue with transmitting Razor form data to API controller using fetch or AJAX

I have created a basic razor web project and defined it as follows: in program.cs I added builder.Services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN"); In the controller, this is what I did: [Route("/api/[controller]")] [ApiCon ...

What is the best way to display a message on the 403 client side when an email sending fails?

I am attempting to display an alert message when the email is sent successfully or if it fails. If it fails, I receive a 403 status code from the backend. However, I am unsure how to handle this error on the client-side. In the case of success, I receive a ...

How can I change "Thu Sep 19 14:24:59 UTC 2019" into a moment date?

Struggling to convert this date: created_at= "Thu Sep 19 14:24:59 UTC 2019" I attempted to use the following code: let elementDate=moment(created_at) However, I keep receiving an error message: moment.invalid(/* Fri Aug 30 09:52:04 UTC 2019 */) I als ...

Experiencing difficulties with transferring a variable within a Jquery function

I need help with this function function procData(a) { $('#loading' + a).show(); $.post("ajax.php?talk=" + a, { slot: $('#slot' + a).val() }, function (response) { $('#talkdesc' + a).fadeOut(); ...

Determine the status of a checkbox in Protractor with JavaScript: Checked or Unchecked?

I'm currently facing a challenge while writing an end-to-end Protractor test. I need to verify whether a checkbox is enabled or not, but it doesn't have a 'checked' property. Is there a way in JavaScript to iterate through a list, check ...

Next.js does not support Video.js functionality when using server side rendering

I'm struggling to set up video.js in my next.js project and encountering issues. When the player is loading, it initially appears black and then disappears abruptly. A warning message in the console reads: "video.es.js?31bb:228 VIDEOJS: WARN: T ...

How should the directory be organized for the param with a prefix in Nuxt.js?

My route is set up as /en/rent-:productSlug How should I organize the directory for this route, considering that the parameter productSlug includes the prefix rent? ...

What methods are available to gradually increase a counter until it reaches a specific number by a designated date?

I have a unique idea for my website - I want to create a special counter that gradually increases to a specific number, but does so over the course of an entire year. Imagine starting at 0 and aiming to reach 35340340 after exactly one year has passed. It ...

How can we integrate Cordova plugins into Vue-Cordova framework?

Looking to integrate Vue-Cordova with Cordova-plugin-file-opener2 to open PDF files within iOS/Android applications. In the Vue-Cordova setup, plugins related to the device are defined on the data property of the App vue instance: data: function () { ...