Videojs - current index as variable - javascript

I have a VideoJs player that plays from a playlist.
I want to display which video number is currently playing from the playlist. Since I need the total number of videos anyway to create the playlist, I can use the defined variable there.
e.g. "Video 3 of 10".
For this I try by means of:
var test = player.currentIndex(videoList);
To pass the current number of the video into the variable.
Unfortunately without success.
var lerneinheit = "E1";
var videocounter = 26;
var videonumber= 0;
const videoList = Array.from({ length: videocounter }, (_, i) => {
return { sources: [{ src: `https://www.XXX.de/player/${lerneinheit}_${videonumber + i + 1}.mp4`, type: 'video/mp4' }], };
});
var player = videojs(document.querySelector('video'), {
inactivityTimeout: 0
});
try {
player.volume(1);
} catch (e) {}
player.playlist(videoList);
document.querySelector('.previous').addEventListener('click', function() {
player.playlist.previous();
});
document.querySelector('.next').addEventListener('click', function() {
player.playlist.next();
});
player.playlist.autoadvance(0); // play all
Array.prototype.forEach.call(document.querySelectorAll('[name=autoadvance]'), function(el) {
el.addEventListener('click', function() {
var value = document.querySelector('[name=autoadvance]:checked').value;
//alert(value);
player.playlist.autoadvance(JSON.parse(value));
});
});
/* ADD PREVIOUS */
var Button = videojs.getComponent('Button');
// Extend default
var PrevButton = videojs.extend(Button, {
//constructor: function(player, options) {
constructor: function() {
Button.apply(this, arguments);
//this.addClass('vjs-chapters-button');
this.addClass('icon-angle-left');
this.controlText("Previous");
},
handleClick: function() {
console.log('click');
player.playlist.previous();
}
});
/* ADD BUTTON */
//var Button = videojs.getComponent('Button');
// Extend default
var NextButton = videojs.extend(Button, {
//constructor: function(player, options) {
constructor: function() {
Button.apply(this, arguments);
//this.addClass('vjs-chapters-button');
this.addClass('icon-angle-right');
this.controlText("Next");
},
handleClick: function() {
console.log('click');
player.playlist.next();
}
});
videojs.registerComponent('NextButton', NextButton);
videojs.registerComponent('PrevButton', PrevButton);
player.getChild('controlBar').addChild('PrevButton', {}, 0);
player.getChild('controlBar').addChild('NextButton', {}, 2);
document.getElementById("current").innerHTML = "Von " + videocounter;

Check the API documentation:
player.curtentItem() returns the index of the current item. You'll probably want to increase this by one for display, as it is 0-based. The playlistitem event is triggered when the item has changed.

Related

Attach varriable to a api object

So I get multiple objects from a REST API.
I get the data via AJAX like this:
var APICaller = (function () {
let endpoint = "https://jsonplaceholder.typicode.com/";
function api_call(method, url, data, callback) {
$.ajax({
url: url,
method: method,
data: data,
success: callback
});
}
function get_users(callback) {
let method = "GET";
let url = endpoint + "users";
let data = {};
api_call(method, url, data, callback);
}
return {
get_users: get_users,
};
})();
I am rolling 3 dices, and the total values of these 3 dices should be attached to each user so i can order the "scoreboard" after the total value.
I wonder if there is any way to attach the variable totalamount to every user?
Thanks in advace!
EDIT:
Currently i am getting all the users from the api.
This is the rest of my code withing this topic:
var Game = (function () {
var dice_total;
//Function for when the dice rolls.
function roll_dice() {
var value1 = $(".val1");
var value2 = $(".val2");
var value3 = $(".val3");
var v1 = Math.floor(Math.random() * 6) + 1;
var v2 = Math.floor(Math.random() * 6) + 1;
var v3 = Math.floor(Math.random() * 6) + 1;
value1.html(v1);
value2.html(v2);
value3.html(v3);
dice_total = v1 + v2 + v3;
}
return {
roll_dice: roll_dice
};
})();
var EventHandlers = (function () {
function init() {
var currentPlayer;
APICaller.get_users(on_get_users_success);
function on_get_users_success(response) {
//For each user in the API
$.each(response, function (i, user) {
$("#my-list").append('<li class="list-li"><a class="list-a">' + user.name + '</a></li>');
//Create the divs and p tags
$("#dice_value").append('<div class="val_div"> <p class="val1"></p> <p class="val2"></p> <p class="val3"></p></div>');
});
//change information
$("#info-txt").text("Välj en spelare!");
}
// On klick on a user make klicked user your own player.
$("#my-list").on('click', '.list-a', function () {
currentPlayer = this.text;
$("#info-txt").text("Tryck på spela knappen för att börja spelet!");
$("#currentPlayer-div").animate({
height: '300px',
opacity: '1'
});
$("#currentPlayer-h3").text(currentPlayer);
});
// On klick of the play button
$("#startGame-button").click(function () {
$().animate();
$("#currentPlayer-div").animate({
height: '150px'
});
$("#startGame-button").animate({
opacity: '0'
});
$("#dice_value").animate({
opacity: '1'
});
Game.roll_dice();
});
// $(".button-to-hide").click(function (){
// $(this).hide();
// });
// $("#show-all-buttons").click(function (){
// $(".button-to-hide").show();
// });
// $("#btn-edit-text").click(function (){
// var value = $("#my-input").val();
// $("p").html(value);
// });
}
return {
init: init,
}
})();
var DocumentEdit = (function () {
return {
}
})();
$(document).ready(function () {
EventHandlers.init();
});
Hope that describes it.

Array callback for every item apart from one

I have the following array:
var videos = [];
$('.video').each(function(){
videos.push($(this).attr('id'));
});
and inside here:
events: {
onPlay: function() {
var id = vid.attr('id');
var index = videos.indexOf(id);
videos.splice(index, 1);
console.log(videos);
}
}
I have also tried something like this:
// if($(this).attr('id') != $('.video').attr('id') ){
// jwplayer( $('.video').attr('id')).stop();
// }
I want to run a function for every array item (videos) apart from the array value equal to:
vid.attr('id')
I am using splice but that removes the item completely and since I have multiple videos I will end up with an empty array. I basically want only one video to play at the time so I need to stop the others.
Full function code:
$(function(){
//add attributes to your ".video" DIV placeholder to customimize output
//example: data-autostart="true" - see customSettings Object below.
if (typeof(jwplayer) !== 'undefined'){
var videos = [];
$('.video').each(function(){
videos.push($(this).attr('id'));
});
$('.video').each(function(){
var vid = $(this),
videoSettings = {},
settings = {
autostart: false,
width: '100%',
aspectratio: '16:9',
image: ''
},
customSettings = {
autostart: vid.attr('data-autostart'),
width: vid.attr('data-width'),
aspectratio: vid.attr('data-aspectratio'),
image: vid.attr('data-image')
};
$.extend(videoSettings, settings, customSettings);
var playerInstance = jwplayer( vid.attr('id') ).setup({
primary: "flash",
file: Drupal.settings.basePath + $(this).attr('data-src'),
autostart: videoSettings.autostart,
aspectratio: videoSettings.aspectratio,
image: Drupal.settings.basePath + videoSettings.image,
skin: "glow",
stretching: "exactfit",
width: videoSettings.width,
events: {
onPlay: function() {
var id = vid.attr('id');
var index = videos.indexOf(id);
videos.splice(index, 1);
console.log(videos);
// if($(this).attr('id') != $('.video').attr('id') ){
// jwplayer( $('.video').attr('id')).stop();
// }
}
}
// ga:{idstring: videoSettings.videotitle,
// trackingobject: "pageTracker"
// }
});
});
}
});
What about a simple forEach?
onPlay: function() {
var id = vid.attr('id');
videos.forEach(function(videoId) {
if(videoId != id) {
//You may want to check first if video is running at all
jwplayer(videoId).stop();
}
});
}
onPlay: function() {
var id = vid.attr('id');
for (var v in videos) {
if(id != v[i]) {
jwplayer(v[i].stop();
}
}
}

jquery plugin, reference video element in DOM

I have started jQuery plugin where I want to retrieve the .duration and .currentTime on a HTML5 video, from within a bound .on('click', ) event.
I am struggling to capture this information within my plugin.registerClick function, here is my code:
(function ($) {
$.myPlugin = function (element, options) {
var defaults = {
videoOnPage: 0,
dataSource: 'data/jsonIntervals.txt',
registerClick: function () { }
}
var plugin = this;
plugin.settings = {}
var $element = $(element);
element = element;
plugin.init = function () {
plugin.settings = $.extend({}, defaults, options);
$element.on('click', plugin.registerClick);
getJsonIntervals();
}
plugin.registerClick = function () {
var duration = $('video').get(plugin.settings.videoOnPage).duration;
console.log('duration: ' + duration);
}
var startTimes = [];
var dataSet = false;
var getJsonIntervals = function () {
if (dataSet == false) {
//calls a $.getJSON method.
//populates startTimes
//updates dataSet = true;
};
}
plugin.init();
}
$.fn.myPlugin = function (options) {
return this.each(function () {
if (undefined == $(this).data('myPlugin')) {
var plugin = new $.myPlugin(this, options);
$(this).data('myPlugin', plugin);
}
})
};
})(jQuery);
$(function () {
$('#button1').myPlugin();
});
Here my sample jsFiddle Click Here
Seems to work for me:
plugin.registerClick = function () {
var video = $('video').get(0);
console.log('duration: ' + video.duration);
console.log('currenttime: ' + video.currentTime);
}
http://jsfiddle.net/p4w040uz/2/
You need to play the video first then click the button. The browser has to retrieve the meta data first before it can return it.
Additional reference material you can read up:
http://www.w3schools.com/tags/av_event_loadedmetadata.asp
http://www.w3.org/2010/05/video/mediaevents.html

Applying transitions to preloaded images

I'm using the jQuery plugin Images-rotation in order to create a slideshow that plays when hovering over an image. I'd like to add transitions between the images, such as jQuery's fadeIn. The images are preloaded, which is why I think what I've attempted so far hasn't been successful.
I've also created this (http://jsfiddle.net/Lydmn2xn/) to hopefully easily show what's being used, although all of the code is found in the Javascript plugin itself. So far I've tried adding variations of the line $this.fadeIn("slow"); in various spots with no luck. Below is the code for the Javascript plugin with changes I've tried to make. Not sure how to point them out as I can't bold the text in the code. (Note: said changes are not in the Jfiddle, as they don't produce any changes).
$.fn.imagesRotation = function (options) {
var defaults = {
images: [], // urls to images
dataAttr: 'images', // html5 data- attribute which contains an array with urls to images
imgSelector: 'img', // element to change
interval: 1500, // ms
intervalFirst: 1500, // first image change, ms
callback: null // first argument would be the current image url
},
settings = $.extend({}, defaults, options);
var clearRotationInterval = function ($el) {
clearInterval($el.data('imagesRotaionTimeout'));
$el.removeData('imagesRotaionTimeout');
clearInterval($el.data('imagesRotaionInterval'));
$el.removeData('imagesRotaionInterval');
},
getImagesArray = function ($this) {
var images = settings.images.length ? settings.images : $this.data(settings.dataAttr);
return $.isArray(images) ? images : false;
},
preload = function (arr) { // images preloader
$(arr).each(function () {
$('<img/>')[0].src = this;
$this.fadeIn("slow");
});
},
init = function () {
var imagesToPreload = [];
this.each(function () { // preload next image
var images = getImagesArray($(this));
if (images && images.length > 1) {
imagesToPreload.push(images[1]);
}
});
preload(imagesToPreload);
};
init.call(this);
this.on('mouseenter.imagesRotation', function () {
var $this = $(this),
$img = settings.imgSelector ? $(settings.imgSelector, $this) : null,
images = getImagesArray($this),
imagesLength = images ? images.length : null,
changeImg = function () {
var prevIndex = $this.data('imagesRotationIndex') || 0,
index = (prevIndex + 1 < imagesLength) ? prevIndex + 1 : 0,
nextIndex = (index + 1 < imagesLength) ? index + 1 : 0;
$this.data('imagesRotationIndex', index);
if ($img && $img.length > 0) {
if ($img.is('img')) {
$img.attr('src', images[index]);
$this.fadeIn('slow');
}
else {
$img.css('background-image', 'url(' + images[index] + ')');
$img.fadeIn('slow');
}
}
if (settings.callback) {
settings.callback(images[index]);
}
preload([images[nextIndex]]); // preload next image
};
if (imagesLength) {
clearRotationInterval($this); // in case of dummy intervals
var timeout = setTimeout(function () {
changeImg();
var interval = setInterval(changeImg, settings.interval);
$this.data('imagesRotaionInterval', interval); // store to clear interval on mouseleave
}, settings.intervalFirst);
$this.data('imagesRotaionTimeout', timeout);
}
}).on('mouseleave.imagesRotation', function () {
clearRotationInterval($(this));
}).on('imagesRotationRemove', function () {
var $this = $(this);
$this.off('.imagesRotation');
clearRotationInterval($this);
});
};
$.fn.imagesRotationRemove = function () {
this.trigger('imagesRotationRemove');
};
Would that do the trick if it was in the right spot, or does fadeIn/Out not apply to preloaded images? Any help or tips are appreciated.
Thanks.

jQuery plugin data mixup with multiple instances

I'm trying to develop a jQuery plugin to display adaptive image galleries. I'm using .data() to store the information for each slide of the gallery.
Everything appears to be working okay when displaying a single gallery, but gets mixed up when trying to have multiple gallery instances on a single page. A rough demo can be viewed here.
Here is the code that is being run:
(function($) {
$.Gallery = function(element, options) {
this.$el = $(element);
this._init(options);
};
$.Gallery.defaults = {
showCarousel : true,
};
$.Gallery.prototype = {
_init : function(options) {
var $this = $(this);
var instance = this;
// Get settings from stored instance
var settings = $this.data('settings');
var slides = $this.data('slides');
// Create or update the settings of the current gallery instance
if (typeof(settings) == 'undefined') {
settings = $.extend(true, {}, $.Gallery.defaults, options);
}
else {
settings = $.extend(true, {}, settings, options);
}
$this.data('settings', settings);
if (typeof(slides) === 'undefined') {
slides = [];
}
$this.data('slides', slides);
instance.updateCarousel();
},
addItems : function(newItems) {
var $this = $(this),
slides = $this.data('slides');
for (var i=0; i<newItems.length; i++) {
slides.push(newItems[i]);
};
},
updateCarousel : function() {
var instance = this,
$this = $(this);
slides = $(instance).data('slides');
var gallery = instance.$el.attr('id');
/* Create carousel if it doesn't exist */
if (instance.$el.children('.carousel').length == 0) {
$('<div class="carousel"><ul></ul></div>').appendTo(instance.$el);
var image = instance.$el.find('img');
};
var carouselList = instance.$el.find('.carousel > ul'),
slideCount = slides.length,
displayCount = carouselList.find('li').length;
if (displayCount < slideCount) {
for (var i=displayCount; i<slides.length; i++) {
slides[i].id = gallery + '-slide-' + i;
slide = $('<img>').attr({src : slides[i].thumb}).appendTo(carouselList).wrap(function() {
return '<li id="' + slides[i].id + '" />'
});
slide.on({
click : function() {
instance.slideTo($(this).parent().attr('id'));
},
});
};
};
},
slideTo : function(slideID) {
var $this = $(this);
var slides = $this.data('slides');
var image;
var $instance = $(this.$el);
$(slides).each( function() {
if (this.id == slideID){
image = this.img;
};
});
$('<img/>').load( function() {
$instance.find('div.image').empty().append('<img src="' + image + '"/>');
}).attr( 'src', image );
},
};
$.fn.gallery = function(options) {
args = Array.prototype.slice.call(arguments, 1);
this.each(function() {
var instance = $(this).data('gallery');
if (typeof(options) === 'string') {
if (!instance) {
console.error('Methods cannot be called until jquery.responsiveGallery has been initialized.');
}
else if (!$.isFunction(instance[options])) {
console.error('The method "' + options + '" does not exist in jquery.responsiveGallery.');
}
else {
instance[options].apply(instance, args);
}
}
else {
if (!instance) {
$(this).data('gallery', new $.Gallery(this, options));
}
}
});
return this;
};
})(jQuery);
$(window).load(function() {
$('#gallery2').gallery();
$('#gallery3').gallery();
$('#gallery2').gallery('addItems', [
{
img: 'images/image2.jpg',
thumb: 'images/image2_thumb.jpg',
desc: 'Image of number 2'
},
{
img: 'images/image3.jpg',
thumb: 'images/image3_thumb.jpg',
desc: 'Image of number 3'
},
{
img: 'images/image4.jpg',
thumb: 'images/image4_thumb.jpg',
desc: 'Image of number 4'
},
{
img: 'images/image5.jpg',
thumb: 'images/image5_thumb.jpg',
desc: 'Image of number 5'
}
]);
$('.pGallery').gallery('addItems', [
{
img: 'images/2.jpg',
thumb: 'images/2_thumb.jpg',
desc: 'Image of number 0'
},
{
img: 'images/image1.jpg',
thumb: 'images/image1_thumb.jpg',
desc: 'The second image'
}
]);
$('.pGallery').gallery('updateCarousel');
});
On the surface it appears to create two galleries with the proper slide structure of:
gallery2
gallery2-slide-0
gallery2-slide-1
gallery2-slide-2
gallery2-slide-3
gallery2-slide-4
gallery2-slide-5
gallery3
gallery3-slide-0
gallery3-slide-1
However, the onclick action doesn't work for the last two slides of Gallery2 (the slides duplicated in both galleries). Upon closer inspection of the DOM, I can see that the slides stored in data for gallery2, have the following ids:
gallery2
gallery2-slide-0
gallery2-slide-1
gallery2-slide-2
gallery2-slide-3
gallery3-slide-0
gallery3-slide-1
I'm not sure what is causing the mix-up or how to fix, so any help would be greatly appreciated.
Thanks
Your problem is that calling $('.pGallery').gallery('addItems'... cause the same objects to be added to the internal structure of both galleries, when you call $('.pGallery').gallery('updateCarousel'); the ids stored in those objects are overwritten.
You need to put a copy of the original objects in there. Do:
addItems : function(newItems) {
var $this = $(this),
slides = $this.data('slides');
for (var i=0; i<newItems.length; i++) {
//slides.push(newItems[i]);
slides.push(jQuery.extend({}, newItems[i]));
};
},
With jQuery.extend({}, oldObject) you can perform a shallow copy;

Categories