Cannot show a html5 video dynamically with js - javascript

I have a table which looks like this:
+------------+---------+
| Name | View |
+------------+---------+
| 1.mp4 | X |
| 2.mp4 | X |
+------------+---------+
X are view buttons.
When the user clicks on any of the view button, I want to show the corresponding video in a modal. I am using html5 video tag for that. In the video tag, I want to provide the src dynamically.
The src would be name of the video. I am using javascript for this.
HTML:
the X button:
<a data-toggle="modal" data-id={{name}} href="#Modal" class="preview">X</a>
<!--{{name}} is 1.mp4-->
modal:
...
<div class="modal-body">
<video width="548" height="455" controls>
<source id="vsrc" type="video/mp4">
Your browser does not support video playback.
</video>
</div>
...
JS:
var videoName = $(this).data('id'); //This is correct
document.getElementById('vsrc').src = videoName;
When I check the source code of the page, the src is correctly set,
<source id="vsrc" type="video/mp4" src="1.mp4">
But there is no video shown on the page, only an empty container and some disabled video control buttons are displayed.
I tried pasting this source code into the actual HTML page and it worked that way, I can't figure out why it doesn't work dynamically.

Set the video source directly like this...
var vid = document.getElementById('vid');
vid.src = "http://clips.vorwaerts-gmbh.de/VfE_html5.mp4";
vid.play();
<div class="modal-body">
<video id="vid" width="548" height="455" controls>
Your browser does not support video playback.
</video>
</div>

Related

Play Video by trigger('play') for 1

$('a.thumbnail').click(function(){
$(this).('.cu_vd').trigger('play');
});
$('a.thumbnail').click(function(){
$(this).('.cu_vd').trigger('play');
});
I am trying to play the video by trigger but the video boxes are multiple with the same class. So I am trying to use 'this' so that It does not trigger to all, but it's not working This is the HTML page, where I am trying to play the video
https://dev-visualshowcase.cvent.com/bkeventvideos.html click on the IOV 1 (First box) the pop-up triggers and I want to play this video with JS function, instead of autoplay, because autoplay is not supporting in IOS https://dev-visualshowcase.cvent.com/eventvideos.html - here you can check the problem
You can use the data-attribute to target a specific video
<button class="thumbnail" data-target="video_1">Play the video</button>
<video id="video_1" playsinline="" preload="auto" muted="" controls="" loop="">
<source src="https://dev-visualshowcase.cvent.com/VS/video/vd_intro/01.mp4" type="video/mp4">
</video>
Each time you click on the .thumbnail button, you use the data-target to choose your video
$('.thumbnail').click(function(){
let target = $(this).attr('data-target')
$('#' + target).trigger('play');
});

Having multiple instances of video.js javascript video player

I am using videojs as the framework for a JavaScript video player page I am working on, its working great & I have customised the playback controls which are inside a div to match the spec I wanted (hide controls on load & then only show when the user has clicked play and has hovered etc).
I am now trying to make sure that the video player works when there is multiple instances on 1 page i.e if I add 4 or 5 videos to a page. the basic video.js functionality features seems to work fine but the additional control functionality which I have implemented will only work on the first instance of the video on the page (& thats because its just standard JS looking for that class & theres no unique ID per video player).
Here is what I have for the HTML:
<div class="cb-article-media__container padding-top-sm padding-bottom-sm">
<div class="cb-article-media__video-block">
<div class="c-video-container">
<video id="videoPlayer" class="video-js vjs-default-skin video-cover" width="100%" height="100%" controls preload="none" poster="<?php echo esc_url($video_thumbnail_url); ?>"
data-setup='{}'>
<source src="http://clips.vorwaerts-gmbh.de/VfE_html5.mp4" type='video/mp4'/>
</video>
</div>
</div>
</div>
<div class="cb-article-media__container padding-top-sm padding-bottom-sm">
<div class="cb-article-media__video-block">
<div class="c-video-container">
<video id="videoPlayer" class="video-js vjs-default-skin video-cover" width="100%" height="100%" controls preload="none" poster="<?php echo esc_url($video_thumbnail_url); ?>"
data-setup='{}'>
<source src="http://clips.vorwaerts-gmbh.de/VfE_html5.mp4" type='video/mp4'/>
</video>
</div>
</div>
</div>
and here is the JS:
var videoContainer = document.querySelector('#videoPlayer');
var videoControl = document.querySelector('.vjs-control');
var timeDivider = document.querySelector('.vjs-time-divider');
var timeDur = document.querySelector('.vjs-duration');
var fullScrControl = document.querySelector('.vjs-fullscreen-control');
$(document.body).on('click', '.vjs-fullscreen-control' , function(){
if (videoContainer && videoContainer.classList.contains('vjs-fullscreen') ) {
fullScrControl.className += " exit-full-screen";
} else {
fullScrControl.classList.remove("exit-full-screen");
}
});
$(document.body).on('click', '.vjs-big-play-button' ,function(){
// if (videoContainer.hasClass('vjs-playing')) {
videoContainer.className += " show-controls";
// }
});
How would I be able to make this JS/Jquery above work per instance of video player on the page (to show and hide the controls per player)? At present it only works for the first video player on the page.
Any help would be really appreciated.
Here is a codepen to the same issue:
https://codepen.io/nolimit966/pen/LYVyVzz
Thank you
Your HTML is incorrect - you have multiple elements with the same ID - videoPlayer. Each ID must be unique in its home subtree (document).
To fix this issue give each player a unique id, e.g.
<video id="videoPlayer1" ...
<video id="videoPlayer2" ...
In JS you just need make sure that you are controlling the correct player. To do this you probably just need to get the elements based on the control that was clicked rather than hard coding them.
You don't show the actual page markup - so this is a guess - but you want something like the following using "closest".
$(document.body).on('click', '.vjs-fullscreen-control' , function(){
// note this is a guess, it could be $(this).parent, is the player you want.
var player = $(this).closest('.video-js')
if(player.classList.contains('vjs-fullscreen')) {
player.closest('.vjs-fullscreen-control').className += " exit-full-screen";
} else {
player.closest('.vjs-fullscreen-control').classList.remove("exit-full-screen");
}
});
In any case the principal remains the same - remove your hardcoded selectors and target the elements relative to the target of the click handler. If this doesn't work then please provide the full mark-up of a video player showing all the elements such as '.vjs-control' and '.vjs-fullscreen-control'

Run function on video element(among other videos) that just exited fullscreen

I have 8 videos on a page. on each video element i have add some things like sound control and description.
Specifically, the sound control mutes and umutes the video on click and also changes its icon accordingly. Hoever, when the video goes full screen, the browser uses its own controls for sound. So, for example if a user watches a video on mute, then goes full screen, and then turns on sound, and then exits full screen, the sound is still on but the sound control suggests it is not.
So i'd like to run a function every time any video on the page exits full screen, to update the sound icon.
Here's my html for the video element. I have 8 identical video elements on the page:
<div class="section-element video-mockup" onmouseenter="hoverIn($(this))" onmouseleave="hoverOut($(this))">
<video loop muted playsinline preload="metadata" class="video-onhover" controlsList="nodownload" onclick="clickPlay($(this))" ondblclick="toggleFullscreen(this)">
<source src="/wp-content/uploads/wysiwyg/webm/Video.webm" type="video/webm">
<source src="/wp-content/uploads/wysiwyg/webm/Video.mp4" type="video/mp4">
</video>
<div class="section-inner video-overlay">
<hr class="whiteLine">
<div class="videoControls">
<div class="overlay-columns description">
<p class="overlay-text"></p>
</div>
<div class="overlay-columns buttons">
<button class="videoButtons sound-button" title="Sound" onclick="toggleSound(this);"><ion-icon name="volume-off"></ion-icon></button>
<button class="videoButtons reset-button" title="Restart" onclick="expandVideo(this);"><ion-icon name="expand"></ion-icon></button>
</div>
</div>
</div>
</div>
So I am trying to update the <button class="videoButtons sound-button" title="Sound" onclick="toggleSound(this);"> on any video that exits fullscreen.
Here's my code for that:
$('video.video-onhover').on('fullscreenchange', function($this) {
var thisVideo = $this.target;
console.log(thisVideo);
var soundButton = thisVideo.parentElement.querySelector('button.sound-button');
if (thisVideo.muted) {
soundButton.innerHTML = '<ion-icon name="volume-off"></ion-icon>';
} else {
soundButton.innerHTML = '<ion-icon name="volume-high"></ion-icon>';
}
});
I added the console.log to see if the function is being called, but it doesn't seem to run. i am guessing there is something wrong with the fullscreenchange event but i can't find any other way. Any ideas?

Issue with video tag . poster is not visible after video call ends

Initially the poster is visible before video call start after video call ends i am able to see a black background in place of poster in video container.
below is the html tag that i have used for this purpose.
<div id="videoSmall">
<video id="videoInput" autoplay width="240px" height="180px" poster="img/webrtc.png"></video>
</div>
i have tried to reset "videoInput" div with this code
var tag = $("#videoInput").clone();
$("#videoInput").replaceWith(tag);
This code works and brings poster image back but the issue with this is when i am performing video call again without refreshing the page .. the poster is not vanishing in order to show video .
You can do this by adding ended eventListener to the video element, and call the video load() again.
Here is a working example: CodePEN
HTML:
<video id="video" width="320" height="240" controls poster="http://www.w3schools.com/images/w3html5.gif">
<source src="http://www.w3schools.com/html/movie.mp4" type="video/mp4">
<source src="http://www.w3schools.com/html/movie.ogg" type="video/ogg">
Your browser does not support the video tag.
</video>
JavaScript / jQuery:
var video= $('#video')[0];
var videoNew= $('#video');
videoNew.on('ended',function(){
video.load();
});

Multiple links that change the source of a video to other videos?

I'm trying to create multiple links that when clicked, will change the source of the video being played on the player.
So far I have something that does ALMOST what I want to achieve:
HTML:
<video id="videoclip" width="640" height="480" controls preload="none">
<source id="mp4video" src="myvideo.mp4?dl=1">
</video>
<p>first video</p>
<p>second video</p>
<p>third video</p>
<p>fourth video</p>
Javascript:
videocontainer = document.getElementById('videoclip');
videosource = document.getElementById('mp4video');
newmp4 = 'newvideo.mp4?dl=1';
videobutton = document.getElementById("videolink1");
videobutton.addEventListener("click", function(event) {
videocontainer.pause();
videosource.setAttribute('src', newmp4);
videocontainer.load();
videocontainer.play();
}, false);
This works great. The problem is, the way the code is written, it will only allow me to change the first video into the second one and that's it. I want to be able to click the other links (videolink2, videolink3, etc) and change what video is being played to something else.
I already spend many hours looking at many other questions here but wasn't able to achieve my goal.
You need to think dynamic in situations like this. What you did to get one working is a good first stepping stone.
Each video link now has a data- attribute that holds the new source for that link.
Each video link also has the same class that way we can group them together using document.getElementsByClassName("videolink") which returns an array of elements with the classname videolink
Then run a loop over the returned array (which is a link element with the classname videolink) and add a click event on each one that calls the changeVideo function
this inside changeVideo refers to the element that was clicked. So we grab the data-videolink value using dataset property on the link element that was just clicked
Finally change the source of the video to that value.
var videocontainer = document.getElementById('videoclip');
var videosource = document.getElementById('mp4video');
var videoButtons = document.getElementsByClassName("videolink");
for (var i = 0; i < videoButtons.length; i++) {
videoButtons[i].addEventListener("click", changeVideo, false);
}
function changeVideo() {
var newLink = this.dataset.videolink;
console.log("Changing video to source: " + newLink);
//videocontainer.pause();
//videosource.setAttribute('src', newLink);
//videocontainer.load();
//videocontainer.play();
}
<video id="videoclip" width="640" height="480" controls preload="none">
<source id="mp4video" src="myvideo.mp4?dl=1">
</video>
<p>first video</p>
<p>second video</p>
<p>third video</p>
<p>fourth video</p>

Categories