Building a custom HTML and JavaScript player to showcase multiple videos on a webpage

UPDATE: The solution has been discovered, shared, and marked as the top answer below.

In the process of creating my portfolio website using HTML, CSS, and JS, I encountered a challenge regarding the addition of multiple videos on various pages.

While following tutorials to customize the video player, I realized that it only works for a single video on each page. To include additional videos, I would have to create a separate .js custom player file for each video and manually configure them on the website.

How can I extend this single .js custom video player to all my videos using only JavaScript?

I've come across similar discussions on this topic here, but they all rely on jQuery, making it difficult for me to adapt with pure JavaScript.

This is the HTML code for the video player:

<section class="videoplayer">
<div class="c-video">
    <div id="video_player">
        <video src="./media/portfolio/videos/Show-Reel-2021.mp4" id="main-video"></video>
        <div class="progressAreaTime">00:00</div>
        <div class="controls">
            <div class="progress-area">
                <div class="progress-bar">
                    <span></span>
                </div>
                <div class="buffered-progress-bar"></div>
            </div>
            <div class="controls-list">
                <div class="controls-left">
                    <span class="icon">
                        <i class="material-icons fast-rewind" title="Rewind 10 seconds">first_page</i>
                    </span>
                    <span class="icon">
                        <i class="material-icons play_pause" title="Play">play_arrow</i>
                    </span>
                    <span class="icon">
                        <i class="material-icons fast-forward" title="Fast forward 10 seconds">last_page</i>
                    </span>
                    <span class="icon">
                        <i class="material-icons volume" title="Mute">volume_up</i>
                        <input type="range" min="0" max="100" class="volume_range">
                    </span>
                    <div class="timer">
                        <span class="current">00:00</span> / <span class="duration">0:00</span>
                    </div>
                </div>
                <div class="controls-right">
                    <span class="icon">
                        <i class="material-icons auto-play" title="Auto-play is off"></i>
                    </span>
                    <span class="icon">
                        <i class="material-icons settingsBtn" title="Details">settings</i>
                    </span>
                    <span class="icon">
                        <i class="material-icons picture_in_picture" title="Miniplayer">picture_in_picture_alt</i>
                    </span>
                    <span class="icon">
                        <i class="material-icons fullscreen" title="Full screen">fullscreen</i>
                    </span>
                </div>
            </div>
        </div>
        <div id="settings">
            <div class="playback">
                <span>Playback Speed</span>
                <ul>
                    <li data-speed="0.25">0.25</li>
                    <li data-speed="0.5">0.5</li>
                    <li data-speed="0.75">0.75</li>
                    <li data-speed="1" class="active">Normal</li>
                    <li data-speed="1.25">1.25</li>
                    <li data-speed="1.5">1.5</li>
                    <li data-speed="1.75">1.75</li>
                    <li data-speed="2">2</li>
                </ul>
            </div>
        </div>
    </div>
</div>

And this is the JavaScript code for the video player:

// Select elements
const vidsrc = document.querySelector('#main-video').src;
const video_player = document.querySelector('#video_player'),
mainVideo = video_player.querySelector('#main-video'),
progressAreaTime = video_player.querySelector('.progressAreaTime'),
controls = video_player.querySelector('.controls'),
progressArea = video_player.querySelector('.progress-area'),
progress_Bar = video_player.querySelector('.progress-bar'),
buffered_Bar = video_player.querySelector('.buffered-progress-bar'),
fast_rewind = video_player.querySelector('.fast-rewind'),
play_pause = video_player.querySelector('.play_pause'),
fast_forward = video_player.querySelector('.fast-forward'),
volume = video_player.querySelector('.volume'),
volume_range = video_player.querySelector('.volume_range'),
current = video_player.querySelector('.current'),
totalDuration = video_player.querySelector('.duration'),
auto_play = video_player.querySelector('.auto-play'),
settingsBtn = video_player.querySelector('.settingsBtn'),
picture_in_picture = video_player.querySelector('.picture_in_picture'),
fullscreen = video_player.querySelector('.fullscreen'),
settings = video_player.querySelector('#settings'),
playback = video_player.querySelectorAll('.playback li');

(mainVideo.addEventListener('loadeddata',()=>{
    setInterval(() => {
        let bufferedTime = mainVideo.buffered.end(0);
        let duration = mainVideo.duration;
        let width = (bufferedTime / duration) * 100;
        buffered_Bar.style.width = `${width}%`
    }, 500);
})

// Other functions such as play, pause, rewind, etc., are then implemented similarly in this revised code snippet to streamline the video player's operation.

Answer №1

A helpful function that allows you to create the HTML structure once and then dynamically generate it for multiple instances

00:00
Playback Speed

You must also handle JavaScript properly and ensure unique IDs are used. Consider using classes instead of IDs like video-1, video-2, video-3, etc.

Key points to note:

  • sources: Array of video URLs to display
  • sources.map: Iterates through the array and generates HTML markup for each video source
  • videoPlayers: Array containing the HTML markup
  • container: Parent element where the generated HTML will be appended

Answer №2

I HAVE CRACKED THE CODE!

For all those who may encounter a similar challenge in the future, I successfully managed to find a solution by initially identifying and selecting each videoplayer div:

const videoContainers = document.querySelectorAll(".video-container")

Next, I utilized the .forEach() method to ensure that a button would be created for every single videoplayer individually:

videoContainers.forEach((container) => {
  let playPauseBtn = container.querySelector(".play-pause-btn");
  let theaterBtn = container.querySelector(".theater-btn");
  let fullScreenBtn = container.querySelector(".full-screen-btn");
...

// The complete code snippet for one videoplayer
}

You have the option to reference "container" for an individual videoplayer or "document" for all videoplayers collectively. It truly works like magic!

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

When using Axios to GET from a local PHP file, it only retrieves the code instead of running

I've run into an issue accessing the API as it has CORS disabled, requiring me to make requests on the server side. Currently, I'm using React and Axios to send a GET request to a local php file that should trigger cURL execution. However, instea ...

Trouble with ng-repeat when working with nested json data

Check out this app demo: http://jsfiddle.net/TR4WC/2/ I feel like I might be overlooking something. I had to loop twice to access the 2nd array. <li ng-repeat="order in orders"> <span ng-repeat="sales in order.sales> {{sales.sales ...

Utilize MetroUiCSS to effortlessly integrate a sleek calendar into your AngularJS application

I'm looking to incorporate a calendar from Metro Ui CSS into my project. Here is the link to the calendar: However, I am struggling with how to activate the calendar. I have already included all necessary scripts in my index.html (3 scripts) and have ...

Comparing the Calculation of CSS Selector Specificity: Class versus Elements [archived]

Closed. This question requires additional information for debugging purposes. It is not currently accepting answers. ...

What is the reasoning behind utilizing the "&" selector in CSS?

.navigation { position: fixed; top: 0; bottom: 0; left: 0; transform: translateX(-100%); transition: translation: all ease 0.25s; &.expand { transform: translateX(0); } } JavaScript file: $(document).ready(func ...

Encountering an issue in a Next.js application while building it, where an error is triggered because the property 'protocol' of 'window.location' cannot be destructured due to being undefined

While building my nextjs application, I encountered the following error. My setup uses typescript for building purposes, although I am only using JavaScript. Build error occurred: TypeError: Cannot destructure property 'protocol' of 'window ...

Tips for creating multiple diagonal lines with CSS and HTML

Is there a way to create multiple diagonal lines within a rectangle using CSS and HTML from the start? I am interested in incorporating diagonal lines at the onset of the rectangle. Here is an example code that displays the rectangle: <div className={ ...

What is the best way to remove an active item from a Vue v-list?

When using Vuetify's v-list-item directive, I encountered an issue where the active prop cannot be removed once an item has been selected. Here is my approach so far: <v-list-item-group pb-6 color="primary" class="pb-3 text-left"> ...

Looking to crop a canvas without changing its dimensions using jQuery

I'm currently working on a project that involves overlaying two images; one uploaded by the user and the other a default image. However, I am facing an issue when the uploaded image is a rectangle instead of a square, causing the canvas to resize it. ...

Select a single option from the group to include in the array

I'm currently developing a new soccer betting application. My goal is to allow users to choose the result of a match - whether it's a win, loss, or draw - and then save that selection in a list of chosen bets. https://i.stack.imgur.com/hO3uV.png ...

How can I change a PHP for loop to Javascript?

Can the following code be converted to JavaScript? for (let lift of liftDetails) { document.write('<option>'+ lift["LiftMakes"] +'</option>'); } ...

Update the observability status of one observable using a different observable

Upon running the following code, you'll notice that an xhr request is being sent to the console regardless of whether I am subscribed to the subject or not. I would prefer for these requests not to be made if I am not subscribed. // To start, install ...

Create a Rest API and implement server-side rendering concurrently using SailsJs

I am exploring the potential of utilizing the SailsJs framework for nodeJs in order to create an application. Initially, my plan was to construct a REST API in Sails and utilize AngularJs for managing the Front-End. This API would also be beneficial for o ...

Issues with webpage responsiveness, width not adjusting correctly

Just completed coding my website and now I'm facing a new challenge. I am focusing on making it responsive for tablet screens (768px) starting with the header section, but for some reason, the modifications I make in the responsive.css file are not ta ...

Webpack 4.1.1 -> The configuration.module contains a property 'loaders' that is unrecognized

After updating my webpack to version 4.1.1, I encountered an error when trying to run it: The configuration object is invalid. Webpack has been initialized with a configuration that does not match the API schema. - The 'loaders' property in ...

Updating Sencha list itemTpl on the fly

Is there a way to dynamically change the itemTpl in a Sencha list to adjust the visibility of a column based on certain conditions? Your assistance would be greatly appreciated. ...

Animating the left and right positioning of a single element using CSS transitions

I am currently working with the following CSS code: #masthead { transition: left linear 0.25s; -moz-transition: left linear 0.25s; -o-transition: left linear 0.25s; -webkit-transition: left linear 0.25s; -ms-transition: left linear 0.2 ...

Switch out the view div element with ui-router

Currently, I am utilizing Angular ui-router to manage various views in the following manner: <div ui-view="header"></div> <div ui-view="nav"></div> <div ui-view></div> Upon Angular loading, the divs are automatically p ...

What is the solution for incorporating multiple elements in knockout's applyBindingsToNode function?

I am currently using knockout applyBindingsToNode to dynamically add and remove elements in order to update my html. I need to cut the binding, which is why I am utilizing applyBindingsToNode. In an example I have provided, if you click on the button "Reb ...

The JSON creation response is not meeting the expected criteria

Hello, I'm currently working on generating JSON data and need assistance with the following code snippet: generateArray(array) { var map = {}; for(var i = 0; i < array.length; i++){ var obj = array[i]; var items = obj.items; ...