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
anddelete
. - 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>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
If any one knows, please explain how I can perform those logic? Since all the actions are dynamic, can i use javascript method here?
CodePudding user response:
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>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
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 > <div > <div > <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>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
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!