i have movie website and my video player local storage just saving one video src.
i want to use different src for each movie video
window.addEventListener("unload", () => {
let setDuration = localStorage.setItem(
"duration",
`${mainVideo.currentTime}`
);
let setSrc = localStorage.setItem(
"src",
`${mainVideo.getAttribute("src")}`
);
});
window.addEventListener("load", () => {
let getDuration = localStorage.getItem("duration");
let getSrc = localStorage.getItem("src");
if (getSrc) {
mainVideo.src = getSrc;
mainVideo.currentTime = getDuration;
}
});
Related
I'm trying to make a video downloader for instagram but whenever I fetch the video url it does not download I have to right click and save. is there a way I could make a download button instead of right click to save?
here my code
$("#getMedia").click(getMedia);
var render = document.querySelector("#media");
function createMedia(data, type) {
var media = document.createElement(type);
media.id = "instagramMedia";
media.src = data.content;
media.setAttribute("class", "");
media.width = $(render).width();
if (type === "video") {
media.controls = true;
media.autoplay = true;
}
render.innerHTML = "";
var downloadMsg = document.createElement("p");
downloadMsg.setAttribute("class", "bg-success text-info");
downloadMsg.innerText = "Right Click on the Media below to get Save Option!";
render.appendChild(downloadMsg);
render.appendChild(media);
}
function getMedia() {
var url = $("#postUrl").val();
if (url) {
$.get(url, function (data) {
render.innerHTML = data;
var mediaWaitTimer = setTimeout(function () {
var video = document.querySelector('meta[property="og:video"]');
if (video) {
createMedia(video, "video");
} else {
var img = document.querySelector('meta[property="og:image"]');
if (img) {
createMedia(img, "img");
} else {
document.body.innerHTML = body;
alert("Error extracting Instagram image / video.");
};
}
clearTimeout(mediaWaitTimer);
}, 200);
});
} else {
document.querySelector("#media").setAttribute("placeholder", "Invalid Address, Please Enter Proper Insagram Link");
}
}
Set download attribute for your clickable html element probably in your createMedia function.
<a href="myvideo.mp4" download>Download</a>
for reference visit : https://www.w3schools.com/tags/att_a_download.asp
I'm trying to play videos one after the other in the same Vimeo player, without success.
This is the code I'm working on. I can't find any example on how to do that.
I'm sure I'm wrong but I don't know how to go further...
var iframe = document.querySelector('iframe.main-player');
var player = new Vimeo.Player(iframe);
var video_ids = ['123456789', '987654321'];
video_ids.forEach(function(item, index) {
player.pause();
player.loadVideo(item);
player.on('loaded', function() {
player.play();
});
})
I'm not sure about this, because can't test it right now , but you can try something like this:
var iframe = document.querySelector('iframe.main-player');
var player = new Vimeo.Player(iframe);
var video_ids = ['123456789', '987654321'];
var index = 0;
var playNext = function(data){
player.pause();
if(index<=video_ids.length)
player.loadVideo(video_ids[index++])
}
player.pause();
player.loadVideo(video_ids[index++]);
player.on('loaded', function() {
player.play();
});
player.on('ended', playNext);
The idea is pretty simple by listen to the ended event then moving to the next item.
First of all, we just create a class to hold some information such as the list & current playing index:
import Player from "#vimeo/player";
class Playlist {
constructor(playlist) {
this.playlist = playlist;
this.currentIdx = 0;
}
init() {
this.player = new Player("app", {
id: this.currentItem,
width: 640
});
this.player.on("ended", this.onEnded.bind(this));
}
onEnded() {
if (this.currentIdx < this.playlist.length) {
this.currentIdx++;
const nextId = this.currentItem;
this.player.loadVideo(nextId);
// Check next item has loaded then play it automatically
// you might not receive any error in case of having to interact with document
this.player.on("loaded", () => {
this.player.play();
});
}
}
get currentItem() {
return this.playlist[this.currentIdx];
}
}
// Try to run 2 items
const pl = new Playlist([59777392, 28582484]);
pl.init();
NOTE: I also created a codesandbox link for you here https://codesandbox.io/s/focused-firefly-ej0fd?file=/src/index.js
I have a list of audio files. How to make them play one by one? Right now If I click button play, they are playing all together.
const audioList = [ 'audio1', 'audio2', 'audio3', 'audio4', 'audio5' ]
let button = document.querySelector('#btnPlay').addEventListener('click', e=>{
audioList.forEach(element => {
let audio1 = new Audio(element);
audio1.play();
});
You can achive this by using the audio element's 'ended' event and change the audio's src after end of each song.
my html file:
<audio src=""></audio>
<button></button>
my js file:
const songs = [ 'audio1', 'audio2', 'audio3', 'audio4', 'audio5' ]
const audio = document.querySelector('audio');
const button = document.querySelector('button');
let songIndex = 0;
audio.src = songs[songIndex]
audio.addEventListener('ended', () => {
songIndex++;
if(songIndex >= songs.length) return;
audio.src = songs[songIndex]
audio.play()
})
document.addEventListener('click', () => audio.play())
Codepen demo : https://codepen.io/PatrykBuniX/pen/GRgGGyr
I hope it helped you! :D
I need the video dimensions of a video that is uploaded via an input tag. But when I set the uploaded video as source of a video tag, the loadedmetadata event doesn't get called.
In this method I set the video and the listener:
function getVideoDimensionsOf(objUrl){
return new Promise(function(resolve){
let video = document.createElement('video');
//THIS GETS CALLED AS EXPECTED
video.addEventListener( "loadedmetadata", function () {
//THIS GETS NEVER CALLED
let height = this.videoHeight;
let width = this.videoWidth;
console.log(height,width)
}, false );
video.src = objUrl;
});
}
In this method, I set up the callback for the video upload:
function localFileVideoPlayer() {
var URL = window.URL || window.webkitURL
var uploadSelectedFile = function (event) {
var file = this.files[0]
var type = file.type
var fileURL = URL.createObjectURL(file)
var fileReader = new FileReader();
fileReader.onload = function() {
var videofile = this.result;
//do something here with video data
};
fileReader.readAsArrayBuffer(file);
getVideoDimensionsOf(window.URL.createObjectURL(file))//-->>HERE I CALL THE FUNCTION THAT SHOULD SET THE VIDEO SOURCE
}
var inputNode = document.getElementById("videofile")
inputNode.addEventListener('change', uploadSelectedFile, false)
}
And this is the html upload field:
<div>
Upload Video:
<input id="videofile" type="file" accept="video/*"/>
</div>
I checked that the getVideoDimensionsOf method gets called, but why is the loadedmetadata listener not getting the callback?
Because nothing forces the browser to preload your video element.
For all it knows, you will never play this video, so it makes sense it won't preload its content.
You could try to force this preloading by calling its play() method.
function getVideoDimensionsOf(objUrl) {
return new Promise(function(resolve) {
let video = document.createElement('video');
video.muted = true; // bypass Chrome autoplay policies
video.addEventListener("loadedmetadata", function() {
let height = this.videoHeight;
let width = this.videoWidth;
video.pause();
resolve( { width, height } );
}, false);
video.src = objUrl;
video.play();
});
}
inp.onchange = e => {
const url = URL.createObjectURL(inp.files[0]);
getVideoDimensionsOf(url)
.then(obj => {
URL.revokeObjectURL(url);
console.log(obj);
});
}
<input type="file" id="inp" accept="video/*,.mp4">
localFileVideoPlayer();
function getVideoDimensionsOf(objUrl) {
return new Promise(function(resolve) {
let video = document.createElement("video");
{
// if you need to append the video to the document
video.controls = true;
document.body.appendChild(video);
}
//THIS GETS CALLED AS EXPECTED
video.addEventListener(
"loadedmetadata",
function() {
//THIS GETS NEVER CALLED
let height = this.videoHeight;
let width = this.videoWidth;
console.log(height, width);
},
false
);
video.src = objUrl;
});
}
function localFileVideoPlayer() {
var URL = window.URL || window.webkitURL;
var uploadSelectedFile = function(event) {
var file = this.files[0];
var type = file.type;
var fileURL = URL.createObjectURL(file);
var fileReader = new FileReader();
fileReader.onload = function() {
var videofile = this.result;
//do something here with video data
};
fileReader.readAsArrayBuffer(file);
getVideoDimensionsOf(window.URL.createObjectURL(file)); //-->>HERE I CALL THE FUNCTION THAT SHOULD SET THE VIDEO SOURCE
};
var inputNode = document.getElementById("videofile");
inputNode.addEventListener("change", uploadSelectedFile, false);
}
<div>
Upload Video:
<input id="videofile" type="file" accept="video/*" />
</div>
In your code, you need to initialize the input change event using the localFileVideoPlayer method, so I first executed this method. Then if you need to display this video in the document, you need to append a video element to the document, so there is appendChild method in getVideoDimensionsOf
I have a question about the sequence of JavaScript. Let me show you my code first:
Here is my HTML:
<video id="video" width="320" height="320" autoplay></video><br>
<button id="snap">Snap Photo</button><br>
<canvas id="canvas" width="320" height="320"></canvas>
<p id="pngHolder"></p>
And here is my JavaScript:
<script>
var Id;
//List cameras and microphones.
if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
console.log("enumerateDevices() not supported.");
}
navigator.mediaDevices.enumerateDevices()
.then(function (devices) {
devices.forEach(function (device) {
if (device.kind == "videoinput" && device.label.indexOf('back') >= 0) {
Id = device.deviceId;
alert("ID 1 : " + Id);
}
});
})
.catch(function (err) {
console.log(err.name + ": " + err.message);
});
// Put event listeners into place
window.addEventListener("DOMContentLoaded", function () {
// Grab elements, create settings, etc.
alert("ID 2 : "+ Id);
var canvas = document.getElementById("canvas"),
videoObj = {
video: {
optional: [{ deviceId: Id }]
}
},
context = canvas.getContext("2d"),
video = document.getElementById("video"),
errBack = function (error) {
console.log("Video capture error: ", error.code);
};
// Trigger photo take
document.getElementById("snap").addEventListener("click", function () {
context.drawImage(video, 0, 0, 640, 480);
// Get the image
var image = convertCanvasToImage(canvas);
// Actions
document.getElementById("pngHolder").appendChild(image);
// Converts canvas to an image
function convertCanvasToImage(canvas) {
var image = new Image();
image.src = canvas.toDataURL("image/png");
return image;
}
});
//alert("ID 2 : " + Id);
// Put video listeners into place
if (navigator.getUserMedia) { // Standard
navigator.getUserMedia(videoObj, function (stream) {
video.src = stream;
video.play();
}, errBack);
} else if (navigator.webkitGetUserMedia) { // WebKit-prefixed
navigator.webkitGetUserMedia(videoObj, function (stream) {
video.src = window.webkitURL.createObjectURL(stream);
video.play();
}, errBack);
} else if (navigator.mozGetUserMedia) { // Firefox-prefixed
navigator.mozGetUserMedia(videoObj, function (stream) {
video.src = window.URL.createObjectURL(stream);
video.play();
}, errBack);
}
}, false);
I want to insert the value of device.deviceId into variable Id that I define on the first of my JavaScript row. It is still a success (it is shown by the alert("ID 1 : " + Id);). But when I try to put it into optional: [{ deviceId: Id }], the Id doesn't have any value.
And also, when I try to run it with browser, I have found that the alert("ID 2 : " + Id); is shown first instead of alert("ID 1 : " + Id);. In fact, I have already put the alert("ID 1 : " + Id); first. I think that's why the variable is still empty.
My question is how can I insert the device.deviceId value to optional: [{ deviceId: Id }] ?
navigator.mediaDevices.enumerateDevices and DOMContentLoaded are racing, and the latter is winning, so you're using Id before it's set.
To solve this use a temporary haveId promise:
var haveId = navigator.mediaDevices.enumerateDevices()
.then(devices => devices.find(d => d.kind == "videoinput" &&
d.label.indexOf("back") >= 0));
// Put event listeners into place
window.addEventListener("DOMContentLoaded", function () {
haveId.then(id => {
// Grab elements, create settings, etc.
alert("ID 2 : "+ id);
var canvas = document.getElementById("canvas"),
videoObj = { video: { deviceId: id } }, // <-- adapter.js constraints
Promise-chains create dependencies, and this way the getUserMedia code wont proceed until both things have happened.
The second problem is you're mixing new and outdated Chrome-specific constraints. Either use adapter.js until Chrome catches up, or in a pinch, use the Chrome-only sourceId (but that wont work in any other browser).
navigator.mediaDevices.enumerateDevices() is asynchronous. It returns a promise (think callback, but fancier).
You should trigger your call to getUserMedia from there or wait for both DOMContentLoaded and enumerateDevices and then execute getUserMedia.