I'm working on a Squarespace website, and they don't allow video upload, so I'm using Dropbox to host a video.
The video starts playing, but he is not repeating.
This is the code:
<video id="htmlVideo" loop="loop">
<source type="video/mp4" src="https://www.dropbox.com/s/videoID/videoplayback.mp4?dl=1">
</video>
What could be the problem?
This is how I create the video
/*
function repeatForDropbox() {
console.log("repeatForDropbox caled" + htmlVideo );
}
*/
function createVideo() {
var video = document.createElement("video");
video.id = "htmlVideo";
video.loop = "loop";
var vidSource = document.createElement("source");
vidSource.type = "video/mp4";
vidSource.src = "https://www.dropbox.com/s/videoID/videoplayback.mp4?dl=1";
video.appendChild( vidSource );
var vidLocation = document.querySelector('#location').parentNode;
vidLocation.appendChild( video );
htmlVideo = document.querySelector(" #htmlVideo ");
// on load, play the video/mp4
window.onload = function () {
setTimeout(function() {
htmlVideo.play();
// htmlVideo.addEventListener("ended", repeatForDropbox);
// I tried here to make the video repeat, using the "ended" event listener
// so when the video ended, the video
// should get another <source> element(same src)
// and delete the old one
// but the event didn't fire
// I also tried htmlVideo.onended = function() {} , but same result
}, 500);
}
}
Just a guess, but I suspect this relates to redirects. A Dropbox share link with ?dl=1 on it will redirect you to a one-time use URL to download the content. Perhaps when the video player tries to loop, it tries to access the target of the redirect again.
This might show up in the network traffic from the browser, so it's worth taking a look. (E.g. the network tab of Chrome inspector, if you're using Chrome.)
I would see if squarespace will let you save the binary of the video into a text file and then import it with AJAX and save it to indexedDB before converting it to video.
Here's some links:
Display a video from a Blob Javascript
https://simpl.info/video/offline/
Just in case anyone still needs the solution, I found a workaround using jQuery:
$('video').on('ended', function () {
this.load();
this.play();
});
However, there is a slight delay between repeats!
Related
How to reload video on page if I change src file on disk?
For example, I have
<video controls="controls" id="myVideo">
<source id="source" src="~/videos/Intro.mp4" type=video/mp4 />
</video>
On disk I replace file Intro.mp4 to another video with same name.
If I use $("#myVideo").load() , it happens nothing. When I refresh page, in Opera my video does not changes, in Edge it reloads. I need to reload video without refresh page.
UPD: In some reasons I cannot use files with different names, I need to use only Intro.mp4 name
If you're only changing the file and keeping the same file name it is very likely that the browser is caching the old video. If you want to change the video without reloading you will need both videos on the disk in the same location. ~/videos/Intro1.mp4 and ~/videos/Intro2.mp4 for example.
The you can change the source of the video using JQuery.
$('#myVideo source').attr('src', '~/videos/Intro2.mp4');
Once the source is changed you can run $("#myVideo")[0].load(); to change the video playing without reloading the page.
I am reloading the video on error. When the replacing takes place, and i change the frame of the video an error occurs (e.g. Error 3; details: PIPELINE_ERROR_DECODE: VDA Error 4), so this is when i reload the video.
var video = $('#myVideo')[0];
var hadError = false;
video.onerror = function () {
console.log('Error ' + video.error.code + '; details: ' + video.error.message);
hadError = true;
video.load();
};
video.addEventListener('loadeddata', function() {
if(hadError) { video.onerror = null; }
});
For some reason in Chrome I can't set the currentTime property of the audio tag. I can alert the currentTime and it displays correctly but when I try to set the currentTime it reverts to zero. There is an event listener on a progress bar which triggers the alert shown below. It always displays as zero. In FireFox and IE the alert works just fine. What's the problem with Chrome?
$(document).ready(function(){document.getElementById('progressBar').addEventListener(
'click',
function(e) {
document.getElementById("audio_id_1").currentTime = 10;
alert(document.getElementById("audio_id_1").currentTime);
...
...
<audio id="audio_id_1" preload="metadata">
<source src="test.mp3" type="audio/mp3" />
</audio>
My chrome can seek "local" audios and videos well, whose source urls start wich "blob:"
So I solved this in such the redundant way:
download the whole media (XMLHttpRequest);
get the blob url (URL.createObjectURL);
change the source url of the media
function makeChromeSeekable(){
var player = document.getElementById("thevideo")
var uReader = new XMLHttpRequest()
uReader.open ('GET', player.src, true)
uReader.responseType = 'blob'
uReader.onload = () => {
player.src = URL.createObjectURL(uReader.response)
}
uReader.send()
}
makeChromeSeekable()
PS: The video files mignt be too large for downloading, but audio files should always be feasible.
PS. I used to believe that blob data has to be converted as data(File.getDataURL), but now using blob urls is ok seems more convenient.
In a Django website I've built, users can add videos for others to see and comment on. Not all users have devices that support video playback, and thus for such edge cases, I want to allow video download.
To do this, I first need to detect whether the video failed or not. How can I do that? I have a working solution below, but with issues I need to resolve.
Currently I'm trying the following in my Django template (where all videos are listed using a ListView). This actually works, but breaks down if I reload the page:
<script>
var videos = document.querySelectorAll('video');
for (var i = 0; i < videos.length; i++) {
(function() {
var v = videos[i];
var s = v.querySelector('source');
//console.log(source);
s.addEventListener('error', function(ev) {
var d = document.createElement('div');
d.innerHTML = v.innerHTML;
console.log("hello")
console.log(v);
v.parentNode.replaceChild(d, v);
}, false);
}());
}
</script>
I.e. first I go through all video tags in the HTML page, then for each tag, I look up the source tag inside. Next, I try to add an event listener to the source tag, catch the error, and do some processing. However, I've found that the event listener is not fired if I reload the page. Maybe the event handler is being added too late; i.e. the browser already attempted to access the video source before the event handler was added. Can someone help me out here? Thanks in advance.
You can use load event of window to set src of <video> element, Node.replaceChild(), download attribute at <a> element
window.onload = function() {
var video = document.querySelector("video");
video.addEventListener("error", function(event) {
var a = document.createElement("a");
a.href = this.src;
a.innerHTML = "download media";
a.download = ""; // set suggested file name here
this.parentElement.replaceChild(a, this);
});
video.src = "media.file";
}
<video controls="">
<source src="" type="video/mp4">
</video>
Im trying to make a video player work in all browsers. There is
more then one video and every time you click on demo reel it plays the
video and if you click the video 1 the other video plays. How can i
make them both work in all browsers? Here is my html and javascript
html
<video id="myVideo" controls autoplay></video>
<div>
Demo Reel</div>
video 1</div>
</div>
javascript
function changeVid1() {
var changeStuff = document.getElementById("myVideo");
changeStuff.src = "video/demoreel.mp4"
}
function changeVid2() {
var changeStuff = document.getElementById("myVideo");
changeStuff.src = "video/video1.mp4";
}
After you switch the source of the video, you need to run .load() on it to force it to load the new file. Also, you need to provide multiple formats, because there is no video codec supported by all browsers.
First, set up your sources like this:
var sources = [
{
'mp4': 'http://video-js.zencoder.com/oceans-clip.mp4',
'webm':'http://video-js.zencoder.com/oceans-clip.webm',
'ogg':'http://video-js.zencoder.com/oceans-clip.ogv'
}
// as many as you need...
];
Then, your switch function should look like this:
function switchVideo(index) {
var s = sources[index], source, i;
video.innerHTML = '';
for (i in s) {
source = document.createElement('source');
source.src = s[i];
source.setAttribute('type', 'video/' + i);
video.appendChild(source);
}
video.load();
video.play(); //optional
}
See a working demo here.
This gives the browser a list of different formats to try. It will go through each URL until it finds one it likes. Setting the "type" attribute on each source element tells the browser in advance what type of video it is so it can skip the ones it doesn't support. Otherwise, it has to hit the server to retrieve the header and figure out what kind of file it is.
This should work in Firefox going back to 3.5 as long as you provide an ogg/theora file. And it will work in iPads, because you only have one video element on the page at a time. However, auto-play won't work until after the user clicks play manually at least once.
For extra credit, you can append a flash fallback to the video element, after the source tags, for older browsers that don't support html5 video. (i.e., IE < 9 - though you'll need to use jQuery or another shim to replace addEventListener.)
I am writing a Browser Plugin and need to find a way to get the current time a YouTube Video playing on YouTube using JavaScript. I have been playing around in the Chrome JavaScript Console and haven't had any luck.
It appears that the chrome API only works with embedded video players not a video that is playing on on youtube.com. One option I looked into is in the share section of a video their is an input box for the "start at:" time that contains the current time of the video. I have tried using .value and .text on this input box and they both return undefined? Does anyone have any ideas?
ytplayer = document.getElementById("movie_player");
ytplayer.getCurrentTime();
See the api
Update: if it didn't work, also try player.playerInfo.currentTime (codepen live example)
Depends on what you want
player.getCurrentTime():Number
Returns the elapsed time in seconds since the video started playing.
player.getDuration():Number
Returns the duration in seconds of the currently playing video. Note
that getDuration() will return 0 until the video's metadata is loaded,
which normally happens just after the video starts playing.
http://code.google.com/apis/youtube/js_api_reference.html
Finally I found how to make it work on iOS (and Android too).
Actually, the whole youtube js api was broken for me if run on mobile browser.
Problem solved by creating player using new YT.Player as described in YouTube IFrame API.
Please note: only creating <iframe> from <div> placeholder works for mobile browsers at the time. If you try to use existing <iframe> in new YT.Player call, as mentioned in IFrame API, this will not work.
After player created, it's possible to use player.getCurrentTime() or player.getDuration() with player instance created.
Note: I had no luck calling this methods on player obtained with
player = document.getElementById(...) (from #JosephMarikle answer).
Only created player instance worked in mobile browsers.
Useful links:
YouTube IFrame API
YouTube JavaScript API
YouTube Player Demo
You can use Html5 Video API on youtube.com
var htmlVideoPlayer = document.getElementsByTagName('video')[0];
htmlVideoPlayer.currentTime
Note: It's not gonna work on Youtube Iframe API because Iframes are isolated. You cannot access the context of a Youtube IFrame .
In 2020, this works:
player.playerInfo.currentTime
full code:
see it live on codepen
Just FYI, There is a new iframe API for the YouTube player:
https://developers.google.com/youtube/iframe_api_reference
document.querySelector('video').currentTime
Stop at specific time youtube video and show notification box in GWD
<script>
var yid = document.getElementById("gwd-youtube_1");
var idBox = document.getElementById("box1");
pausing_function = function(event) {
var aa = setInterval(function() {
if (yid.getCurrentTime() > 8.0 && yid.getCurrentTime() < 8.1) {
yid.pause(yid);
idBox.style.opacity = 1;
console.log(yid.getCurrentTime() + "playing")
clearInterval(aa);
yid.removeEventListener("playing", pausing_function);
}
}, 100)
}
yid.addEventListener("playing", pausing_function);
var pausing_function_1 = function() {
if (yid.getCurrentTime() > 8.1) {
console.log(yid.getCurrentTime() + "pause")
// remove the event listener after you paused the playback
yid.removeEventListener("playing", pausing_function);
}
};
</script>
play video and hide notification
<script type="text/javascript" gwd-events="handlers">
window.gwd = window.gwd || {};
gwd.pauseVideo = function(event) {
var idBox = document.getElementById("box1");
idBox.style.opacity = 0;
};
</script>
<script type="text/javascript" gwd-events="registration">
// Support code for event handling in Google Web Designer
// This script block is auto-generated. Please do not edit!
gwd.actions.events.registerEventHandlers = function(event) {
gwd.actions.events.addHandler('gwd-youtube_1', 'playing', gwd.pauseVideo, false);
};
gwd.actions.events.deregisterEventHandlers = function(event) {
gwd.actions.events.removeHandler('gwd-youtube_1', 'playing', gwd.pauseVideo, false);
};
document.addEventListener("DOMContentLoaded", gwd.actions.events.registerEventHandlers);
document.addEventListener("unload", gwd.actions.events.deregisterEventHandlers);
</script>