HTML5 audio clicking the progress bar to move to a different time - javascript

<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script>
$(document).ready(function(){
var counter = 0;
var numOfTracks = $(".audio-player").length;
$("#play-bt").click(function(){
$(".audio-player")[counter].play();
$("#message").text("Music started");
})
$("#pause-bt").click(function(){
$(".audio-player")[counter].pause();
$("#message").text("Music paused");
})
$("#stop-bt").click(function(){
$(".audio-player")[counter].pause();
$(".audio-player")[counter].currentTime = 0;
$("#message").text("Music Stopped");
})
$("#next-bt").click(function(){
$(".audio-player")[counter].pause();
$(".audio-player")[counter].currentTime = 0;
counter++;
if(counter > numOfTracks - 1){
counter = 0 ;
}
$(".audio-player")[counter].play();
$("#message").text("Next Track started");
})
$("#prev-bt").click(function(){
$(".audio-player")[counter].pause();
$(".audio-player")[counter].currentTime = 0;
counter--;
$(".audio-player")[counter].play();
$("#message").text("Previous Track");
})
$(".audio-player").bind('timeupdate', function(){
//Gets the whole duration of the track.
//No idea kung saan ko ilalagay sa UI**IMPLEMENT LATER**
var track_length = $(".audio-player")[counter].duration;
var secs = $(".audio-player")[counter].currentTime;
var progress = (secs/track_length) * 100;
$('#progressbar').css({'width' : progress * 2});
//Will Use these later on production
//NOTE DO NOT DELETE
//Track Minutes
var tcMins = parseInt(secs/60);
//Track Seconds
var tcSecs = parseInt(secs - (tcMins * 60));
if (tcSecs < 10) { tcSecs = '0' + tcSecs; }
// Display the time. REMEMBER
$('#timecode').html(tcMins + ':' + tcSecs);
})
})
</script>
<style>
/*Seperate this some time in the development*/
#playerContainer{
background-color: #A8A8A8 ;
width: 260px;
height: 55px;
padding: 8px;
border: 1px solid #d0d0d0;
}
/* Player Controls */
/*list items of controls */
#playerControls li {
display: block;
width: 32px;
height: 32px;
padding: 0px;
float: left;
cursor: pointer;
}
#playerControls { list-style: none; padding: 0px; margin: 0px;}
/*Images for each li items items */
#play-bt { background: url('icons/glyphicons_173_play.png'); background-repeat:no-repeat }
#pause-bt {background: url('icons/glyphicons_174_pause.png'); background-repeat:no-repeat;}
#next-bt { background: url('icons/glyphicons_176_forward.png'); background-repeat:no-repeat}
#prev-bt {background: url('icons/glyphicons_172_rewind.png'); background-repeat:no-repeat;}
/*Progress Stuff*/
/*Remember to manipulate its width via javascript later*/
#progressContainer
{
background-color:#e0e0e0;
height: 14px;
width: 256px;
float: left;
margin-left: 0px;
}
#progressbar {background-color: #1384bb; height:14px; width:0%; }
</style>
</head>
<body>
<audio class ="audio-player" name= "audio-player" src="04-zedd-stars_come_out_(terravita_remix).ogg" >
<p>Sorry your file doesn't support html5</p>
</audio>
<!--Second Track For Testing Purposes-->
<audio class ="audio-player" name= "audio-player" src="01-hard_rock_sofa-quasar.mp3" ></audio>
<div id="message"></div>
<div id = "playerContainer">
<ul id = "playerControls" >
<li id = "prev-bt"></li>
<li id= "play-bt"></li>
<li id= "pause-bt"></li>
<li id = "next-bt"></li>
<li id= "stop-bt" ></li>
<li><span id ="timecode"></span></li>
</ul>
<div id="progressContainer"><!-- Progess bars container //-->
<div id="progressbar"></div>
</div>
</div>
</div>
</body>
</html>
How can I click a certain part of my progress bar so that I can move it to a different time in the track? I have no idea on how I am going to do that. any ideas ?

Given some html that looks like this:
<div class="container">
<video class="video">
<source></source>
</video>
<progress min="0" max="100" value="0"></progress>
<div class="controls"></div>
</div>
In order to seek to a specific time in the video as a result of a click event the js would look like this:
var player = document.querySelector("video");
var progressBar = document.querySelector("progress");
progressBar.addEventListener("click", seek);
function seek(e) {
var percent = e.offsetX / this.offsetWidth;
player.currentTime = percent * player.duration;
progressBar.value = percent / 100;
}
However, this doesn't address how to seek on a click/drag (like most video players do). include script

I came across this question today because I am creating a custom HTML5 video player and had the same question. Just in regards to video instead of audio. The process should work the same though.
I found this article and was able to incorporate the progress bar part of it into my player. https://msdn.microsoft.com/en-us/library/ie/gg589528%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
Instead of using a progressbar element, like I was doing, or a div element, like you're doing, the trick here is to use a canvas element instead.
<canvas id='progress-bar' width="200" height="20" style="border:1px solid green;">canvas not supported</canvas>
Then in your JavaScript, create a handle to reference it by
var mediaPlayer;
var progressBar;
var canvas;
When the document loads, initialize everything including the progress bar items
mediaPlayer = document.getElementById('media-video');
progressBar = document.getElementById('progress-bar');
canvas = document.getElementById('progress-bar');
canvas.addEventListener("click", function(e) {
var canvas = document.getElementById('progress-bar');
if (!e) {
e = window.event;
} //get the latest windows event if it isn't set
try {
//calculate the current time based on position of mouse cursor in canvas box
mediaPlayer.currentTime = mediaPlayer.duration * (e.offsetX / canvas.clientWidth);
}
catch (err) {
// Fail silently but show in F12 developer tools console
if (window.console && console.error("Error:" + err));
}
}, true);
mediaPlayer.addEventListener('timeupdate', updateProgressBar, false);
Then create a function outside of your initialization function for the timeupdate listener to call and automatically update the progress bar for you
function updateProgressBar() {
mediaPlayer = document.getElementById('media-video');
//get current time in seconds
var elapsedTime = Math.round(mediaPlayer.currentTime);
//update the progress bar
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
//clear canvas before painting
ctx.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight);
ctx.fillStyle = "rgb(255,0,0)";
var fWidth = (elapsedTime / mediaPlayer.duration) * (canvas.clientWidth);
if (fWidth > 0) {
ctx.fillRect(0, 0, fWidth, canvas.clientHeight);
}
}
}
I haven't completely cleaned it up yet. Hence the redundant handles to the same id. But I'm sure you get the picture.

Hope this can save someone some time. If you're trying to set this up in an Angular app, you'll notice this is your controller context. So you'll need to use e.srcElement.clientWidth for this to work.
vm.setPosition = function(e){
var percent = ((e.offsetX / e.srcElement.clientWidth));
vm.songObject.setProgress(percent);
}

I wrote about that in Working with HTML5 multimedia components – Part 3: Custom controls, scroll down to "Adding a progress bar".

Related

Play multiple audio tracks sequentially, not simultaneously

I'm trying to use the <audio> tag, and I want to have as many tracks playing as I add. But now they play at the same time, can I somehow make them play sequentially?
<audio id="audio1" preload="" autoplay="" loop="" type="audio/mp3" src="music/mus1.mp3"></audio>
<audio id="audio2" preload="" autoplay="" loop="" type="audio/mp3" src="music/mus.mp3"></audio>
<div id="pp" style="cursor: pointer;" onclick="pVid();"><img src="img/heart.png"></div>
<script type="text/javascript">
function pVid() {
var audio1 = document.getElementById("audio1");
var audio2 = document.getElementById("audio2");
audio1.paused ? audio1.play() : audio1.pause();
audio2.paused ? audio2.play() : audio2.pause();
}
</script>
I found one solution, it works but not the way I want
var sounds = new Array(new Audio("music/mus1.mp3"), new Audio("music/mus.mp3"));
var i = -1;
pVid();
function pVid() {
i++;
if (i == sounds.length) return;
sounds[i].addEventListener('ended', pVid);
sounds[i].play();
}
Here everything just plays right away, but I want to be able to play the tracks myself through the button and pause at any time. This is done in the first version, but there all the tracks play at the same time
Use audio events as much as possible. We can use freesound.org for testing.
let sounds = new Array(new Audio("https://freesound.org/data/previews/46/46992_514283-lq.mp3"),
new Audio("https://freesound.org/data/previews/610/610823_13156161-lq.mp3"),
new Audio("https://freesound.org/data/previews/92/92005_1499847-lq.mp3"), new Audio("https://freesound.org/data/previews/46/46992_514283-lq.mp3"),
new Audio("https://freesound.org/data/previews/610/610823_13156161-lq.mp3"),
new Audio("https://freesound.org/data/previews/92/92005_1499847-lq.mp3"));
let current = random(0);
let paused = true;
// set event handlers on all audio objects
for (let s of sounds) {
s.addEventListener('ended', ended);
s.addEventListener('play', play);
s.addEventListener('pause', pause);
}
updateVolume()
// handle button click
function playPause() {
if (paused) {
sounds[current].play();
btn.innerText = 'pause';
paused = false;
} else {
sounds[current].pause();
btn.innerText = 'play';
paused = true;
}
}
function ended(e) {
document.getElementById(current + '').classList.remove('playing');
document.getElementById(current + '').classList.remove('paused');
/*i++;
if (i >= sounds.length) //loop
i = 0;
*/
current = random(current); // shuffle
paused = true;
playPause();
}
function play() {
document.getElementById(current + '').classList.add('playing');
document.getElementById(current + '').classList.remove('paused');
}
function pause() {
document.getElementById(current + '').classList.add('paused');
document.getElementById(current + '').classList.remove('playing');
}
function random(i) {
let next = i;
while (next == i)
next = Math.floor(Math.random() * sounds.length);
return next;
}
function updateVolume() {
for (let s of sounds) {
s.volume = volume.value;
}
}
#list {
margin-top: 1rem;
border: 1px solid gray;
width: 100px;
}
#controls {
position: fixed;
right: 2rem;
top: 1rem;
width: 50px;
}
#volume {
width: 150px;
height: 20px;
transform-origin: 75px 75px;
transform: rotate(-90deg) translateY(50%);
}
.playing {
background-color: lightblue;
}
.paused {
background-color: wheat;
}
<Button id=btn onClick='playPause()'>play</Button>
<div id=list>
<div id='0'>Guitar</div>
<div id='1'>Drum</div>
<div id='2'>Violin</div>
<div id='3'>Guitar</div>
<div id='4'>Drum</div>
<div id='5'>Violin</div>
</div>
<div id=controls>
<label for="volume">Volume</label><br>
<input id=volume type="range" id="volume" name="volume" min="0" max="1" step='.1' value='.5' onInput='updateVolume()'>
</div>
I don't know why no one mentioned the onended event
<audio id="aud1" onended="playaud2()" src="whatever.mp3"> <!--first audio-->
<audio id="aud2" src="whatever.mp3"> <!--second audio-->
<script>
//the onended event calls a function when the audio finishes playing
function playaud2() {
document.getElementById("aud2").play()}
</script>
As simple :)
Audio files
For testing, I used a few free sound-effects audio files from https://www.freesoundeffects.com.
To make it work in all browsers it is recommended by w3c to use the <audio>-tag with <source> tags.
Solution
I added some arbitrary sound files and buttons. The buttons will reset all the audios that are currently playing then play the sounds in the data-track attributes.
data-track syntax:
track-a // will play track a
track-a;track-b // will play track a followed by track b
track-a+track-b // will play track a and b simultaniously
track-a+track-b;track-c // as above but add track c to the end
You could do something like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
audio {
display: block;
}
</style>
<script defer type="application/javascript">
let activeTimeout;
function init(player) {
player.innerHTML = `play ${player.dataset.label}`;
player.addEventListener('click', clickHandler);
}
function reset(audio) {
clearTimeout(activeTimeout);
audio.pause();
audio.currentTime = 0;
}
function dequeue(tracks) {
console.log("Queue:", tracks);
if (tracks.length >= 1) {
const track = tracks.pop();
const multiTrack = track.split('+');
let maxDuration = 0;
multiTrack.forEach((it) => {
const audio = document.querySelector(`[data-audio="${it}"]`);
maxDuration = Math.max(maxDuration, audio.duration);
audio.play();
});
activeTimeout = setTimeout(() => {
dequeue(tracks);
}, maxDuration * 1000);
}
}
function clickHandler(e) {
const allAudios = document.querySelectorAll('[data-audio]');
const trackAttr = this.dataset.track;
const tracks = trackAttr.split(';');
if (tracks) {
allAudios.forEach(reset);
dequeue(tracks.reverse()); // reverse to make the pop-operations faster
} else {
console.log('No track defined!');
}
}
window.addEventListener('load', function() {
const players = document.querySelectorAll('[data-player]');
players.forEach((it) => init(it));
});
</script>
</head>
<body>
<audio data-audio="applause" controls="controls" preload="preload">
<source src="https://www.freesoundeffects.com/files/mp3_426807.mp3" type="audio/mp3"></source><!-- replace with your audio file -->
</audio>
<audio data-audio="bark" controls="controls" preload="preload">
<source src="https://www.freesoundeffects.com/files/mp3_89478.mp3" type="audio/mp3"></source><!-- replace with your audio file -->
</audio>
<audio data-audio="chirp" controls="controls" preload="preload">
<source src="https://www.freesoundeffects.com/files/mp3_89489.mp3" type="audio/mp3"></source><!-- replace with your audio file -->
</audio>
<button data-player data-label="bark!" data-track="bark" />
<button data-player data-label="chirp!" data-track="chirp" />
<button data-player data-label="applause!" data-track="applause" />
<button data-player data-label="applause then bark!" data-track="applause;bark" />
<button data-player data-label="bark then chirp then bark again!" data-track="bark;chirp;bark" />
<button data-player data-label="applause then chirp!" data-track="applause;chirp" />
<button data-player data-label="applause with chirp then bark!" data-track="applause+chirp;bark" />
</body>
</html>
Yes, you can check if you have an element with a simple truthy/falsy check:
if (!slider) return;

How to resize two video elements with respect to the parent DIV size using javascript / Jquery?

I want to achieve dynamic video resizing in HTML using javascript. I have attached a detailed image of my requirement.
In the HTML, initially I have a single video element with two buttons add and delete.
When you click the Add button, a second video element will be appended to the parent DIV.
Also the first video should resize to left side and the new video should come to the right side (Need to fit both videos inside the parent DIV)
When you click the Delete button, the second video element will be removed (if it exists) and the first video should be fit to parent DIV.
function add_video() {
//add second video
var videoelement = document.createElement("video");
videoelement.setAttribute("id", "second_video");
videoelement.setAttribute("controls", "controls");
var sourceMP4 = document.createElement("source");
sourceMP4.type = "video/mp4";
sourceMP4.src = "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4";
videoelement.appendChild(sourceMP4);
document.getElementById("container").appendChild(videoelement);
//resize first video and second video
}
function delete_video() {
//delete the second video if exist
var myEle = document.getElementById("second_video");
if (myEle) {
myEle.remove();
}
//resize first video
}
#container {
width: 800px;
height: 400px;
border: 1px solid red;
}
video#firstvideo {
position: absolute;
width: 800px !important;
height: 400px !important;
}
<div id="container">
<!-- parent DIV-->
<video id="firstvideo" controls="controls">
<source type="video/mp4" src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"/>
</video>
</div>
<div id="buttons">
<button id="add_video" onclick="add_video()">Add</button>
<button id="delete_video" onclick="delete_video()">delete</button>
</div>
If any one knows, please explain how I can perform those logic? Since all the actions are dynamic, can i use javascript method here?
According to your code here's a working demo.
let defaultWidth = 800;
let defaultHeight = 400;
let container = document.getElementById('container');
let firstVideo = document.querySelector('#firstvideo');
container.style.width = firstVideo.style.width = defaultWidth+'px';
container.style.height = firstVideo.style.height = defaultHeight+'px';
function add_video(){
//add second video
var videoelement = document.createElement("video");
videoelement.setAttribute("id", "second_video");
videoelement.setAttribute("controls", "controls");
var sourceMP4 = document.createElement("source");
sourceMP4.type = "video/mp4";
sourceMP4.src = "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4";
videoelement.appendChild(sourceMP4);
container.appendChild(videoelement);
videos = document.querySelectorAll('video').forEach(function(v){
v.style.width = (parseInt(container.style.width)/2)-5+'px';
v.style.height = parseInt(container.style.height)+'px';
});
}
function delete_video(){
//delete the second video if exist
var myEle = document.getElementById("second_video");
if(myEle){
myEle.remove();
}
container.style.width = firstVideo.style.width = defaultWidth+'px';
}
#container{
width: 800px;
height: 400px;
border: 1px solid red;
}
#container video{
display:inline-block;}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>App</title>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link href="styles.css" rel="stylesheet" />
</head>
<body>
<div id="container"> <!-- parent DIV-->
<video id="firstvideo" controls="controls">
<source type="video/mp4" src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"/>
</video>
</div>
<div id="buttons">
<button id="add_video" onclick="add_video()">Add</button>
<button id="delete_video" onclick="delete_video()">delete</button>
</div>
</body>
</html>
This is a good question and many cannot safely answer but I have the solution that makes it epic for many-to-many broadcasting situations where cameras appear/disappear and resizing is necessary.
setInterval(()=>{
// You can add/remove element now and update after!
let elem = document.querySelector(".videos-items");
elem.innerHTML += `<div class="js-video"> <div class="video"> <div class="video-wrapper"> <video video-id="1" autoplay="" playsinline="">Your browser does not support the video tag...</video> </div> </div> </div>`;
UpdateVideo();
}, 1000); // Let's automate this for visuals
function UpdateVideo() {
let videos = document.querySelector("#videos"); // The parent element containing your videos
let elem = videos.querySelectorAll(".videos-items"); // All the video elements
if (elem !== undefined) { // If no videos don't run at all
for (let index = 0; index < elem.length; index++) {
if ("object" != typeof elem[index]) continue; // safety to not render further video
// Sometimes the video element is not actually visible say an unrendered embed, let's not consider it in our calculations!
let child = videos.querySelectorAll(".videos-items:nth-child(" + (index + 1) + ") > .js-video:not(.hidden)");
// Let's be very bad now and resize all the videos
if (child.length) ResizeVideo({ wrapper: elem[index], height: elem[index].clientHeight, width: elem[index].clientWidth, childs: child });
}
}
}
function ResizeVideo(a) {
// Don't worry about all this your head will melt.
let c = a.childs.length;
let e = 100;
let f = 100;
let d = 0;
let g = 0;
for (; c;) {
let d = Math.floor(a.height / c);
let h = Math.floor(d / 0.75);
if (h > a.width) {
h = a.width;
d = Math.floor(0.75 * h);
}
let i = Math.floor(a.width / h);
for (; i * c < a.childs.length || d * c > a.height;) {
i++;
h = Math.floor(a.width / i);
d = Math.floor(0.75 * h);
}
let j = d * h;
let k = a.height * a.width;
let l = Math.floor(1e4 * ((k - j * a.childs.length) / k)) / 100;
if (0 < l && e >= l) {
if (1 < c && a.childs.length % i) {
let d = i;
for (; d;) {
if (Math.ceil(a.childs.length / d) > c) {
d++;
break;
}
d--;
}
g = d < i && d ? Math.floor((a.width - d * h) / 2) : 0;
} else {
g = 0;
}
e = l;
f = Math.floor(100 * (100 * (h / (a.width - 2 * g)))) / 100;
}
c--;
}
for (let c in a.wrapper.style.padding = "0 " + g + "px", a.childs) {
if ("object" == typeof a.childs[c] && (a.childs[c].style.width = f + "%")) {
let e = a.childs[c].clientHeight;
let g = a.childs[c].clientWidth;
a.childs[c].style.width = (100 === f && a.height - d > e) ? f + "%" : Math.floor(100 * (e * g / (e + d) / (g / f))) / 100 + "%";
}
}
}
.videos-items{
display: flex;
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
flex-direction: row;
flex-wrap: wrap;
align-content: center;
justify-content: center;
align-items: center;
box-sizing: border-box;
}
.videos-items.hidden {
display: none;
}
.videos-items>.js-video {
width: 100%;
}
.video>.video-wrapper:before {
content: '';
display: block;
width: 100%;
padding-bottom: 75%;
border:1px black solid;
}
.js-video>video {
position: absolute;
height: 100%;
top: 0;
left: 0;
background: black;
}
.video>div>video {
position: absolute;
height: 100%;
top: 0;
left: 0;
width: 100%;
}
<div id="videos">
<div class="videos-items">
<div class="js-video">
<div class="video">
<div class="video-wrapper">
<video video-id="1" autoplay="" playsinline="">Your browser does not support the video tag...</video>
</div>
</div>
</div>
<div class="js-video">
<div class="video">
<div class="video-wrapper">
<video video-id="2" autoplay="" playsinline="">Your browser does not support the video tag...</video>
</div>
</div>
</div>
<div class="js-video">
<div class="video">
<div class="video-wrapper">
<video video-id="3" autoplay="" playsinline="">Your browser does not support the video tag...</video>
</div>
</div>
</div>
<div class="js-video">
<div class="video">
<div class="video-wrapper">
<video video-id="4" autoplay="" playsinline="">Your browser does not support the video tag...</video>
</div>
</div>
</div>
<div class="js-video">
<div class="video">
<div class="video-wrapper">
<video video-id="5" autoplay="" playsinline="">Your browser does not support the video tag...</video>
</div>
</div>
</div>
<div class="js-video">
<div class="video">
<div class="video-wrapper">
<video video-id="6" autoplay="" playsinline="">Your browser does not support the video tag...</video>
</div>
</div>
</div>
</div>
</div>
The code is fairly straight forward in the sense any time you need to update the videos, say a request came in to load another video when the element is ready you would fire off UpdateVideo();
It will loop and sort everything for you. You'd need to slightly modify the UpdateVideo to properly search your videos but fairly straight forward or a question to ask in a different post.
Good luck!
Updated
Code will insert new video elements every 1 second and update the videos position, this will keep track of screen height/width and keep items from falling off the page. Example should run perfectly, but don't run it too long just a demo.
The class videos-item can be setup to split-screen if you need two zones for scaling images or more!

Use html <a> tag with same z-index?

I have slider and when i mouseover on slider play button is displaying, but slider images are inside a tag and when play button is not hidden i can't click on images inside a tag. i tried set same z-index for both (slider images and play button) but still not working
i need to click on play button when it shown and go to link placed bottom of this play button
if it is possible please help, and sorry for my bad english.
Main question: how can i click on play button with and redirect to link placed inside a tag?
Here is image how slider looks like onmouseover and image when mouse is out of slider
here is my html code:
<style type="text/css">
#slider-play-button-container{
position: absolute;
z-index: 2;
left: 0;
right: 0;
text-align: center;
cursor: pointer;
}
#slider-play-button{
position: relative;
top: 25vh;
width: 2vw;
opacity: 0;
}
.slide-img{
width: 100%;
height: 55vh;
object-fit: cover;
border-radius: .7vw;
overflow:hidden;
}
</style>
<main class=content>
<span id="slider-play-button-container"><img src="https://i.imgur.com/md7vyI8.png" id="slider-play-button"></span>
<div id="slider">
<a href="Link to go after play button click" target="_Blank">
<h3 class="slider-movie-name">ჯონ ვიკი: III თავი - პარაბელუმი</h3>
<img src="https://i.imgur.com/OP3AITl.jpg" class="slide-img">
</a>
<a href="Another link to go after play button click" target="_Blank">
<h3 class="slider-movie-name">შურისმაძიებლები: დასასრული</h3>
<img src="https://i.imgur.com/3vDzVHa.jpg" class="slide-img">
</a>
</div>
</main>
<script>
function bid(n){return document.getElementById(n)}
function qs(n){return document.querySelector(n)}
function qsa(n){return document.querySelectorAll(n)}
let slider = bid('slider');
let arrowTop = bid('slide_arrow_top');
let arrowBottom = bid('slide_arrow_bottom');
let sliderImage = qsa('.slide-img');
let sliderPlayButtonContainer = bid('slider-play-button-container');
let sliderPlayButton = bid('slider-play-button');
let count = 0;
let imageOffset = 0;
let imgOffset = 0;
var slideInterval;
let sliderImageOffset;
/* autoscroll */
window.addEventListener('load',winLoadForSlide);
function winLoadForSlide(){
/* slider */
slider.addEventListener('wheel',slideMouseScroll);
arrowBottom.addEventListener('click',scrollBottom);
arrowTop.addEventListener('click',scrollTop);
function bottomSlide(){
if (count < 4) {
count++;
}
imageOffset = sliderImage[count].offsetTop;
slider.scrollTo(0,imageOffset);
}
function topSlide(){
if (count > 0) {
count--;
}
imageOffset = sliderImage[count].offsetTop;
slider.scrollTo(0,imageOffset-5);
}
function slideMouseScroll(){
if (event.deltaY < 0){
topSlide();
}else if (event.deltaY > 0){
bottomSlide();
}
}
function scrollBottom(){
bottomSlide();
}
function scrollTop(){
topSlide();
}
slideInterval = setInterval(repeatScroll,100 * 20);
function showSliderPlayButton(){
sliderPlayButton.style.transform = "scale(5)";
sliderPlayButton.style.opacity = "1";
sliderPlayButton.style.transition = "250ms";
}
function hideSliderPlayButton(){
sliderPlayButton.style.transform = "scale(1)";
sliderPlayButton.style.opacity = "0";
sliderPlayButton.style.transition = "250ms";
}
[slider,arrowBottom,arrowTop,sliderPlayButtonContainer,sliderPlayButton].forEach(slideElements => {
slideElements.addEventListener('mouseover',()=>{
clearInterval(slideInterval);
});
slideElements.ondragstart = function(){ return false; }
});
[slider,sliderPlayButtonContainer,sliderPlayButton].forEach(slideElementsWithoutButtons => {
slideElementsWithoutButtons.addEventListener('mouseover',()=>{
showSliderPlayButton();
});
});
slider.addEventListener('mouseleave',()=>{
slideInterval = setInterval(repeatScroll,100 * 20);
hideSliderPlayButton();
});
function repeatScroll(){
if( (slider.scrollHeight - slider.scrollTop - slider.clientHeight) !== 4 ){
if (imgOffset < 4) {
imgOffset++;
}
sliderImageOffset = sliderImage[imgOffset].offsetTop;
slider.scrollTo(0,sliderImageOffset);
}else{
imgOffset = 0;
slider.scrollTo(0,0);
}
}
/* END slider */
}
/* END autoscroll */
</script>
There are a few ways to get around this problem.
One would involve getting rid of the anchor tags altogether, grouping each image inside a single container and assigning a click event listener to each one to ultimately open the link. If you then add another click listener to the arrow button which executes event.preventDefault(); the click event will be passed through to the object below - the <div> including your image.
If you want to keep the anchor tags, things are a little tricky. Luckily there are some helpful JavaScript functions, foremost document.elementsFromPoint(x,y).
If you feed the current mouse coordinates to this function - e.g. by clicking on the arrow button - it will return an array of objects below this point.
This array contains the anchor element in the background, so it's just a matter of picking it out of the array, get the link assigned to it and open it using the window.open() command.
Here's an example:
function bid(n) {
return document.getElementById(n)
}
let sliderPlayButtonContainer = bid('slider-play-button-container');
let sliderPlayButton = bid('slider-play-button');
sliderPlayButtonContainer.addEventListener('click', (event) => {
var list = document.elementsFromPoint(event.clientX, event.clientY)
var anchorElement = list.find(element => element instanceof HTMLImageElement && element.className == 'slide-img').parentElement;
window.open(anchorElement.href, anchorElement.target);
});
function showSliderPlayButton() {
sliderPlayButton.style.transform = "scale(5)";
sliderPlayButton.style.opacity = "1";
sliderPlayButton.style.transition = "250ms";
}
sliderPlayButtonContainer.addEventListener('mouseover', () => {
showSliderPlayButton();
});
#slider-play-button-container {
position: absolute;
z-index: 2;
left: 0;
right: 0;
text-align: center;
cursor: pointer;
}
#slider-play-button {
position: relative;
top: 25vh;
width: 2vw;
opacity: 1;
}
.slide-img {
width: 100%;
height: 55vh;
object-fit: cover;
border-radius: .7vw;
overflow: hidden;
}
<span id="slider-play-button-container"><img src="https://i.imgur.com/md7vyI8.png" id="slider-play-button"></span>
<div id="slider">
<a href="https://www.startpage.com" target="_blank">
<h3 class="slider-movie-name">ჯონ ვიკი: III თავი - პარაბელუმი</h3>
<img src="https://i.imgur.com/OP3AITl.jpg" class="slide-img">
</a>
</div>
parentElement property helped a lot to solve my problem
playButtonATagHref = sliderImage[imgOffset].parentElement.href;
sliderPlayButton.addEventListener('click',()=>{
window.location.href = playButtonATagHref;
});

How jump ahead in audio by the amount clicked on a progress bar? [duplicate]

<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script>
$(document).ready(function(){
var counter = 0;
var numOfTracks = $(".audio-player").length;
$("#play-bt").click(function(){
$(".audio-player")[counter].play();
$("#message").text("Music started");
})
$("#pause-bt").click(function(){
$(".audio-player")[counter].pause();
$("#message").text("Music paused");
})
$("#stop-bt").click(function(){
$(".audio-player")[counter].pause();
$(".audio-player")[counter].currentTime = 0;
$("#message").text("Music Stopped");
})
$("#next-bt").click(function(){
$(".audio-player")[counter].pause();
$(".audio-player")[counter].currentTime = 0;
counter++;
if(counter > numOfTracks - 1){
counter = 0 ;
}
$(".audio-player")[counter].play();
$("#message").text("Next Track started");
})
$("#prev-bt").click(function(){
$(".audio-player")[counter].pause();
$(".audio-player")[counter].currentTime = 0;
counter--;
$(".audio-player")[counter].play();
$("#message").text("Previous Track");
})
$(".audio-player").bind('timeupdate', function(){
//Gets the whole duration of the track.
//No idea kung saan ko ilalagay sa UI**IMPLEMENT LATER**
var track_length = $(".audio-player")[counter].duration;
var secs = $(".audio-player")[counter].currentTime;
var progress = (secs/track_length) * 100;
$('#progressbar').css({'width' : progress * 2});
//Will Use these later on production
//NOTE DO NOT DELETE
//Track Minutes
var tcMins = parseInt(secs/60);
//Track Seconds
var tcSecs = parseInt(secs - (tcMins * 60));
if (tcSecs < 10) { tcSecs = '0' + tcSecs; }
// Display the time. REMEMBER
$('#timecode').html(tcMins + ':' + tcSecs);
})
})
</script>
<style>
/*Seperate this some time in the development*/
#playerContainer{
background-color: #A8A8A8 ;
width: 260px;
height: 55px;
padding: 8px;
border: 1px solid #d0d0d0;
}
/* Player Controls */
/*list items of controls */
#playerControls li {
display: block;
width: 32px;
height: 32px;
padding: 0px;
float: left;
cursor: pointer;
}
#playerControls { list-style: none; padding: 0px; margin: 0px;}
/*Images for each li items items */
#play-bt { background: url('icons/glyphicons_173_play.png'); background-repeat:no-repeat }
#pause-bt {background: url('icons/glyphicons_174_pause.png'); background-repeat:no-repeat;}
#next-bt { background: url('icons/glyphicons_176_forward.png'); background-repeat:no-repeat}
#prev-bt {background: url('icons/glyphicons_172_rewind.png'); background-repeat:no-repeat;}
/*Progress Stuff*/
/*Remember to manipulate its width via javascript later*/
#progressContainer
{
background-color:#e0e0e0;
height: 14px;
width: 256px;
float: left;
margin-left: 0px;
}
#progressbar {background-color: #1384bb; height:14px; width:0%; }
</style>
</head>
<body>
<audio class ="audio-player" name= "audio-player" src="04-zedd-stars_come_out_(terravita_remix).ogg" >
<p>Sorry your file doesn't support html5</p>
</audio>
<!--Second Track For Testing Purposes-->
<audio class ="audio-player" name= "audio-player" src="01-hard_rock_sofa-quasar.mp3" ></audio>
<div id="message"></div>
<div id = "playerContainer">
<ul id = "playerControls" >
<li id = "prev-bt"></li>
<li id= "play-bt"></li>
<li id= "pause-bt"></li>
<li id = "next-bt"></li>
<li id= "stop-bt" ></li>
<li><span id ="timecode"></span></li>
</ul>
<div id="progressContainer"><!-- Progess bars container //-->
<div id="progressbar"></div>
</div>
</div>
</div>
</body>
</html>
How can I click a certain part of my progress bar so that I can move it to a different time in the track? I have no idea on how I am going to do that. any ideas ?
Given some html that looks like this:
<div class="container">
<video class="video">
<source></source>
</video>
<progress min="0" max="100" value="0"></progress>
<div class="controls"></div>
</div>
In order to seek to a specific time in the video as a result of a click event the js would look like this:
var player = document.querySelector("video");
var progressBar = document.querySelector("progress");
progressBar.addEventListener("click", seek);
function seek(e) {
var percent = e.offsetX / this.offsetWidth;
player.currentTime = percent * player.duration;
progressBar.value = percent / 100;
}
However, this doesn't address how to seek on a click/drag (like most video players do). include script
I came across this question today because I am creating a custom HTML5 video player and had the same question. Just in regards to video instead of audio. The process should work the same though.
I found this article and was able to incorporate the progress bar part of it into my player. https://msdn.microsoft.com/en-us/library/ie/gg589528%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
Instead of using a progressbar element, like I was doing, or a div element, like you're doing, the trick here is to use a canvas element instead.
<canvas id='progress-bar' width="200" height="20" style="border:1px solid green;">canvas not supported</canvas>
Then in your JavaScript, create a handle to reference it by
var mediaPlayer;
var progressBar;
var canvas;
When the document loads, initialize everything including the progress bar items
mediaPlayer = document.getElementById('media-video');
progressBar = document.getElementById('progress-bar');
canvas = document.getElementById('progress-bar');
canvas.addEventListener("click", function(e) {
var canvas = document.getElementById('progress-bar');
if (!e) {
e = window.event;
} //get the latest windows event if it isn't set
try {
//calculate the current time based on position of mouse cursor in canvas box
mediaPlayer.currentTime = mediaPlayer.duration * (e.offsetX / canvas.clientWidth);
}
catch (err) {
// Fail silently but show in F12 developer tools console
if (window.console && console.error("Error:" + err));
}
}, true);
mediaPlayer.addEventListener('timeupdate', updateProgressBar, false);
Then create a function outside of your initialization function for the timeupdate listener to call and automatically update the progress bar for you
function updateProgressBar() {
mediaPlayer = document.getElementById('media-video');
//get current time in seconds
var elapsedTime = Math.round(mediaPlayer.currentTime);
//update the progress bar
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
//clear canvas before painting
ctx.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight);
ctx.fillStyle = "rgb(255,0,0)";
var fWidth = (elapsedTime / mediaPlayer.duration) * (canvas.clientWidth);
if (fWidth > 0) {
ctx.fillRect(0, 0, fWidth, canvas.clientHeight);
}
}
}
I haven't completely cleaned it up yet. Hence the redundant handles to the same id. But I'm sure you get the picture.
Hope this can save someone some time. If you're trying to set this up in an Angular app, you'll notice this is your controller context. So you'll need to use e.srcElement.clientWidth for this to work.
vm.setPosition = function(e){
var percent = ((e.offsetX / e.srcElement.clientWidth));
vm.songObject.setProgress(percent);
}
I wrote about that in Working with HTML5 multimedia components – Part 3: Custom controls, scroll down to "Adding a progress bar".

how to fix issue with youtube player not showing up with full width & height?

Below is sample of my code im trying to use playlist where the player will be in full width and height but for some reason it's not working. So what i'm trying to accomplish is the player will be on full page without anything else. Nothing else will show up example link here is link for fiddle any help will be appreciated.
COPY of code
<html>
<head>
</head>
<body onload="load()" style="background-color:white">
<script type="text/javascript">
var playlisturl = "http://gdata.youtube.com/feeds/api/playlists/PL704DA9FE5E10160C?v=2";
var playlisturls = ["http://gdata.youtube.com/feeds/api/playlists/PL704DA9FE5E10160C?v=2"];
var pause_playlist_text = "Pause playlist (loop current video)";
var embed = true;
var autoplay = true;
var vwidth = 400;
var vheight = 500;
</script>
<script type="text/javascript" src="http://youtube-playlist-randomizer.valami.info/seedrandom.js"></script>
<script type="text/javascript" src="http://youtube-playlist-randomizer.valami.info/playlist2-min.js"></script>
<div id="control_buttons" style="display:none">
<button style="display:none" id="nextbutton" onclick="next()">Play next</button> <span style="display:none" id="videosleft"></span> <button style="display:none" id="previousbutton" onclick="previous()">Play previous</button>
<button style="display:none" id="pauseplaylist" onclick="pause_playlist()">Pause playlist (loop current video)</button> <button style="display:none" onclick="reshuffle()">Reshuffle</button>
</div>
<script type="text/javascript">
document.getElementById('pauseplaylist').style.display = "none"
</script>
<div id="video">
<p>Loading playlist...</p>
</div>
<div class="videowrapper">
<div id="myytplayer"></div>
</div>
<script type="text/javascript">
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var ytplayer;
function onYouTubeIframeAPIReady()
{
ytplayer = new YT.Player('myytplayer', {
height: vheight,
width: vwidth,
videoId: '8tPnX7OPo0Q',
events: {
'onReady': onYouTubePlayerReady,
'onStateChange': onytplayerStateChange,
'onError': onytplayerError
}
});
}
</script>
</body>
</html>
Make the container width and height 100%, Check this out :
#myytplayer {
width:100%;
height:100%;
}
.videowrapper {
width:100%;
height:100%;
}
Hi, you could use tubular: http://www.seanmccambridge.com/tubular/
as tubular is quite suffisticated, i extracted the necessary code
for you. (renders the video in full width and height, NOT stetched, similar to a css cover image)
html code:
<div id="player-container" style="overflow: hidden; position: absolute; width: 100%; height: 100%;">
<div id="player" style="position: absolute">
</div>
here comes the complete youtube API cover style stuff, extracted from
tubular. jquery is needed. Also the standard youtube html5 iframe api
code must be included - as given here:
https://developers.google.com/youtube/iframe_api_reference#Getting_Started
var ratio = 16 / 9;
window.onPlayerReady = function (e) {
resize();
}
$(window).on('resize', function () {
resize();
})
var resize = function () {
console.log("resize");
var heightcorrection = 0,
width = $(window).width(),
pWidth, // player width, to be defined
height = $(window).height() - heightcorrection,
pHeight, // player height, tbd
$videoPlayer = $('#player');
if (width / ratio < height) { // if new video height < window height (gap underneath)
pWidth = Math.ceil(height * ratio); // get new player width
$videoPlayer.width(pWidth).height(height).css({
left: (width - pWidth) / 2,
top: 0
}); // player width is greater, offset left; reset top
} else { // new video width < window width (gap to right)
pHeight = Math.ceil(width / ratio); // get new player height
$videoPlayer.width(width).height(pHeight).css({
left: 0,
top: (height - pHeight) / 2
}); // player height is greater, offset top; reset left
}
}

Categories