I have in my webpage a series of elements, for example videos or other media:
<div id = "text">
</div>
<video height="240" width="412" id="video" controls="controls"> </video>
I change with JavaScript the original status of these elements and I use
Popcorn.js for create a synchronization events, for example:
var video = document.getElementById('video');
video.src = $("#url").val(); //Change src value
var popcorn = Popcorn( "#video" );
popcorn.footnote({ //Create a synchronization event; I add a footnote
start: 2,
stop: 5,
text: 'Hello World!!!',
target: 'text',
});
So now, my problem is that I want save these elements with their events.
And after I want to have the possibility to load (in the my webpage) this elements for continue to change them again.
How can I save/load in this case?
Related
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 read video path using javascript and pass it to html source value. Currently I am using hard coded from my html to read video and I want it to be dynamic to javascript. Here is my Temporary loading from content folder in my project:
<video id="video" controls preload="metadata" style="width:100%; height:100%">
<source src="~/Content/Videos/Sample_Vid.mp4" type="video/mp4">
</video>
If I understand your question correctly then you could:
implement a function like setVideoSource() as shown below, which would allow you to set/change the source of a video element that already exists in your page or,
implement a function like addVideo() as shown below, which would allow you to dynamically create/add a new video element to your page with a source of your choosing
Please see the documentation below for detail on how both functions work:
/*
Updates the source of first video in the document matching the selector
*/
function setVideoSource(selector, src) {
const element = document.querySelector(selector);
/*
Check that element is video before proceeding
*/
if(element.nodeName === 'VIDEO') {
/*
If element is a video, remove any source children if present
*/
for(const source of element.querySelectorAll('source')) {
element.removeChild(source);
}
/*
Create a new source element and populate it with the src
attribute
*/
const source = document.createElement('source');
source.setAttribute('src', src);
/*
Add source element to the video we're updating
*/
element.appendChild(source);
}
}
/*
Adds a new video to the document under the first element matching the parentSelector
*/
function addVideo(parentSelector, src, width, height) {
const parent = document.querySelector(parentSelector);
/*
Check that parent exists before proceeding
*/
if(parent) {
/*
Create new video element
*/
const video = document.createElement('video');
video.setAttribute('controls', true);
if(width) {
video.setAttribute('width', width);
}
if(height) {
video.setAttribute('height', height);
}
/*
Create a new source element and populate it with the src
attribute
*/
const source = document.createElement('source');
source.setAttribute('src', src);
/*
Add source element to the video we're inserting and add
the video element to the document element
*/
video.appendChild(source);
parent.appendChild(video);
}
}
// Update source of existing video
setVideoSource('#video', 'https://www.w3schools.com/html/mov_bbb.mp4')
// Add a new video to the page
addVideo('#parent', 'https://www.w3schools.com/html/mov_bbb.mp4', '100%', '150px')
<h3>Existing video dynamically updated with JavaScript</h3>
<video id="video" controls preload="metadata" style="width:100%; height:100%">
<source src="~/Content/Videos/Sample_Vid.mp4" type="video/mp4">
</video>
<h3>New video dynamically added to page with JavaScript</h3>
<div id="parent">
</div>
Hope that helps!
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();
}
})
<script src="jquery.js"></script>
<video id="video" controls preload="none" width="640" poster="http://media.w3.org/2010/05/sintel/poster.png" onloadedmetadata="$(this).trigger('video_really_ready')">
<source id='mp4' src="http://media.w3.org/2010/05/sintel/trailer.mp4" type='video/mp4' />
<source id='webm' src="http://media.w3.org/2010/05/sintel/trailer.webm" type='video/webm'/>
<source id='ogv' src="http://media.w3.org/2010/05/sintel/trailer.ogv" type='video/ogg' />
</video>
<br />
<input type="button" id="capture" value="Capture" /> Press play, and then start capturing
<div id="screen"></div>
<script>
var VideoSnapper = {
/**
* Capture screen as canvas
* #param {HTMLElement} video element
* #param {Object} options = width of screen, height of screen, time to seek
* #param {Function} handle function with canvas element in param
*/
captureAsCanvas: function(video, options, handle) {
// Create canvas and call handle function
var callback = function() {
// Create canvas
var canvas = $('<canvas />').attr({
width: options.width,
height: options.height
})[0];
// Get context and draw screen on it
canvas.getContext('2d').drawImage(video, 0, 0, options.width, options.height);
// Seek video back if we have previous position
if (prevPos) {
// Unbind seeked event - against loop
$(video).unbind('seeked');
// Seek video to previous position
video.currentTime = prevPos;
}
// Call handle function (because of event)
handle.call(this, canvas);
}
// If we have time in options
if (options.time && !isNaN(parseInt(options.time))) {
// Save previous (current) video position
var prevPos = video.currentTime;
// Seek to any other time
video.currentTime = options.time;
// Wait for seeked event
$(video).bind('seeked', callback);
return;
}
// Otherwise callback with video context - just for compatibility with calling in the seeked event
return callback.apply(video);
}
};
$(function() {
$('video').bind('video_really_ready', function() {
var video = this;
$('input').click(function() {
var canvases = $('canvas');
VideoSnapper.captureAsCanvas(video, { width: 160, height: 68, time: 40 }, function(canvas) {
$('#screen').append(canvas);
if (canvases.length == 4)
canvases.eq(0).remove();
})
});
});
});
</script>
How can I add youtube video instead. Could not play youtube video in video tag. embed tag is working to play youtube video. How to take screenshot by placing youtube video inside embed tag. Please help me
I could solve this with ffmpeg.
Just run
ffmpeg -i inputfile.avi -r 1 -t 1 -ss 00:00:03 image-%d.jpeg
where
-i inputfile.avi - input file
-r 1 - one frame per second
-t 1 - how many seconds should be converted to images
-ss 00:00:03 - from what second to start
image-%d.jpeg - resulting filename template
Found here http://linuxers.org/tutorial/how-extract-images-video-using-ffmpeg
The following bookmarklet capture a Youtube video at click time, in the current video resolution and quality, as you are seeing it, but without the toolbars overlays.
javascript:void(function(){let canvas=document.createElement("canvas"),video=document.querySelector("video"),ctx=canvas.getContext("2d");canvas.width=parseInt(video.offsetWidth),canvas.height=parseInt(video.offsetHeight),ctx.drawImage(video,0,0,canvas.width,canvas.height);var base64ImageData=canvas.toDataURL("image/jpeg"),o = new Date(0),p = new Date(video.currentTime*1000),filename="📷Capture_"+new URL(document.location.href).searchParams.get("v")+"_"+document.title+"#"+new Date(p.getTime()-o.getTime()).toISOString().split("T")[1].split("Z")[0]+".jpg",a=document.createElement("a");a.download=filename,a.href=base64ImageData,a.click()}());
Enhancement of the bookmarklet found here https://github.com/ReeganExE/youtube-screenshot.:
Image served as file download.
Does not block the playing video.
The image title contains the Youtube ID, the video title, and the exact time of the capture in the video.
Modified to work also in Firefox
If manually set up image this might be help you.
Try add poster="placeholder.png" //photo you want to the video tag.
example
<video width="470" height="255" poster="placeholder.png" controls>
<source src="video.mp4" type="video/mp4">
<source src="video.ogg" type="video/ogg">
<source src="video.webm" type="video/webm">
<object data="video.mp4" width="470" height="255">
<embed src="video.swf" width="470" height="255">
</object>
</video>
I am working on an HTML5 video player with jQuery. For now I have my video player working very well but I want to get the variable for the video duration and show/display it in pure HTML page.
So from here you can take more info about this Jquery video player:
http://www.videojs.com/docs/api/
I think the variable for video duration is: myPlayer.duration();
How I can display this value in HTML?
Here is my HTML code to display the player:
<video id="vemvo-player" class="video-js vjs-default-skin" controls autoplay="true" width="950" height="534"
data-setup="{}">
<source src="[var.base_url]/uploads/[var.video_play]" type='video/flv' />
</video>
This is what I have tried to display this variable but it says that it is = "0" when on the video player it says that it's 4min:
<video id="vemvo-player" class="video-js vjs-default-skin" controls autoplay="true" width="950" height="534"
data-setup="{}">
<source src="[var.base_url]/uploads/[var.video_play]" type='video/flv' />
</video>
<div id="duration"></div>
<script type="text/javascript">
_V_("vemvo-player").ready(function(){
var myPlayer = this;
var howLongIsThis = myPlayer.duration();
$('#duration').html('Duration: ' + howLongIsThis);
});
</script>
Where is my mistake?
You can try this. It works for me.
var myPlayer = videojs('vemvo-player');
if (myPlayer.readyState() < 1) {
// wait for loadedmetdata event
myPlayer.one("loadedmetadata", onLoadedMetadata);
}
else {
// metadata already loaded
onLoadedMetadata();
}
function onLoadedMetadata() {
alert(myPlayer.duration());
$('#duration').html("Duration: " + myPlayer.duration());
}
var player = videojs('my-video', {
fluid:false, // videojs settings
controls:true,
height: '300'
});
$(document).ready(function(){
console.log(player.duration());
// will return video duration. Can't be used while page is loading.
console.log(player.currentTime());
// will return current time if video paused at some time. Intially it would be 0.
});
Those who might come here and are using videojs with Vue 3, also might work with similar frameworks like React.
Referring to this code and component usage - https://docs.videojs.com/tutorial-vue.html you can do the following changes to get the duration, height, and width.
// New Code here
this.player = videojs(
this.$refs.videoPlayer,
this.options,
function onPlayerReady() {
console.log("onPlayerReady", this);
}
);
this.player.one("loadedmetadata", () => {
var duration = this.player.duration();
console.log(`Duration of Video ${duration}`);
console.log(`Original Width of Video ${this.player.videoWidth()}`);
});
I was having troubles to get the real duration of videos (using videojs v7.18.*) resulting in bugged custom progressbar! The problem was that player.duration() always returns rounded number while player.liveTracker.seekableEnd() returns the real value but only after start event.
For example, if real duration is 13.456s, these values are returned for videojs player object p:
| On ready | On load | On start
----------------------------|-------------|---------|----------
p.duration() | 0 | 14 | 14
p.liveTracker.seekableEnd() | 14 | 14 | 13.456
I've ended up with this solution in React:
const onDurationChange = () => {
const dur = player?.liveTracker.seekableEnd() || player?.duration() || 0;
setDurationInSec(dur);
}
return <video ref={videoRef} onDurationChange={onDurationChange}>
As you're using jQuery, that can be done much easier :) You can use $.html to edit the html contents of a dom element. Your code will look something like this:
<div id="duration"></div>
<script type="text/javascript">
_V_("vemvo-player").ready(function(){
var myPlayer = this;
var howLongIsThis = myPlayer.duration();
$('#duration').html('Duration: ' + howLongIsThis);
});
</script>