I'm embedding a Youtube playlist with a special tweak - the starting point should be randomly chosen - by means of the following two snippets:
HTML:
<iframe id="juliacon-player"
align="center"
width="560"
height="315"
frameborder="0"
allowfullscreen>
</iframe>
JavaScript at the bottom of the <body>:
<script type="text/javascript">
var playlistId = 'PLP8iPy9hna6Sdx4soiGrSefrmOPdUWixM',
videoCount = 61,
index = Math.floor(Math.random() * videoCount),
playlistUrl = 'https://www.youtube.com/embed/videoseries?list=' + playlistId + '&index=' + index,
videoPlayer = document.getElementById('juliacon-player');
if (videoPlayer) {
videoPlayer.src = playlistUrl;
}
</script>
This works well in that it chooses a random video from the playlist and starts at that point (giving the impression of embedding a random video from the list on each page view), but the thumbnail before pressing Play is always the first video.
All resources I can find on how to change the thumbnail for a playlist does so permanently and statically - is there a way to change it so that I can change the thumbnail dynamically? I would of course prefer is this happens semi-automatically, but if I have to script the parameters somehow that's OK too.
I think it has something to do with youtube selecting the thumbnail based on the viewport size. I think you'll find the thumbnail will display correctly if the width of the iframe is 430px or less. When it is above that, for some reason it will only show the first thumbnail of the playlist.
iframe(width="280" height="158" src="https://www.youtube.com/embed/videoseries?list=PLaQokWZfgbykfIr6NKIcOMxsUC0cltOwE&index=2" frameborder="0" allowfullscreen)
vs
iframe(width="720" height="405" src="https://www.youtube.com/embed/videoseries?list=PLaQokWZfgbykfIr6NKIcOMxsUC0cltOwE&index=2" frameborder="0" allowfullscreen)
Same playlist. Different thumbnails. Notice the 280px is showing the correct thumbnail though.
If you embed just the video and attach the playlist to it, the thumbnail will be correct.
iframe(width="720" height="405" src="https://www.youtube.com/embed/K-mG66pwQ5M?list=PLaQokWZfgbykfIr6NKIcOMxsUC0cltOwE")
This is something I see you've already discovered. You've manually made the array, so I thought I'd take it one step further.
And automatically generate an array of the videos in the playlist. And then change your iframe src to show the video with the playlist appended to the url.
Based off this Retrieve all videos from youtube playlist using youtube v3 API I've created a javascript thing that pulls all the videoIds from the playlist; adds them to an array; then selects a random video from the array; and puts that into the iframe src.
Here is the code. You'll have to put your own API-Key in there. http://codepen.io/anon/pen/vLoRyL
I'm a total noob at this. So any constructive criticism with my code would be much appreciated. Hope this helps anyone else out there.
$(function() {
// GET A RANDOM VIDEO FROM ALL PLAYLISTS
function randomVideo() {
// VARIABLES
// the playlist
var playlistDon = {url:"PLaQokWZfgbykfIr6NKIcOMxsUC0cltOwE", count:4, name:"Don's Design Lab"};
// get random video from that playlist
var indexRando = Math.floor((Math.random() * playlistDon.count));
// making the array of videos in playlist
var sum = 0;
var videoArray = [];
// CONNECTING TO API
function getVids(PageToken){
$.get(
"https://www.googleapis.com/youtube/v3/playlistItems",{
part : 'snippet',
maxResults : 50,
playlistId : playlistDon.url, // selecting the random playlist
pageToken : PageToken,
key: 'YOUR API KEY'
},
function(data){
myPlan(data);
}
);
}
// GETTING LIST OF VIDEOiDS FROM PLAYLIST
function myPlan(data){
var total = data.pageInfo.totalResults;
var nextPageToken = data.nextPageToken;
// cycle through the data
for(var i=0;i<data.items.length;i++){
// add .items to videoArray
videoArray.push(data.items[i].snippet.resourceId.videoId);
sum++ ;
if(sum === (total) ){ // if the current item number equals the total number of items
sum = 0; // reset the count
updateIframe(); // update the iframe
return;
}
}
if(sum < (total)){
getVids(nextPageToken);
}
}
function updateIframe() {
// put that video into the iframe
var videoUrl = "https://www.youtube.com/embed/" + videoArray[indexRando] +"?list=" + playlistDon.url + "&index=" + indexRando + "&showinfo=1";
$('.video.random iframe').attr("src", videoUrl);
}
getVids();
}
$('button').on('click', function() {
randomVideo();
});
});
Related
I'm making a random order video player, adapting code from here but the same video just keeps playing, even though I can see (from text above the video) that the random ordering is working. Live version is here.
Is the problem with the appendChild meaning the new video is end of a list but the first in list keeps playing? I tried replaceChild but that didn't work.
<script type="text/javascript">
$(document).ready(function(){
var videos = [
[{type:'mp4', 'src':'carlos/one-carlostest.mp4'}],
[{type:'mp4', 'src':'carlos/two-carlostest.mp4'}],
[{type:'mp4', 'src':'carlos/three-carlostest.mp4'}],
[{type:'mp4', 'src':'carlos/four-carlostest.mp4'}],
[{type:'mp4', 'src':'carlos/five-carlostest.mp4'}]
];
// selecting random item from array as first to be played
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(){
var newRandom = videos[Math.floor(Math.random()*videos.length)];
newvideo(newRandom[0].src)
document.getElementById("monitor").innerHTML = "randomitem is " + newRandom[0].src;
}
})
</script>
Also, if anyone can tell me why the autoplay never works that'd be appreciated, though it's the least of my problems.
I have kinda found this solution for your video playing one after other. now in your JS file, now you just will need to add your video src path.
var vidElement = document.getElementById('video');
var vidSources = [
"https://lutins.co.uk/carlos/one-carlostest.mp4",
"http://www.w3schools.com/html/movie.mp4"
];
var activeVideo = Math.floor((Math.random() * vidSources.length));
vidElement.src = vidSources[activeVideo];
vidElement.addEventListener('ended', function(e) {
// update the active video index
activeVideo = (++activeVideo) % vidSources.length;
if(activeVideo === vidSources.length){
activeVideo = 0;
}
// update the video source and play
vidElement.src = vidSources[activeVideo];
vidElement.play();
});
video {
width:350px;
}
<p>wowww you got it!</p>
<video src="https://lutins.co.uk/carlos/one-carlostest.mp4" id="video" autoplay muted playsinline></video>
Change the randomIt variable into a callback, only this way, it will generate new random number each time it get call.
// I have change randomitem into a function with ofcourse a proper name
var getRandomItem = function() {
return videos[Math.floor(Math.random()*videos.length)];
}
You should also call it properly like this:
//newvideo(randomitem[0].src) -> change it to
newvideo(getrandomItem().src)
There might also other adjustments requires for your code to work.
I have a script that will pull the latest video from a youtube channel and embed it to my school page. It works but there are two issues.
One it doesn't immediately identify a recently posted video. Is there a delay from youtube before it syncs and the new posts can register?
Two the script runs but it does stop other video content on the page from displaying. Any idea why that might be?
I've looked it over and over and exhausted any searches I could think of.
Thanks for the help! Here is the code:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<iframe id="youtube_video" width="400" height="215" frameborder="0" allowfullscreen></iframe>
<script>
var channelID = "UC0gcWgeEVOE7TDEKtLNnSuA";
$.getJSON('https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Fwww.youtube.com%2Ffeeds%2Fvideos.xml%3Fchannel_id%3D'+channelID, function(data) {
var link = data.items[0].link;
var id = link.substr(link.indexOf("=")+1);
$("#youtube_video").attr("src","https://youtube.com/embed/"+id + "?controls=1&showinfo=0&rel=0");
});
</script>
I am not 100% clear on what you are trying to achieve - but if you are trying to display MORE than 1 video, you currently only have a single #youtube_video element. Rather you would likely need to create an element for each index of the data array and create unique IDs such as
#youtube_video + link[i]
here's a Fiddle:
https://jsfiddle.net/e620tuy8/
var channelID = "UC0gcWgeEVOE7TDEKtLNnSuA";
$.getJSON('https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Fwww.youtube.com%2Ffeeds%2Fvideos.xml%3Fchannel_id%3D' + channelID, function(data) {
var container = $('.container');
for (var i = 0; i < data.items.length; i++) {
var link = data.items[i].link;
var id = link.substr(link.indexOf("=") + 1);
var iframe = '<iframe id="youtube_video_id_' + i + '" src="https://youtube.com/embed/' + id + '?controls=1&showinfo=0&rel=0" width="400" height="215" frameborder="0" allowfullscreen></iframe>'
container.append(iframe)
}
});
Found, the answer with a little more digging.
Thanks to Frank's answer here https://stackoverflow.com/a/43873099/5943182
Thank you to anyone who viewed.
I still don't know why the most recent wasn't being pulled in the above code, but the alternative method works wonderfully for me.
I have designed an i-phone-like screen on a web browser where I am testing this application I am in the process of building. It works great up until the point where I want to call out another set of videos.
What works
The application is structured so that when the user sees the screen she is directed to a channel that has a vertical video.
The buttons on the top left and top right advance to the next and the previous video.
<div id="topVid" class="videoContainer">
<div class="topHorizontalButtonRow">
</div>
<video class="topVid" loop onclick="this.paused? this.play() : this.pause()" >
<source src="videos/ParisisBurning_660x370_I_went_to_a_ball.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
There is a "channel" button that shows the user a smaller window if pressed, where the user can view other channels by clicking on a second set of buttons next and previous buttons.
<div id="bottomVid" class="videoContainerTwo hiddenElement">
<div class="topHorizontalButtonRow">
<div class="buttonLeftTriangleBlue"></div>
<div class="buttonRightTriangleBlue"></div>
</div>
<video loop onclick="this.paused? this.play() : this.pause()" >
<source src="videos/Politics_Refugee_Sign.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
jquery show/hide smaller window:
$(".buttonTeardropChannelBlue").click( function (){
if( $("#bottomVid").is(':visible') ) {
$("#bottomVid").hide();
} else {
$("#bottomVid").show();
}
});
If the user wants to watch this specific channel, she can click on the smaller window, which hides the current window and advances to the other channel. The video can be clicked on, and once that happens, the user will be directed to the next channel.
Below is the code that works perfectly to advance the video of the current selection, and it contains the videos in arranged in an array.
var Vids = (function() {
var _currentId = -1;
var _urls =
["videos/ParisisBurning_370x660_Get_Into_The_Suits_Vert.mp4","videos/ParisisBurning_370x660_School_Vert.mp4","videos/ParisisBurning_660x370_I_came_I_saw_Vert.mp4", "videos/ParisisBurning_660x370_I_went_to_a_ball.mp4"]; // literal array
return {
next: function() {
if (++_currentId >= _urls.length)
_currentId = 0;
return this.play(_currentId);
},
prev: function() {
if (--_currentId < 0)
_currentId = _urls.length - 1;
return this.play(_currentId);
},
play: function(id) {
var myVideo = document.getElementsByTagName('video')[0];
myVideo.src = _urls[id];
myVideo.load();
myVideo.play();
return false;
}
}
})();
What does not work
The issue: showing and hiding multiple video lists
However, the problem starts when I want to select a different class of videos, which has the exact same code except for different videos. I have changed the name of the function to say, VidsTwo but the problem remains.
var VidsTwo = (function() {
var _currentId = -1;
var _urls = ["videos/Politics_Atl_We_are_the_people.mp4","videos/Politics_Atlanta_Whose_Streets.mp4", "videos/Politics_Womens_March_Washington_CBS_VERT.mp4",
"videos/Politics_No_bans_no_walls_America_is_home_to_all_VERT.mp4",
"videos/Politics_Let_them_in_VERT.mp4",
"videos/Politics_Tear it Down_JFK_VERT.mp4",
"videos/Politics_This_is_What_America_Looks_Like_embrace.mp4",
"videos/Politics_This_land_was_made_VERT.mp4", "videos/Politics_We_need_an_independent_investigation_town_hall.mp4",
"videos/Politics_Just say no_town_hall_VERT.mp4", ]; // literal array
return {
next: function() {
if (++_currentId >= _urls.length)
_currentId = 0;
return this.play(_currentId);
},
prev: function() {
if (--_currentId < 0)
_currentId = _urls.length - 1;
return this.play(_currentId);
},
play: function(id) {
var myVideo = document.getElementsByTagName('video')[0];
myVideo.src = _urls[id];
myVideo.load();
myVideo.play();
return false;
}
}
})();
The issue remains: the buttons will continue to play the videos of the current channel in addition to the ones of the new channel, and it will not hide the current video. I understand it happens because in the javascript code, it uses the select element by tag which is "video". and all the array lists have "video" so it is playing all of them.
What is the best solution to this problem, given that I want to be able to separate the videos into categories "channels" that will have similar thematic content, and that this categories will be called by users as they look at a second smaller window of videos?
Core questions
Is there a way to have it NOT play a selection of arrays? What can I change in the Javascript code that will indicate that these separate video arrays do not belong to the same class? How can I make it clear in the code that these videos, although they are all videos, belong to different categories and therefore can only be played if their specific category is called?
Brainstorming solutions:
I am thinking I would probably need a second div that will have a
second row of buttons that call out the second function, since the
prev and next indicate a separate variable that was declared for each
class of videos...but this is getting a bit complicated for my newbie
skills:)
Or perhaps each video on a parent class should be saved on the
html itself as a hidden div and should be called by using "show
next child of parent div", as opposed to being saved as an array on
the javascript code?
The next step is adding marquee text to each video so maybe having
separate hidden divs on the html itself is a better solution than
having the videos stored as javascript arrays?
This is basically a prototype/beta for something that will become an
app so there is no database yet, (which will make it easier to
store this info eventually once I begin more in-depth user tests).
This complication is for testing only:)
UPDATE: I am still curious as to what the best solution would be, however I have decided, in this case, to add divs directly to the html and use jquery's next sibling selectors. Because I will have some text specific to some videos, they won't be properly connected to the javascript arrays anyway. I find the javascript array solution "cooler" but it is perhaps not the best in the end.
make Vids like this:
var Vids = function(vidArray=[]) {
var _currentId = -1;
var _urls = vidArray;
return {
next: function() {
if (++_currentId >= _urls.length)
_currentId = 0;
return this.play(_currentId);
},
prev: function() {
if (--_currentId < 0)
_currentId = _urls.length - 1;
return this.play(_currentId);
},
play: function(id) {
var myVideo = document.getElementsByTagName('video')[0];
myVideo.src = _urls[id];
myVideo.load();
myVideo.play();
return false;
}
}
};
then prepare your url array and call Vids:
var urls =["videos/ParisisBurning_370x660_Get_Into_The_Suits_Vert.mp4","videos/ParisisBurning_370x660_School_Vert.mp4","videos/ParisisBurning_660x370_I_came_I_saw_Vert.mp4", "videos/ParisisBurning_660x370_I_went_to_a_ball.mp4"];
Vids(urlf).play(3); //Replace 3 with any id
I'd like to know how could I achieve a video playlist without any buttons or control that would simply play an array of videos and would start again when the last is over.
I found this piece of code about a clickable playlist : http://jsfiddle.net/e8CbF/
but I really don't know how to make it automatic. Also, the array is coming from a PHP variable, how I can I use it inside this code ?
function loadVids(vidsArray){
for(var a=0,b,f=document.createDocumentFragment();b=vidsArray[a];++a){
var c=document.createElement('div');
c.textContent=b;
f.appendChild(c);
}
d.appendChild(f);
}
var video=document.createElement('video'),vids=['http://screen.alifts.com/screenfiles/video1.mp4','http://screen.alifts.com/screenfiles/video2.mp4'], /* Is it there that I should put the php array ? */
d=document.createElement('div');
d.onclick=function(e){if(e.target.parentNode==this){
video.src=e.target.textContent;
video.play();
}}
document.body.appendChild(video);
document.body.appendChild(d);
loadVids(vids);
Your code is a total mess. So i completely rewrite it.
<video src="" id="player"/>
<script>
var video=counter=0;
videos=['<?php echo join("';'",$array);?>'];
window.onload=()=>{
//get the video frame
video=document.getElementById("player");
//if the video ended, play next.
video.addEventListener("ended",play,false);
//start
play();
}
var play=()=>{
//add the video src
video.src=videos[counter];
//play next video next time
counter++;
if(counter==videos.length){
counter=0;
}
};
</script>
This is what I'm working with:
var numberOfSongs = 5
var sound = new Array(numberOfSongs+1)
sound[0]= "https://domain.com/media/audio1.mp3"
sound[1]= "https://domain.com/media/audio2.mp3"
sound[2]= "https://domain.com/media/audio3.mp3"
sound[3]= "https://domain.com/media/audio4.mp3"
sound[4]= "https://domain.com/media/audio5.mp3"
function randomNumber(){
var randomLooper = -1
while (randomLooper < 0 || randomLooper > numberOfSongs || isNaN(randomLooper)){ randomLooper = parseInt(Math.random()*(numberOfSongs+1))
}
return randomLooper
}
var randomsub = randomNumber()
var soundFile = sound[randomsub]
document.write ('<EMBED src= "' + soundFile + '" hidden=true autostart=true loop=true>')
A friend gave me this for my website. This is used to play a randomly selected mp3 file from a list of 5 of them. I'm trying to add volume values to this (Nothing that will visibly show as controls) but to be put in as JS.
I want to be able to upload audio but not have to edit the audio itself in a audio editor, I'd rather do it here in JS for my convenience. What would be a good way to add volume values to this?
Eg: volume at default is set at 25% but can't be changed unless you edit the source of this JS. There should be no controls visible.
I'm not good at JS at all. I've looked up how to build something like that into this but I don't know where to begin.
Use Audio
var audio = new Audio(soundFile);
audio.loop = true;
audio.autoplay = true;
// set volume here, between 0 and 1
audio.volume = .7;