Change HTML 5 autoplayed video source dynamically - javascript

On my website https://cravydev.netlify.com I'm trying to change the video dynamically when the different headlines are in viewport.
I'm using a div with HTML 5 autoplay and loop properties, but not able yet to change the video source and load again when the specific headline is on screen. Here are the details.
HTML
<div class="iphone-sticky"></div>
<div class="iphone-video">
<video autoplay loop muted poster="assets/img/poster.png" id="iphonevideo">
<source id="video1" src="assets/img/iphone-video.mp4" type="video/mp4">
<source id="video2" src="assets/img/iphone-video-1.mp4" type="video/mp4">
</video>
JS
//Detect is element is in viewport
$(window).on('resize scroll', function() {
var player = document.getElementById('iphonevideo2');
if ($('#headline2').isInViewport()) {
var source = document.getElementById('video1');
$(source).attr("src", "assets/img/iphone-video-1.mp4");
player.pause();
player.load();
} else if ($('#headline3').isInViewport()) {
var source = document.getElementById('video1');
$(source).attr("src", "assets/img/iphone-video.mp4");
player.pause();
player.load();
}
});
EDIT
I have been able to solve it thanks to Kley comment. Now the problem is that the js logic does not check constantly the viewport visibility of headlines, only once. Also, the video is played while scrolling and the poster image appears, making the whole experience a little bit weird.
Any suggestion to solve that?
Thanks!

Check the page, it's not the viewport ()
I could tell you that you are changing the src every time you scroll while it is visible, this is causing the video to restart. You must make a validation, if it has already been changed the src should not be changed again.
Note that # headline2 is not visible when # headline3 is a bit up.
you have to scroll down until the end of the page to enter this condition.
You could use another smaller element at the beginning of each #headline to do this validation.
you could use the first p of the #headline
For example:
$(window).on('resize scroll', function() {
var player = document.getElementById('iphonevideo2');
if ($('#headline2 p').eq(0).isInViewport()) {
var source = document.getElementById('video1');
var url = "assets/img/iphone-video-1.mp4";
var src = $(source).attr("src");
// validate if you already have the src
if(src==url) return; // if exists src leaves function
$(source).attr("src", url);
player.pause();
player.load();
} else if ($('#headline3 p').eq(0).isInViewport()) {
var source = document.getElementById('video1');
var src = $(source).attr("src");
var url = "assets/img/iphone-video.mp4";
// validate if you already have the src
if(src==url) return; // if exists src leaves function
$(source).attr("src", url);
player.pause();
player.load();
}
})

Related

Using 'this.currentTime' to get the time of a video and reset it to the starting point on 'hover out'

I have a video library where I want to dynamically use the Media Fragment time in URL as the poster.
When hovering out, I am trying to reset the video to the initial start - to make sure the poster is at 2 seconds (in this specific example) instead of 0.
this.load works but creates a bad user experience as the whole video loads in again.
My idea is to define the current time as a variable (before the video starts playing) and use it when pausing the video.
However I just get "Uncaught ReferenceError: posterTime is not defined".
<video id="video">
<source src="videourl.mp4#t=2" type="video/mp4">
</video>
const videos = document.querySelectorAll("video")
videos.forEach(video => {
video.addEventListener("mouseover", function () {
var posterTime = this.currentTime;
this.currentTime = 0;
this.play()
})
video.addEventListener("mouseout", function () {
this.currentTime = posterTime;
this.pause();
})
})
Note that I use Webflow and is not very strong with jQuery/Javascript.
My idea is to define the current time as a variable (before the video
starts playing) and use it when pausing the video. However I just get
"Uncaught ReferenceError: posterTime is not defined".
Your idea and code is fine but you made a basic mistake.
Remember: A variable defined inside a function will exist only for that function where it was created.
Use let for internal variables (where possible) and use var for global variables.
solution: Define the variable as global (outside of any functions)...
const videos = document.querySelectorAll("video");
var posterTime = -1; //# global var, with starting value...
videos.forEach(video => {
video.addEventListener("mouseover", function ()
{
posterTime = this.currentTime; //# set time
this.currentTime = 0;
this.play()
})
video.addEventListener("mouseout", function ()
{
this.currentTime = posterTime; //# get time
this.pause();
})
})
As I hover out I need it to show that initial frame again (not the first frame, but the one set in the URL)
Given this requirement you can retrieve the fragment from the URL in the src attribute of the source element and apply it to the currentTime of the video when the mouseleave event occurs:
const videos = document.querySelectorAll("video")
videos.forEach(video => {
video.addEventListener("mouseenter", function() {
this.currentTime = 0;
this.play()
})
video.addEventListener("mouseleave", function() {
let src = this.querySelector('source').src;
let time = (src.split('#')[1] || 't=0').split('=')[1];
this.currentTime = time;
this.pause();
})
})
<video id="video">
<source src="http://grochtdreis.de/fuer-jsfiddle/video/sintel_trailer-480.mp4#t=5" type="video/mp4">
</video>

Randomize Background Video with Sound, after clicking function

I wrote this code a while back, and it allowed users to click and refresh the page to autoplay a RANDOM background video with sound.
This is the function that they click that loads the function
https://pastebin.com/0XXEHvQQ
<div align="center">
<p><font face="verdana" size="2">
<a onclick="ok()"> press me PLAY VIDS :)</a></font></p>
</div>
https://pastebin.com/PD5qdNDM
<div align="center">
<p><font face="verdana" size="2">
<a onclick="ok()"> -> press me to fix the site :) <-</a></font></p>
</div>
</div>
</div>
</div>
<!-- Scripts -->
<script src="js/parallax.js"></script>
<script>
// Pretty simple huh?
var scene = document.getElementById('scene');
var parallax = new Parallax(scene);
</script>
</script>
<script src="js/custom.js"></script>
<script>
let volumeInterval;
function loaded(){
setInterval(loop, 600);
volumeInterval = setInterval(volume, 1);
}
function unload(){
for (var i = 1; i < 99999; i++)
window.clearInterval(i);
console.log("unloaded");
}
function volume() {
try {
document.getElementsByTagName("video")[0].volume = 0.15;
console.log("done!");
clearInterval(volumeInterval);
}
catch (e) {
console.log("waiting..");
}
}
function ok() {
document.write(unescape(
and heres the unescaped code
https://pastebin.com/YJwbG2mC
<!-- VIDEO GRABBB -->
<video preload="auto" autoplay="true" loop="true">
<source id="player" src="5.mp4">
<script>
var video = document.currentScript.parentElement;
video.volume = 0.33;
//document.getElementById('player').currentTime = 20;
</script>
<script>
var video = document.getElementById("player");
video.addEventListener("timeupdate", function(){
if(this.currentTime >= 1000) {
location.reload();
}
});
</script>
<script type="text/javascript">
var video = document.getElementsByTagName('video')[0];
video.onended = function() {
location.reload();
};
</script>
<script>
document.getElementById("player").src = "/" + Math.floor((Math.random()*7)+1) + ".mp4";
</script>
</video>
No matter how I try to adjust the unescaped code, I can't get the MP4 to autoplay after clicking the function.
Here is my live site that I no longer can access: form.wtf
According to the HTML Spec on the Source Element,
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.
Therefore, no matter what you do to the source element, you can't change the video unless the new src is applied directly to the video element.
Replacing the source element also has no effect on the video that plays. The source element's src attribute may changed but the video will keep on playing.
Therefore, you should leave your source's src attribute empty until the JavaScript code sets it or
Leave out the source tag all together and apply the src straight to the video.
Math.floor(Math.random() * 7 + 1); is exactly the same thing as Math.ceil(Math.random() * 7);
document.querySelector('#player > source').src = `/${Math.ceil(Math.random() * 7)}.mp4`;
<video id="player" preload="auto" autoplay loop>
<source src="">
</video>

How do I make a random video play on pageload?

I'm trying to make a random video player in html/js.
It is supposed to play a different video on pageload and as soon as one video is over, it should play another one.
HTML
<video width="320" height="240" autoplay>
<source src="abcdefg.com/example1.mp4" type="video/mp4">
<source src="abcdefg.com/example2.mp4" type="video/mp4">
</video>
JS
<script>
var videos = [
[{type:'mp4', 'src':'abcdefg.com/example1.mp4'}],
[{type:'mp4', 'src':'abcdefg.com/example2.mp4'}],
];
$(function() {
var number = Math.floor(Math.random()*videos.length);
$(this).find('source').each(function(index){
videoSrc = videos[number][index].src;
$(this).attr('src', videoSrc);
$('video').load();
$('video').play();
});
});
</script>
However, my current code plays the same video every page reload and as soon as it's over, nothing happens.
How do I need to optimize my code so it automatically plays a different video on every pageload + when the previous video is over?
Try this,I have added an event listener to video end property and called the newvideo() function ,so that every time the video finishes a new random video is loaded from array.I could'nt find more video urls ,you can test and let me know if it works for you.
$(document).ready(function(){
var videos = [
[{type:'mp4', 'src':'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4'}],
[{type:'mp4', 'src':'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4'}],
[{type:'mp4', 'src':'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4'}]
];
// selecting random item from array,you can make your own
var randomitem = videos[Math.floor(Math.random()*videos.length)];
// This function adds a new video source (dynamic) in the video html tag
function videoadd(element, src, type) {
var source = document.createElement('source');
source.src = src;
source.type = type;
element.appendChild(source);
}
// this function fires the video for particular video tag
function newvideo(src)
{
var vid = document.getElementById("myVideo");
videoadd(vid,src ,'video/ogg');
vid.autoplay = true;
vid.load();
//vid.play();
}
// function call
newvideo(randomitem[0].src)
// Added an event listener so that everytime the video finishes ,a new video is loaded from array
document.getElementById('myVideo').addEventListener('ended',handler,false);
function handler(e)
{
newvideo(randomitem[0].src)
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<video width="320" height="240" autoplay id="myVideo">
</video>

How to replace src= "name1" with src="name2"?

everybody!
i have an idea, but I don't know how to implement it.
how to make sure that when you press ctrl + shift + i also on the f12 key changed a certain part of the html code?
for example: SRC="video.MP4 "on SRC=" error.MP4
Thanks!
update -9.24.18
you need to make it so that the user was difficult to copy the link from scr="video.mp4"
-Aison
Here's one way you could do this:
<video id="someVideo" src="somfile.mp4" />
<script>
function KeyPress(e)
{
var evtobj = window.event ? event : e;
// 73 = i
if (evtobj.keyCode == 73 && evtobj.ctrlKey && evtobj.shiftKey)
{
document.getElementById('someVideo').src = "error.mp4";
}
}
// On keypress, activate our function
document.onkeydown = KeyPress;
</script>
However, as I mentioned in the comments this will in no way prevent users from downloading your mp4 file.
Users can still:
Right click, inspect element
Hit f12
Have the 'inspect element' open before visiting your website
Save your webpage
Save just the video from your webpage
Disable JS / override your JS.
Access your webpage without the use of a webbrowser (GET/save your webpage)
There are other ways as well, that's just off the top of my head.
Edit following comments:
You could instead use an html5 <canvas>.
This will hide the source. However, it will cause the video to no longer work if the user has JS disabled.
Example (you'll have to either add your own play button, or change the script to start the video automatically):
<!-- You can hide this element anywhere in your hmtl. It will not be visbile (via CSS) -->
<!-- note: I used `muted="muted"` because otherwise you will get an error when starting the video without a user action -->
<video id="someVideo" muted="muted" controls>
<source src="http://clips.vorwaerts-gmbh.de/VfE_html5.mp4" type="video/mp4">
</video>
<!-- canvas will display the video -->
<canvas id="myCanvas"></canvas>
<script>
document.addEventListener('DOMContentLoaded', function()
{
var hiddenVideo = document.getElementById('someVideo');
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var cw = Math.floor(canvas.clientWidth);
var ch = Math.floor(canvas.clientHeight);
canvas.width = cw;
canvas.height = ch;
hiddenVideo.addEventListener('play', function(){
draw(this,context,cw,ch);
},false);
hiddenVideo.onloadstart = function(){
this.play();
};
},false);
function draw(v,c,w,h)
{
if(v.paused || v.ended)
return false;
c.drawImage(v,0,0,w,h);
setTimeout(draw,20,v,c,w,h);
}
</script>
<style>
#someVideo
{
display: none;
width: 200px;
height: 200px;
}
#myCanvas
{
width: 200px;
height: 200px;
}
</style>
Since you're giving the mp4 file to the user, you cannot prevent the user from having the mp4 file.

Start playing HTML5 Video only after the complete video is buffered

Is there a way I can start playing my HTML5 MP4 video only after the entire video is buffered (100%). When it is in the process of buffering, I should display the Loading screen. Please help. This code should work in both Firefox and IE11.
Hyperlink Titles Example :
- Play Video1: Fav Foods - Play Video1: Fav Veg - Play Video2: Fav Animal
And here is the code I have when I click on the hyperlink and also the Video tags. I load the video dynamically from the database. The attribute 'pos' tells the time in seconds where the player has to seek playing.
<video id="VideoContainer" controls="controls" style="width:500px;height:320px" preload="auto">
<source id="VideoData" src=#Model.IntroVideoPath type="video/mp4" />
Your browser does not support the video tag.
<a onclick="navVideo('#items.FileName','#items.StartSec');">#items.DisplayText</a>
function navVideo(fileName, pos) {
//Get Player and the source
var player = document.getElementById('VideoContainer');
var mp4Vid = document.getElementById('VideoData');
var mp4CurVid = $(mp4Vid).attr('src');
//Reload the player only if the file name changes
if (mp4CurVid != fileName) {
$(mp4Vid).attr('src', fileName);
player.load();
player.play();
if (pos != 0) {
setTimeout(function () {
player.currentTime = pos;
player.play();
}, 1000);
}
}
else {
player.pause();
player.currentTime = pos;
player.play();
}
The problem was with the encoding technique for that MP4 file. I encoded with different settings (random settings options for Mp4) and finally got that to work without buffer.
You could use the this http://videojs.com/ to get that to work.

Categories

Resources