I have a popup that contains a video with empty source attributes.
<div id="event-popup">
<video width="320" height="240" controls id="event-popup-video">
<source src="" type="video/mp4" id="epv-mp4"></source>
<source src="" type="video/ogg" id="epv-ogg"></source>
</video>
</div>
This is used for multiple Leaflet map markers the a user can click on, which will trigger the popup to appear and then inject the correct src attribute based on the id of the clicked item.
var marker = L.marker(new L.LatLng(a.lat, a.lon), {
alt: a.cartodb_id,
icon: starIcon,
clickable: true
}).on('click', onClick);
The onClick function displays the popup and injects the correct src file location (S3 bucket item) into the .
function onClick(e){
// other code to display popup
showChangeEventVideo(e.target.options.alt);
}
function showChangeEventVideo(id){
$("#epv-mp4").attr("src", "s3_URL_based_on_ID.mp4");
$("#epv-ogg").attr("src", "s3_URL_based_on_ID.ogg");
}
The code executes, displays the popup, and inserts the correct src URL into the , but doesn't show the video. I can hard code a video URL into the HTML src attribute and the video appears.
Simply need to add .load() at the end of each .attr() call to force the source to refresh itself.
Related
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'
I know that I can to pass controls="false" to not show controls, text-boxes and any other stuff from videojs, but that only hide that elements. I want to know how to remove completely all the elements added by videoJS from DOM.
Vidoe JS has the following HTML for the control box so
<div class="vjs-control-bar" dir="ltr"></div>
As per your question I take it its the controls you want to delete.So to delete it
let controlbar = document.querySelector(".vjs-control-bar");
controlbar.parentNode.removeChild(controlbar);
This should remove the control bar from your video. You can do the same for the context menu on the video etc
Then you would also have to change
<video id="preview-player_html5_api" preload="auto" crossorigin="anonymous" class="vjs-tech" playsinline="playsinline" tabindex="-1" role="application" poster="//vjs.zencdn.net/v/oceans.png" src="//vjs.zencdn.net/v/oceans.mp4" loop=""></video>
and removecontrols tag from the html tag
I have used a slide show on my web site. There are a couple of images and a video. I have not enabled any shadow elements or controls for this video, however there is a custom button to open it externally and I cannot disable it in any ways.
I have tried different JS scripts to attach a shadow and set the mode on closed, but I get the error that this video element cannot have an attached shadow.
Here's the button I am talking about
An example script that I have used:
function makeShadowTree(shadowClose) {
var root = shadowClose.attachShadow({mode: 'closed'});
}
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('.slides--i').forEach(makeShadowTree);
});
<div class="slides">
<div class="slides--i" id="slide--1"></div>
<div class="slides--i" id="slide--2"></div>
<video autoplay muted loop class="slides--i" id="slide--video">
<source src="img/slides/slide-03-video.mp4" type="video/mp4">
</video>
</div>
I have an HTML 5 video inside my page and I would like to set the src dynamically.
I'm using vue, inside my js controller I set a variable with the video path then I use the variable in my page as below:
<video width="450" controls>
<source v-model="controller.var" v-bind:src="var" type="video/mp4">
</video>
The player doesn't load the video but my var is properly set with the right url.
What I'm missing here?
Thanks
Adding the key attribute with the source's URL to the video element will cause both video and source to be updated when the URL changes:
<video
:key="video.mp4"
width="450"
controls
>
<source
:src="video.mp4"
type="video/mp4"
>
</video>
This supports dynamic replacement of a video + source.
First, I don't know if you are actually using var in your template, but if you are, Vue will throw a warning in the template.
avoid using JavaScript keyword as property name: "var" in expression :src="var"
Second, you cannot dynamically change the source element.
From the HTML5 specification,
Dynamically modifying a source element and its attribute when the
element is already inserted in a video or audio element will have no
effect. To change what is playing, just use the src attribute on the
media element directly, possibly making use of the canPlayType()
method to pick from amongst available resources. Generally,
manipulating source elements manually after the document has been
parsed is an unnecessarily complicated approach.
So, bind your data to the src attribute of the video element.
<video width="450" controls :src="video"></video>
console.clear()
new Vue({
el:"#app",
data:{
video: "https://www.w3schools.com/tags/movie.mp4"
},
methods:{
changeVideo(){
this.video = "http://techslides.com/demos/sample-videos/small.mp4"
}
}
})
<script src="https://unpkg.com/vue#2.2.6/dist/vue.js"></script>
<div id="app">
<video width="450" controls :src="video"></video>
<div>
<button #click="changeVideo">Change</button>
</div>
</div>
If you need to change the src dynamically, you can change the src and load the new src with the .load() function.
new Vue({
el:"#app",
data:{
src: ""
},
methods:{
changeVideo(newSrc){
this.$data.src = newSrc;
//Force video load.
var vid = this.$refs.video;
vid.load();
}
}
})
<script src="https://unpkg.com/vue#2.2.6/dist/vue.js"></script>
<div id="app">
<video width="450" controls :src="src" ref="video"></video>
<div>
<button #click="changeVideo('http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4')">Change1</button>
<button #click="changeVideo('https://www.w3schools.com/tags/movie.mp4')">Change2</button>
</div>
</div>
Try setting the entire source as variable in the controller.
<video controls autoplay>
{{{ src }}}
</video>
new Vue({
el: '#app',
data: {
src: '<source src="#url" type="video/mp4">'
}
})
Im using a flexslider that has audio files for each slide, but I don't want to load countless audio files right away on the page. So im trying to get the data-src to become the src after each slide
the slides are currently as follows:
<div class="flexslider carousel">
<ul class="slides">
<li>
<img src="http://www.quinnmedical.com/skin/frontend/gigasavvy/quinn/ppt/Slide01.jpg" />
<audio id="demo" controls>
<source src="/skin/frontend/gigasavvy/quinn/audio/Slide1.mp3" type="audio/mpeg" />
</audio>
</li>
<li>
<img src="http://www.quinnmedical.com/skin/frontend/gigasavvy/quinn/ppt/Slide03.jpg" />
<audio id="demo" controls>
<source data-src="/skin/frontend/gigasavvy/quinn/audio/Slide3.mp3" src="" type="audio/mpeg" />
</audio>
</li>
</ul>
</div>
In the after function i want to change data-src to src. Any help would be greatly appreciated as how to go from data-src to src
Renaming an attribute is not be possible. You can add new attribute and remove the old one.
Suppose there is a click event as in the following example:
$('#demo').on("click", "img", function () {
var t = this;
var source = $(t).children("source");
$source.attr({
src: $t.attr('data-src')
}).removeAttr('data-src');
}
Please modify the event according to your requirements.
Try this:
$('source').attr("src", $(this).data('src'));
$('source').removeAttr('data-src');
This should move the url from data-src to src, and then remove the data-src attribute.
Inside the after function get the currently visible slide and then get the auto on it and it's source. Next check to see if it already has a src attribute. If not then set it to it's own .data('src'). Add this into the flexslider object.
after: function(){
var $currentAudio = $('.flex-active-slide audio source');
if(!$currentAudio.attr('src')){
$currentAudio.attr('src', $currentAudio.data('src'));
}
}