
Come and make music this Christmas!

At Christmas, music is everywhere. And this year we’ve joined forces with Big Ear Games to bring you our 'Song for Santa' challenge. This makes it easy for you to create your very own festive tune, plus you may even end up with an extra special present!

How to Start Creating Music
To help your creativity, we’re offering a coupon code that disables ads and allows full experience of the Big Ear game free of charge until 1.1.2021
Install Big Ear. Learn and Make Music
Available for iOS and Android devices
Coupon Activation
Launch the game and play the tutorial
In the hub, just tap the shop icon

In the shop, find the coupons card and tap it

Enter your coupon code: GENELEC in the coupon popup.

You're ready to go!
In case of a game update, you might need to enter the coupon code again
An error has occurred when reading existing sub-variable "title"; see cause exception! The type of the containing value was: extended_hash+string (org.json.JSONObject wrapped into f.e.b.StringModel) ---- FTL stack trace ("~" means nesting-related): - Failed at: ${localizeField(video.properties.titl... [in template "20116#20152#257335" at line 19, column 37] ----
1<#if cmsEntity?has_content>
2<#if cmsEntity.getLocalizedField(profile, "/entity/relationships/videos")?has_content>
3 <#assign vods = cmsEntity.getLocalizedField(profile, "/entity/relationships/videos") >
4 <#assign videos = vods.references>
5</#if>
6<#if videos?has_content>
7<#include "${templatesPath}/227222" /> <@sectionHeader title="${title}" menuTitle="${menuTitle}" cssClasses="bg-gray-light" id="section-video"/>
8
9<#list videos.iterator() as video>
10 <#assign id = video.id>
11 <#if video?index=0 || videos.get(0).properties.isNull("url") && video?index=1>
12 <div id="video-title-${id}" class="video-title-container">
13 <#if !video.properties.isNull("title")>
14 <h2 class="text-bolder">${localizeField(video.properties.title, profile.getCMSLangCode())}</h2>
15 </#if>
16 </div>
17 <#else>
18 <div id="video-title-${id}" class="title-variant video-title-container">
19 <h2 class="text-bolder">${localizeField(video.properties.title, profile.getCMSLangCode())}</h2>
20 </div>
21 </#if>
22</#list>
23<br>
24
25
26<div class="zoom-gallery-video">
27 <div class="d-none d-lg-block">
28 <#list videos.iterator() as video>
29 <#if !video.properties.isNull("url")>
30 <#assign videoURL = "${video.properties.url}">
31 <#assign id = video.id>
32 <#if videoURL?contains("youtu.be")>
33 <#assign videoID = videoURL?split("/")?last />
34 <#if video?index=0>
35 <div class="responsive-video">
36 <div data-slide-id="video-${id}" class="zoom-gallery-slide-video video-slide responsive-wrapper active youtube" data-embed="${videoID}" id="video-${id}">
37 <span class="icon-play"></span>
38 <span class="round-button"></span>
39 </div>
40 </div>
41 <#elseif videos.get(video?index).properties.isNull("url") && video?index=video?index+1>
42 <div class="responsive-video">
43 <div data-slide-id="video-${id}" class="zoom-gallery-slide-video video-slide responsive-wrapper active youtube" data-embed="${videoID}" id="video-${id}">
44 <span class="icon-play"></span>
45 <span class="round-button"></span>
46 </div>
47 </div>
48 <#else>
49 <div class="responsive-video">
50 <div data-slide-id="video-${id}" class="zoom-gallery-slide-video video-slide responsive-wrapper youtube" id="video-${id}">
51 </div>
52 </div>
53 </#if>
54 <#elseif videoURL?contains("youtube")>
55 <#assign videoID = videoURL?replace("^.*\\?v=([\\w-_]*).*", "$1", "r") />
56 <#if video?index=0>
57 <div class="responsive-video">
58 <div data-slide-id="video-${id}" class="zoom-gallery-slide-video video-slide responsive-wrapper active youtube" data-embed="${videoID}" id="video-${id}">
59 <span class="icon-play"></span>
60 <span class="round-button"></span>
61 </div>
62 </div>
63 <#elseif videos.get(video?index).properties.isNull("url") && video?index=video?index+1>
64 <div class="responsive-video">
65 <div data-slide-id="video-${id}" class="zoom-gallery-slide-video video-slide responsive-wrapper active youtube" data-embed="${videoID}" id="video-${id}">
66 <span class="icon-play"></span>
67 <span class="round-button"></span>
68 </div>
69 </div>
70 <#else>
71 <div class="responsive-video">
72 <div data-slide-id="video-${id}" class="zoom-gallery-slide-video video-slide responsive-wrapper youtube" id="video-${id}">
73 </div>
74 </div>
75 </#if>
76 <#elseif videoURL?contains("vimeo")>
77 <#assign videoID = videoURL?split("/")?last />
78 <#if video?index=0>
79 <div class="responsive-video">
80 <div data-slide-id="video-${id}" class="zoom-gallery-slide-video video-slide responsive-wrapper active vimeo" data-embed="${videoID}" id="video-${id}">
81 <span class="icon-play"></span>
82 <span class="round-button"></span>
83 </div>
84 </div>
85 <#elseif videos.get(0).properties.isNull("url") && video?index=1>
86 <div class="responsive-video">
87 <div data-slide-id="video-${id}" class="zoom-gallery-slide-video video-slide responsive-wrapper active vimeo" data-embed="${videoID}" id="video-${id}">
88 <span class="icon-play"></span>
89 <span class="round-button"></span>
90 </div>
91 </div>
92 <#else>
93 <div class="responsive-video">
94 <div data-slide-id="video-${id}" class="zoom-gallery-slide-video video-slide responsive-wrapper vimeo" id="video-${id}">
95 <span class="icon-play"></span>
96 <span class="round-button"></span>
97 </div>
98 </div>
99 </#if>
100 </#if>
101 </#if>
102 </#list>
103 </div>
104
105 <div class="selectors">
106 <div class="video-carousel owl-carousel owl-theme">
107 <#list videos.iterator() as video>
108 <#if !video.properties.isNull("url")>
109
110 <#assign videoURL = "${video.properties.url}">
111 <#assign id = video.id>
112 <#if videoURL?contains("youtu.be")>
113 <#assign videoID = videoURL?split("/")?last />
114 <div class="card card-video">
115 <a data-slide-id="video-${id}" class="youThumb videoThumb" data-embed="${videoID}" onclick="updateVideoTitle('${id}');" data-id="${id}" id="videoThumb-${id}">
116 <span class="icon-play"></span>
117 <span class="round-button"></span>
118 </a>
119 <div class="card-padding text-dark">
120 <#if !video.properties.isNull("title")>
121 <h3>${localizeField(video.properties.title, profile.getCMSLangCode())}</h3>
122 </#if>
123 <#if !video.properties.isNull("summary")>
124 <#assign summary = cmsContentFormatterService.getMarkdown(localizeField(video.properties.summary, profile.getCMSLangCode()))>
125 <div class="small">${summary}</div>
126 </#if>
127 </div>
128 </div>
129 <#elseif videoURL?contains("youtube")>
130 <#assign videoID = videoURL?replace("^.*\\?v=([\\w-_]*).*", "$1", "r") />
131 <div class="card card-video">
132 <a data-slide-id="video-${id}" class="youThumb videoThumb" data-embed="${videoID}" onclick="updateVideoTitle('${id}');" data-id="${id}" id="videoThumb-${id}">
133 <span class="icon-play"></span>
134 <span class="round-button"></span>
135 </a>
136 <div class="card-padding text-dark">
137 <#if !video.properties.isNull("title")>
138 <h3>${localizeField(video.properties.title, profile.getCMSLangCode())}</h3>
139 </#if>
140 <#if !video.properties.isNull("summary")>
141 <#assign summary = cmsContentFormatterService.getMarkdown(localizeField(video.properties.summary, profile.getCMSLangCode()))>
142 <div class="small">${summary}</div>
143 </#if>
144 </div>
145 </div>
146 <#elseif videoURL?contains("vimeo")>
147 <#assign videoID = videoURL?split("/")?last />
148 <div class="card card-video">
149 <a data-slide-id="video-${id}" class="vimeoThumb videoThumb" data-thumb="${videoID}" onclick="updateVideoTitle('${id}');" data-id="${id}" id="videoThumb-${id}">
150 <span class="icon-play"></span>
151 <span class="round-button"></span>
152 </a>
153 <div class="card-padding text-dark">
154 <#if !video.properties.isNull("title")>
155 <h3>${localizeField(video.properties.title, profile.getCMSLangCode())}</h3>
156 </#if>
157 <#if !video.properties.isNull("summary")>
158 <#assign summary = cmsContentFormatterService.getMarkdown(localizeField(video.properties.summary, profile.getCMSLangCode()))>
159 <div class="small">${summary}</div>
160 </#if>
161 </div>
162 </div>
163 </#if>
164 </#if>
165 </#list>
166 </div>
167 </div>
168</div>
169
170<@sectionFooter/>
171
172
173
174
175<script>
176
177function createVimeoUrl(id) {
178 var videoUrl = "https://vimeo.com/"+id;
179 var endpoint = 'https://vimeo.com/api/oembed.json';
180 var url = endpoint + '?url=' + encodeURIComponent(videoUrl) + '&width=1280&autoplay=1';
181 return url;
182};
183
184function loadVimeoJson(url,id,state) {
185 $.ajax({
186 type : "GET",
187 url : url,
188 dataType : "jsonp",
189 processData: false,
190 crossDomain: true,
191 success : function(result) {
192 var target = $("div").find("[data-embed='"+id+"']");
193 if (state === 'thumbnail') {
194 target.append("<img src='"+result.thumbnail_url+"' />");
195 $('.vimeoThumb').append("<img src='"+result.thumbnail_url+"' />");
196 } else if (state == 'video') {
197 target.html(result.html);
198 }
199 }
200 });
201};
202
203$('.vimeo').on('click',function() {
204 var id = $(this).data('embed');
205 var url = createVimeoUrl(id);
206 loadVimeoJson(url,id,'video');
207});
208$('.vimeoThumb').on('click',function() {
209 var id = $(this).data('thumb');
210 var url = createVimeoUrl(id);
211 loadVimeoJson(url,id,'video');
212});
213
214$(document).ready(function() {
215 var vimeo = document.querySelectorAll( ".vimeo" );
216 for (var i = 0; i < vimeo.length; i++) {
217 var url = createVimeoUrl(vimeo[i].dataset.embed);
218 loadVimeoJson(url,vimeo[i].dataset.embed,'thumbnail');
219 }
220});
221
222
223
224$(document).ready(function() {
225 var youtube = document.querySelectorAll( ".youtube" );
226 for (var i = 0; i < youtube.length; i++) {
227 if($(youtube[i]).attr("data-embed") !== undefined){
228 var source = "https://img.youtube.com/vi/"+ youtube[i].dataset.embed +"/maxresdefault.jpg";
229 var image = new Image();
230 image.src = source;
231 image.className = "poster-image";
232 image.setAttribute('onload', "youtube_check($(this))");
233 image.addEventListener( "load", function() {
234 youtube[ i ].appendChild( image );
235 }( i ) );
236 youtube[i].addEventListener( "click", function() {
237 var iframe = document.createElement( "iframe" );
238 iframe.setAttribute( "frameborder", "0" );
239 iframe.setAttribute( "allowfullscreen", "" );
240 iframe.setAttribute( "allow", "autoplay" );
241 iframe.setAttribute( "src", "https://www.youtube.com/embed/"+ this.dataset.embed +"?rel=0&autoplay=1" );
242 this.innerHTML = "";
243 this.appendChild( iframe );
244 } );
245 };
246 };
247});
248
249
250
251$(document).ready(function() {
252 var youThumb = document.querySelectorAll( ".youThumb" );
253 for (var i = 0; i < youThumb.length; i++) {
254 var source = "https://img.youtube.com/vi/"+ youThumb[i].dataset.embed +"/maxresdefault.jpg";
255 var image = new Image();
256 image.className = "poster-img owl-lazy";
257 image.setAttribute('data-src', source);
258 image.setAttribute('onload', "youtube_check($(this)); fixVideoCarouselHeight()");
259 image.addEventListener( "load", function() {
260 youThumb[ i ].appendChild( image );
261 }( i ) );
262 youThumb[i].addEventListener( "click", function() {
263 if ($(window).outerWidth() < 992) {
264 var iframe = document.createElement( "iframe" );
265 iframe.setAttribute( "frameborder", "0" );
266 iframe.setAttribute( "allowfullscreen", "" );
267 iframe.setAttribute( "allow", "autoplay" );
268 iframe.setAttribute( "src", "https://www.youtube.com/embed/"+ this.dataset.embed +"?rel=0&autoplay=1" );
269 iframe.setAttribute( "height", $('.youThumb img').height());
270 iframe.setAttribute( "width", $('.youThumb img').width());
271 this.innerHTML = "";
272 this.appendChild( iframe );
273 }else{
274 var iframe = document.createElement( "iframe" );
275 iframe.setAttribute( "frameborder", "0" );
276 iframe.setAttribute( "allowfullscreen", "" );
277 iframe.setAttribute( "allow", "autoplay" );
278 iframe.setAttribute( "src", "https://www.youtube.com/embed/"+ this.dataset.embed +"?rel=0&autoplay=1" );
279 $('.youtube.active').html("");
280 $('.youtube.active').append( iframe );
281 }
282 } );
283 var thumbnail = ["maxresdefault", "mqdefault", "sddefault", "hqdefault", "default"];
284 var url = $('.poster-img').attr('src');
285 };
286});
287
288function youtube_check(e) {
289 var thumbnail = ["maxresdefault", "sddefault", "mqdefault", "hqdefault", "default"];
290 var url = e.attr("src");
291 if (e[0].naturalWidth === 120 && e[0].naturalHeight === 90) {
292 for (var i = 0, len = thumbnail.length - 1; i < len; i++) {
293 if (url.indexOf(thumbnail[i]) > 0) {
294 e.attr("src", url.replace(thumbnail[i], thumbnail[i + 1]));
295 break;
296 }
297 }
298 }
299};
300
301
302<#--
303 Make the height on the carousel same height
304-->
305function fixVideoCarouselHeight() {
306
307 <#-- There is also lazy loading so all the images might not yet have height... so when we set height for elements
308 have to make sure image is visible/loaded = has height
309
310 And for that reason we have to call this function when carousel page is changed ...
311 -->
312 var maxHeight = Math.max.apply(null, $('.card-video').map(function(){return $(this).height()}));
313 $('.card-video').each(function(index){
314 if ($(this).find("img").height() > 0 ) {
315 $(this).height(maxHeight)
316 }
317 });
318}
319
320
321$('.zoom-gallery-video .selectors a').on('click touch', function(e) {
322 var iframe = $('.active iframe[src*="youtube"],.active iframe[src*="vimeo"]');
323 if (iframe.length) {
324 iframe.attr('src',iframe.attr('src'));
325 }
326 $('.zoom-gallery-video .zoom-gallery-slide-video').removeClass('active');
327 $('.zoom-gallery-video .selectors a').removeClass('active');
328 $(iframe).remove();
329 $('.zoom-gallery-video .zoom-gallery-slide-video[data-slide-id="'+$(this).attr('data-slide-id')+'"]').addClass('active');
330 $(this).addClass('active');
331 $('.youtube.active').innerHTML = "";
332 e.preventDefault();
333 });
334
335$(document).ready(function() {
336 $('.video-carousel').owlCarousel({
337 loop:false,
338 nav:true,
339 dots:false,
340 lazyLoad:true,
341 margin:10,
342 navText : ['<i class="icon-angle-left">','<i class="icon-angle-right">'],
343 responsive:{
344 0:{items:1, slideBy:1},
345 600:{items:1, slideBy:1},
346 1000:{items:3, slideBy:3}
347 },
348});
349});
350
351function updateVideoTitle(id) {
352 if ($(window).outerWidth() >= 992) {
353 $('div[id^=video-title]').hide();
354 $("#video-title-"+id).show();
355 }
356}
357
358
359function updateThumbnail(id) {
360 if ($(window).outerWidth() < 992) {
361 var youThumb = $("#videoThumb-"+id);
362 if ($("#videoThumb-"+id+ " img").length == 0){
363 var source = "https://img.youtube.com/vi/"+ $(youThumb).attr("data-embed") +"/maxresdefault.jpg";
364 var image = new Image();
365 var playButton = document.createElement( "span" );
366 var roundButton = document.createElement( "span" );
367 playButton.setAttribute("class", "icon-play");
368 roundButton.setAttribute("class", "round-button");
369 youThumb.append( playButton );
370 youThumb.append( roundButton );
371 image['src'] = source;
372 image.className = "poster-img";
373 image.setAttribute('onload', "youtube_check($(this))");
374 youThumb.append( image );
375 };
376 };
377};
378
379
380$(document).ready(function() {
381if ($(window).outerWidth() < 992) {
382 var owl = $('.video-carousel');
383owl.owlCarousel();
384owl.on('translated.owl.carousel', function(event) {
385 if ($(".owl-item").hasClass("active")){
386 var id = $(".active").find(".videoThumb").attr("data-id");
387 updateVideoTitle(id);
388 updateThumbnail(id)
389 }
390});
391
392owl.on('change.owl.carousel', function(event) {
393 fixVideoCarouselHeight();
394 if ($(".owl-item").hasClass("active")){
395 var iframe = $('.active iframe[src*="youtube"],.active iframe[src*="vimeo"]');
396 $(iframe).remove();
397 $(".owl-item").removeClass("active");
398 }
399});
400};
401});
402</script>
403
404
405<style>
406
407
408 <#list videos.iterator() as video>
409 <#assign id = video.id>
410
411 .zoom-gallery-video .selectors a[data-slide-id=video-${id}] {
412 position: relative;
413 }
414
415 </#list>
416
417<#-- Small screens videos are displayed only in carousel. So list title is enough otherwise title is shown double and no need for that
418 Wider screens there is main video content and there need to be title for that + title in "list/carousel" for items.
419-->
420@media screen and (max-width: 991px) {
421 #section-video .video-title-container { display: none; }
422}
423
424
425
426</style>
427</#if>
428</#if>
