Uploaded .mov video plays out of sync - javascript

After uploading the videos into the server, and you try to watch by clicking the play button the videos with the (.mp4) format plays well smoothly but the (.mov) video plays out of sync, like the voice delays, but if you download it, it plays normally with no problem. I don't know what could be the problem and the potential solution for it. I've tried Preloading but did not work.
My HTML the src is placed dynamically
<div class="video-player" id="videoPlayer">
<video width="100%" controls autoplay id="talentVideo">
<source src="" type="video/mp4">
<source src="" type="video/qt">
</video>
<i class="fas fa-times close-btn" onclick="stopVideo()"></i>
</div>
My Js code:
<script>
var videoPlayer = document.getElementById("videoPlayer");
var talentVideo = document.getElementById("talentVideo");
function stopVideo(){
videoPlayer.style.display = "none";
talentVideo.pause();
talentVideo.currentTime = 0;
}
const playVideoBtn = document.querySelectorAll('.video-tal .pathLinkToPlay');
for(let i = 0; i < playVideoBtn.length; i++){
// playVideoBtn[i].addEventListener("click", function(){ alert("Hello World!"); });
playVideoBtn[i].onclick = ()=>{
var videopath = playVideoBtn[i].getAttribute('data-id'); //getting the url of clicked video
window.videoPlayingId = playVideoBtn[i].getAttribute('id'); //getting the id of clicked video
window.roleId = playVideoBtn[i].getAttribute('data-role-id'); //getting the role_id of clicked video
window.talentId = playVideoBtn[i].getAttribute('data-talent-id'); //getting the talent_id of clicked video
playVideo(videopath);
}
}
function playVideo(videopath){
talentVideo.src = videopath;
videoPlayer.style.display = "block";
}

Related

JavaScript html5 video

I have a sample html5 video with simple html code.
What I need to do is a customized mute button for all the videos, meaning:
if the user clicks on the mute/unmute button for one video, all the other videos get muted/unmuted as well
Is there any way of doing this?
without your html code it is pretty vague but in JS you can do it :
here is a link of the documentation im using :
https://www.w3schools.com/tags/av_prop_muted.asp
https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_av_prop_muted
<button onclick="enableMute()" type="button">Mute sound</button>
<button onclick="disableMute()" type="button">Enable sound</button>
<video id="myVideo" width="320" height="176" controls>
<source src="mov_bbb.mp4" type="video/mp4">
<source src="mov_bbb.ogg" type="video/ogg">
Your browser does not support HTML5 video.
</video>
<script>
var vid = document.getElementById("myVideo");
function enableMute() {
vid.muted = true;
}
function disableMute() {
vid.muted = false;
}
</script>
So to trigger the action on all your videos you can :
add a class preferably or id on all your video tag
make js know about them
var vid = document.getElementById("myVideo");
var vid1 = document.getElementById("myVideo1");
var vid2 = document.getElementById("myVideo2");
var vid3 = document.getElementById("myVideo3");
var vid4 = document.getElementById("myVideo4");
add an onClick action on a button that trigger an action here Mute action which will mute or unmute your videos using the mute property of your element, the action would like
function enableMute() {
vid.muted = true;
vid1.muted = true;
vid2.muted = true;
vid3.muted = true;
vid4.muted = true;
}
I think you could do it without this much duplication of code if you add the same class to all your element, and looping through all of them in the action you trigger when you click on the button and then change for each of them their property but not sure exactly how to do it

Hiding HTML5 video sources in div tag id attributes

I’d like to be able to specify my video sources for my toggle button in the HTML document so that I don’t have to include them in the JavaScript code.
I figured out a way to accomplish it by hiding the URLs in div tags as id attributes and then getting them in the JavaScript by their class name. (See below). This seems like a total hack. I’m sure there must be a better way to do this. Any suggestions?
<!DOCTYPE html>
<html>
<body>
<div class="video1" id="http://www.w3schools.com/html/mov_bbb.mp4"></div>
<div class="video2" id="http://www.w3schools.com/html/movie.mp4"></div>
<button onclick="Harmonica(this,'myVideo')" type="button"> Video 2</button>
<video height="auto" width="500"id="myVideo" controls autoplay loop class="myvideo">
<source id="mp4_src" src="http://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
</video>
</body>
<script>
var vid = document.getElementById("myVideo");
var statusElement = document.getElementById("status");
var currentlyPlaying = 1;
var currentlPlayingTime;
var src1 = document.getElementsByClassName("video1")[0].id;
var src2 = document.getElementsByClassName("video2")[0].id;
function Harmonica(btn,myVideo) {
currentlPlayingTime = vid.currentTime;
if (currentlyPlaying === 1) {
vid.src = src2;
currentlyPlaying = 2;
btn.innerHTML = "Video 1";
} else {
vid.src = src1;
currentlyPlaying = 1;
btn.innerHTML = "Video 2";
}
vid.load();
vid.addEventListener('canplay', function () {
vid.currentTime = currentlPlayingTime;
}, false);
}
</script>
</html>

Single click not working on javascript

I am building a video website, when user clicks on a picture related video runs. But the problem is that first time a user have to double click on a link, after that single click works.
Here's html:
<div id="player_container">
<video controls="controls" id="videoclip" autoplay>
<source id="mp4video" src="videos\video.mp4" type="video/mp4" />
<source id="oggSource" src="video.mp4" type="video/ogg">
<p> Your browser does not support the video tag <p>
</video>
<div class="vid_container_row2">
<div class="shadow2">
<div>
<a href="#" onclick="myFunctionId(this.id);" id="videolink1">
<img class="top" src="images/gayle1.jpg" height="80px" width="110px">
</a>
</div>
</div>
<div class="shadow2">
<div>
<a href="#" onclick="myFunctionId(this.id);" id="videolink2">
<img class="top" src="images/rohit-sharma.jpg" height="80px" width="110px">
</a>
</div>
</div>
<div class="shadow2">
<div>
<a href="#" onclick="myFunctionId(this.id);" id="videolink3">
<img class="top" src="images/blara.jpg" height="80px" width="110px">
</a>
</div>
</div>
</div>
</div>
here is my javascript code:
<script type="text/javascript">
function myFunctionId(id){
var jungi = id;
if (jungi == "videolink1")
{
var videocontainer = document.getElementById('videoclip');
var videosource = document.getElementById('mp4video');
var videobutton = document.getElementById('videolink1');
var newmp4 = 'videos/video.mp4';
videobutton.addEventListener("click", function(event) {
videocontainer.pause();
videosource.setAttribute('src', newmp4);
videocontainer.load();
videocontainer.play();
}, false);
}
else if (jungi == "videolink2")
{
var videocontainer = document.getElementById('videoclip');
var videosource = document.getElementById('mp4video');
var videobutton = document.getElementById('videolink2');
var newmp4 = 'second_video.mp4';
videobutton.addEventListener("click", function(event) {
videocontainer.pause();
videosource.setAttribute('src', newmp4);
videocontainer.load();
videocontainer.play();
}, false);
}
else
{
var videocontainer = document.getElementById('videoclip');
var videosource = document.getElementById('mp4video');
var videobutton = document.getElementById('videolink3');
var newmp4 = 'third_video.mp4';
videobutton.addEventListener("click", function(event) {
videocontainer.pause();
videosource.setAttribute('src', newmp4);
videocontainer.load();
videocontainer.play();
}, false);
}
}
</script>
When you click the link
<a href="#" onclick="myFunctionId(this.id);" id="videolink3">
You are executing the function that adds a click handler to the element. To now activate this click, you will have to click it again. To add the event listeners on load, remove the onclick attributes from your elements and simply pre-apply the function to your DOM like this:
var videobutton1 = document.getElementById('videolink1');
var videobutton2 = document.getElementById('videolink1');
var videobutton3 = document.getElementById('videolink1');
[videobutton1, videobutton2, videobutton3].forEach(function(button){
myFunctionId( button.id )
});
It's a bit of a roundabout way (you should not have to find by id and then pass the id, you could just pass the elements around), but it works.
A potentially better way is to structure your dom a little better. here is an example:
var videoPath = document.querySelector('h1'); // This is for debugging on Stack Overflow - there are no videos here so nothing will display. We will change this value to show it is working.
var video = document.querySelector('video'); // get the main video element
var links = document.querySelectorAll('.changeVideoSource'); // get all links marked with the class changeVideoSource
for(var i = 0; i < links.length; i++){
links[i].addEventListener('click', function(e){
e.preventDefault(); // Prevent following the link
video.src = this.getAttribute('href'); // set the source
videoPath.textContent = this.getAttribute('href'); // show the update as the videos are not available here
video.play(); // Although your video hasn't loaded yet, the system will actually try to start playing as soon as it can.
})
}
video { width: 100%; height: 200px; background: #000; }
Video 1
Video 2
Video 2
<h1>video1.mp4</h1>
<video src="video1.mp4"></video>
This is much simpeler, and adding another video link is now super easy! Also, as an added bonus, people with disabled javascript still have access to the videos as the link will now just be followed.
video.load() starts the loading process, but returns before the video is loaded, and hence the play immediately following it doesn't work as it isn't loaded yet. You need to use :
video.addEventListener('canplaythrough', function() {
// Video is loaded and can be played
}, false);
For one section:
var videocontainer = document.getElementById('videoclip');
var videobutton = document.getElementById('videolink3');
var newmp4 = 'third_video.mp4';
videobutton.onclick = null;
videocontainer.src = newmp4;
videocontainer.load();
videocontainer.oncanplay = function (e) {
videocontainer.play();
}
videobutton.onclick = function (e) {
myFunctionId(id);
}

How do I dynamically change multiple video sources using JavaScript?

I'm trying to dynamically change the video source with the onclick event.
Here's the HTML:
<video autoplay loop poster="1.jpg" id="bg">
<source src="/static/media/1.webm" type="video/webm">
<source src="/static/media/1.mp4" type="video/mp4">
</video>
In onclick I generate a random link, then I change the source of the <video> element:
window.onclick = function() {
var randint = Math.floor(Math.random() * 10) + 1;
var srcmp4 = "http://127.0.0.1:8888/static/media/" + randint.toString() + ".mp4";
document.getElementById('bg').src=srcmp4;
};
If I try to access the source element the same way, by assigning it an id:
<source id="webmid" src="/static/media/1.webm" type="video/webm">
I get null.
I want to dynamically change both .jpg, .webm, .mp4 links. How do I access and assign multiple source elements inside video tag via JS?
The video tag is missing width, height, and controls attributes. Try this:
<video width="320" height="240" id="bg" autoplay loop controls>
<source src="/static/media/1.webm" type="video/webm">
<source src="/static/media/1.mp4" type="video/mp4">
</video>
Additionally here is the new js:
window.onclick = function() {
var randint = Math.floor(Math.random() * 10) + 1;
var srcmp4 = "http://127.0.0.1:8888/static/media/" + randint.toString() + ".mp4";
var video = document.getElementById('bg');
var source = document.getElementByTagName('source');
source = srcmp4;
video.load();
};
After changing that, the source seems to change according to this test.
So i did some reading. First i tried deleting children of video, creating new source elements and appending to video, everything worked in page source, but view didn't render any changes.
So i followed .canPlayType route to determine if client supports .webm, and if not -- assigning mp4 src directly to video element.
Also added small fix so random generated numbers won't repeat. Random video loads when page is loaded and on click events afterwards. Here is the code, it's a mess:
<video autoplay loop poster="" id="bg">
</video>
<script type="text/javascript">
function randlink(a,b){
// generate random int in range of a,b. return str
var c = Math.floor(Math.random()*b)+a;
return "/static/media/"+c.toString();
}
//assign video new random src and poster on page load
window.onload = function(){
var bgvid = document.getElementById('bg');
var randbase = randlink(1,10);
bgvid.poster = randbase + ".jpg";
//check if webm, else mp4 src
if(bgvid.canPlayType('video/webm; codecs="vp8, vorbis"') != ""){
bgvid.src = randbase+".webm";
} else { bgvid.src = randbase+".mp4"}
//change src and poster on click
window.onclick = function() {
var randbase2 = randlink(1,10);
//check if unique
do{
randbase2 = randlink(1,10)
} while (randbase2 == randbase);
randbase = randbase2;
bgvid.poster = randbase2 + ".jpg";
var webmstr = ".webm";
//check if previous was webm, else mp4
if(bgvid.src.indexOf(webmstr) > 0){
bgvid.src = randbase2 +".webm";
}else{
bgvid.src = randbase2 +".mp4";
}}
};
I've already answered this before here: Can I use javascript to dynamically change a video's source?
You have to give the source tags different ids and then add another document.getElementById("source").src = "ANOTHER_SOURCE"; after the first one

HTML5 video custom controls for any number of videos on the page

mates!
I was needed a simple text button – "Play". It should be hidden if video is playing and should be visible when video ends. Everything works fine, but it works only if I have one video on the page with unique ID.
HTML:
<video id="main-video" width="640" height="480">
<source src="media//mp4/video.mp4" type="video/mp4">
</video>
<span id="custom-play-button">Play</span>
And here is the JS:
window.onload = function() {
var video = document.getElementById("main-video");
var playButton = document.getElementById("custom-play-button");
playButton.addEventListener("click", function() {
document.getElementById('main-video').addEventListener('ended',myHandler,false);
video.play();
playButton.style.visibility = "hidden";
function myHandler(e) {
playButton.style.visibility = "visible";
}
});
}
But what should I do if there will be 4,5,6...100 videos on the page (and there will be)? I can't handle with 100 unique ID...
You can put every video and button in a parent div tag as below.
<div class="video-container">
<video id="main-video" width="640" height="480">
<source src="media//mp4/video.mp4" type="video/mp4">
</video>
<span id="custom-play-button">Play</span>
</div>
I'm using jQuery code, you can translate it to plain JS easily.
This should work.
$(".video-container").each(function () {
var video = $(this).find("video");
var plainVideo = video.get(0);/*DOM video object, unwrapped from jQuery*/
var playBtn = $(this).find("span");
playBtn.click(function () {
video.get(0).addEventListener('ended',myHandler,false);
plainVideo.play();
playBtn.css("visibility", "hidden");
function myHandler(e) {
playBtn.css("visibility", "visible");
}
});
});
At least this will give you an idea about the approach to this problem.
With pure Javascript (No jQuery)
You should but depend on the id, use the tag for reference, and get the nearest span. See the below code.
function closest(el, sel) {
if (el != null) return el.matches(sel) ? el : (el.querySelector(sel) || closest(el.parentNode, sel));
}
var videos = document.getElementsByTagName("video");
for (i = 0; i < videos.length; i++) {
var video = videos[i];
var playButton = closest(video, "span");
playButton.addEventListener("click", function () {
document.getElementById('main-video').addEventListener('ended', myHandler, false);
video.play();
playButton.style.visibility = "hidden";
function myHandler(e) {
playButton.style.visibility = "visible";
}
});
}
<video width="640" height="480">
<source src="media//mp4/video1.mp4" type="video/mp4">
</video>
<span class="custom-play-button">Play</span>
<video width="640" height="480">
<source src="media//mp4/video2.mp4" type="video/mp4">
</video>
<span class="custom-play-button">Play</span>
You've got to use CSS classes rather that id's and you have to use JavaScript to listen for video events and have your custom controls such as playpause button toggle. JavaScript's event.target tells you which video is doing what. MDN has a great article Creating a cross-browser video player which includes detailed instructions for custom controls for a single video.
Automated
I spent a few days creating a JavaScript that automates custom controls (Google's Material Design UI) for any number of videos on your HTML page.
The readable source code is on github at rhroyston/material-controls-for-html-video.
Fairly complex to do, but as you can see, it can be done. Live working demo is at https://hightechtele.com/articles/material-controls-for-html-video
Finally, like I said, this took me a few days. It's easy to do by hand for a single video but wanted to automate/script it. ...So view the script (and small accompanied CSS) to see how it can be done.

Categories

Resources