Knedlíky povýšené na umění. Takové jako u Lázničků vaří málokde

22. 1. 2018
Doba čtení: 9 minut

Sdílet

Ilustrační obrázek
Autor: Depositphotos – AllaSerebrina
Ilustrační obrázek
Firma Knedlíky Láznička nemůže s jinými výrobci knedlíků soupeřit co do velikosti. V kvalitě a chuti ale překoná kdekoho. Sázka na kvalitu se prostě vyplácí.

Je to už pár let, co se Petr Kosiner osamostatnil a začal jako živnostník vařit knedlíky. Jejich kvalita byla od začátku o několik tříd vyšší než běžně dostupná produkce a nezřídka se stávalo, že poptávka převyšovala nabídku a zákazníci odcházeli s prázdnou. Brzy se dostal do uzavřeného kruhu problémů, ze kterého nebylo úniku. Podnikání mu jednoduše přerostlo přes hlavu. Jde o moment, který řadě živnostníků takzvaně zlomí vaz a jejich často velice dobře nastartované plány berou za své. 

Petr Kosiner měl ale štěstí. Našel investora Vladimíra Zikmundu, který v jeho báječných knedlících viděl potenciál a rozhodl se začínajícího podnikatele podpořit. Nejprve se jednalo skutečně jen o investici, ale postupem času se ukázalo, že bude potřeba mnohem víc. Někdo totiž umí vařit knedlíky, jiný je zase schopný manažer. Vést kuchyni, dělat obchody a zajišťovat chod celé firmy bylo na jednoho moc a tak brzy padlo praktické rozhodnutí. Petr Kosiner se začal plně věnovat práci v kuchyni, která ho na jeho podnikání stejně bavila nejvíc, a Vladimír Zikmunda se stal 100% vlastníkem firmy. Takto společnost Knedlíky Láznička funguje od roku 2014 a ukázalo se to být nejlepším řešením.

Vladimír Zikmunda má za sebou mnohaletou manažerskou praxi ve velkých podnicích. Svého času mimo jiné zastřešoval koncepci systémů řízení pro novou Tatru. Ve zralém věku a s řadou zkušeností byl ale najednou postaven před zcela novou výzvu. Měl vést malou firmu, která neměla ambici nijak závratně růst. Chtěla jen dělat špičkovou produkci. Uvědomil jsem si, v jak složité situaci se živnostníci nacházejí. Aby mohli podnikat, musí se orientovat ve spoustě oborů. Stát jim jejich práci nijak neusnadňuje, naopak je spíš zatěžuje povinnostmi a brzdí v rozvoji. Brzy jsem zjistil, že je mnohem snazší vést velkou firmu, kde máte k dispozici specializovaná oddělení, popisuje majitel firmy Vladimír Zikmunda.

Malá firma, v níž dnes pracuje jen deset lidí, se pro něj stala výzvou. A to nejen proto, že začínala prakticky od nuly a bylo potřeba v ní nastavit nové fungování, ale také proto, že kupované knedlíky neměly díky běžně nabízené produkci dobrou pověst. Obliba knedlíků jakožto tradiční přílohy a v některých variantách i jako hlavního chodu totiž v uplynulých desetiletích postupně klesala a bylo na ně pohlíženo s despektem. Je to dáno nejen jiným životním a stravovacím stylem, vinu za odvrat lidí od knedlíků nesl i důraz na jejich výrobu za co nejnižší cenu bez ohledu na kvalitu. Firma Knedlíky Láznička proto kromě jiného začala s osvětou.

Knedlík musí být delikatesa, ne nechutná hmota

Knedlík je zdánlivě jednoduchý výrobek, ale uvařit skutečně chutný a nadýchaný, který nebude jen pouhou přílohou, ale stane se plnohodnotnou součástí jídla, vyžaduje dostatek zkušeností. Průmyslově vyráběné knedlíky dostupné v obchodech se tomuto v naprosté většině případů ani nepřibližují a lidé jsou přesvědčení, že nejlepší knedlík je ten domácí. Petr Kosiner a Vladimír Zikmunda se rozhodli tento stav změnit a přesvědčit konzumenty, že jim dokážou nabídnout ještě lepší než pověstný babiččin knedlík. A ti, kteří ochutnali, jim i přes počáteční nedůvěru musí dát za pravdu. Firemní slogan ne nadarmo hlásá „Povýšili jsme knedlíky na umění“.

Tvrdit, že děláme lepší knedlíky než domácí, považovala řada lidí za nemístnou provokaci a útok na domácí kuchyni. My k tomu ale máme skutečně objektivní důvody. Ani sebelepší kuchařka totiž doma nemá takové podmínky jako my. Nedostane se například ke stejným surovinám, které jsou alfou a omegou, říká Vladimír Zikmunda. Základem je kvalitní mouka. Tu firma odebírá z jednoho mlýna specializovaného na nejnáročnější klientelu. Mouka nikdy není starší než dva týdny, je prostá všech zbytečných příměsí a má tedy úplně jiné vlastnosti než ta, kterou mají k dispozici hospodyně nakupující v běžných obchodech. Do houskových knedlíků se u Lázničků přidává vlastnoručně vyrobené pečivo s originální recepturou upravenou přímo pro použití do knedlíků. Klasické tukové rohlíky v těchto knedlících nenajdete. Těsto na bramborové knedlíky je zase připravováno z kvalitních českých brambor, které zajišťují nejlepší vlastnosti. A takových malých ovšem pro chuť a kvalitu zásadních vychytávek je celá řada.

O tom, jak bude nakonec kynutý knedlík chutnat, samozřejmě rozhoduje i samotné kynutí. Někteří si možná ještě pamatují, jak babičky nechávaly těsto kynout v posteli. Kdo má ale dnes doma peřiny, aby to tak mohl dělat? Kynutí v duchnách mělo své důvody. Šlo o podmínky, které my řešíme technologiemi. V kynárně máme ideální teplotu i vlhkost a těsto kyne v řízené atmosféře, vysvětluje majitel firmy, kde si pochvalují využití moderních technologií, ale zároveň nedají dopustit na ruční práci. Rozdíl mezi knedlíkem uváleným strojně ve velkokapacitní výrobě a tím z malovýroby, který prošel lidskýma rukama, je totiž vidět. A u některých typů knedlíků není strojová výroba ani možná. Ovocné knedlíky z velkovýroby se plní injektáží. Vpravuje se do nich podivná marmeládě podobná směs. My do knedlíků dáváme zásadně jen kusové ovoce a to jinak než ručně zabalit nejde, komentuje Vladimír Zikmunda. Takový přístup je sice dražší, ale knedlíky Láznička nejsou pro ty, kdo chtějí ušetřit. Ocení je ti, kteří si chtějí především pochutnat.

V rámci osvěty se firma zaměřuje na historické receptury, různé možnosti využití knedlíků, krajové speciality a rodinné recepty. Knedlíky jakožto plnohodnotnou potravinu ukazuje nejen na svém webu, ale především na sociální síti. A daří se jí to. Ačkoli působí jen v malém regionu, na Facebooku její profil sleduje přes 22 000 lidí. Sledují nás i ti, kteří naše zboží nemají šanci koupit, protože k nim nedodáváme. Tato osvěta tedy nemá bezprostředně komerční cíl. Mezi našimi fanoušky jsou i Češi žijící v zahraničí. Jsme pro lidi inspirací a oni se díky našim příspěvkům vrací do dětství. Prezentujeme totiž spoustu zapomenutých jídel, která z našich stolů postupně vymizela. Brzy vydáme už 150. díl knedlíkového seriálu, říká Vladimír Zikmunda. S Facebookem firma začala relativně pozdě, profil si na něm zřídila teprve před třemi lety, přesto dokázala to, co jiní ani zdaleka. Má velmi aktivní komunitu, která ráda sdílí své kulinářské výtvory. A na fotkách se vůbec nemusí objevit knedlíky značky Láznička. V tomto případě jde o knedlík jako takový. Ať už domácí nebo kupovaný od Lázničky.

50 druhů knedlíků, žádný problém

Když majitel firmy někde řekne, že vyrábí přes 50 druhů knedlíků, mnozí tomu nechtějí věřit. Nabídka je ale skutečně velmi pestrá. Jejím základem jsou přílohové knedlíky v kynuté houskové nebo bramborové podobě v nejrůznějších obměnách. Dále knedlík karlovarský, bylinkový, špekový, posvícenský nebo svatební. Posledně jmenovaný představuje skutečnou špičku a je připraven ve stylu Magdaleny Dobromily Rettigové. Nechybí ani oblíbené knedlíky plněné uzeným masem nebo ovocem. A k tomu jsou tu ještě sezónní speciality. V listopadu a prosinci to byl knedlík perníkový hodící se ke zvěřině, nabídku pro únor a březen ozvláštní křenový knedlík podle staré klášterní receptury a řeznický bramborový knedlík se škvarky.

Nabídka se neustále mění a odpovídá sezóně. Naše knedlíky totiž neobsahují žádné zbytečné konzervanty a jsou určené k okamžité spotřebě. Proto u nás v zimě nedostanete třeba tolik poptávané jahodové knedlíky. Ty totiž děláme výhradně z čerstvých jahod v době, kdy na plantážích v Praze-Kunraticích zrají. Jen po omezenou dobu jsou k dostání také švestkové nebo hruškové knedlíky. Celoročně nabízíme sladké varianty jen s borůvkami, malinami a meruňkami. Borůvky a maliny bereme část roku ze zahraničí a meruňky používáme kompotované, protože jsou do knedlíků lepší než čerstvé ovoce, vysvětluje majitel knedlíkárny.

Důraz na čerstvost a co nejrychlejší spotřebu firmu svým způsobem limituje v možnostech rozšiřování okruhu prodeje, ale to není důležité. Dodáváme do mnohem menší oblasti, než kterou představují naši fanoušci na Facebooku a někteří nám to mají za zlé. Chtěli by naše knedlíky zkusit, ale logistika to zkrátka neumožňuje. Jednou jsme řešili i možnost dodání knedlíků na svatební hostinu na Floridě. Zákazník na dodání trval, a dokonce se nám podařilo najít způsob rychlé přepravy, při které by knedlíky neztratily nic ze své kvality. Její cena ale byla natolik vysoká, že z toho nakonec stejně sešlo, říká Vladimír Zikmunda.

Knedlíky od něj odebírají především restaurace. Jde zejména o podniky pro náročnější klientelu, pro kterou je kvalita mnohem důležitější než nízká cena. Vladimír Zikmunda tvrdí, že díky specializaci a životní vášni knedlíkového mága Petra Kosinera, který má na starosti výrobu, dokáže být firma pro restaurace zajímavá nejen chuťově, ale i finančně. Po Praze objednávky i sama rozváží a k tomu je velmi flexibilní a vychází vstříc požadavkům zákazníků. Odmítá jen takové, kvůli kterým by utrpěla kvalita knedlíků. Významnou skupinu zákazníků tvoří cateringové společnosti, které si mohou objednat zboží přímo na míru pro jednotlivé akce. Například karlovarské knedlíky dělá firma v deseti různých formátech. A i přes vyšší cenu se stále rozrůstá zájem škol a školek. Rodičům už totiž není jedno, že dětem v jídelnách nechutná a chtějí pro ně kvalitní jídlo, které jejich potomci s chutí snědí. V konečném důsledku to ani není nijak zvlášť dražší varianta, protože knedlíky jsou skutečně poctivé a jeden meruňkový dítě ve školce spolehlivě zasytí. Dva jsou pak slušnou porcí i pro dospělého.

V úplných počátcích, kdy firmu ještě plně ovládal Petr Kosiner, fungovala v Holešovicích specializovaná knedlíková prodejna. Ta už je ale minulostí. Jednotlivci si mohou knedlíky koupit přímo z výrobny v Petrovicích, kam se pro své objednávky sjíždí i majitelé restaurací a cateringových společností mimo hlavní město. Další možností je pak nákup v online obchodech Světbedýnek.cz a Rohlík.cz. Dřív jsme naše knedlíky nabízeli i ve farmářských prodejnách, a zprostředkovaně dokonce i na farmářských trzích. Naráželi jsme ale na problémy se skladováním. Internetové obchody s potravinami jsou pro nás momentálně nejlepším řešením. Světbedýnek odebírá zboží jen na základě předem potvrzených objednávek od zákazníků a Rohlík pak každý den určitý počet v takovém objemu, jaký je schopný rychle prodat. Knedlíky se tak na stoly zákazníků dostávají do 24 nebo maximálně 48 hodin od výroby, popisuje podnikatel.

MM25_Copy

Knedlíková osvěta se vyplatila

Pokud má čtenář stále ještě pochyby o vysoké kvalitě knedlíků Láznička, může ho o ní přesvědčit i řada ocenění. Ta firma v soutěži Česká chuťovka sbírá už od roku 2014 a na kontě už jich má celkem 12. Mezi poslední oceněné patří perníkový knedlík, který ocenila nejen odborná, ale i dětská porota. Ocenění jsou skvělá pro marketing a firmě pomohla zejména v začátcích, kdy mýtus, že doma vyrobený knedlík je lepší než ten koupený, vůbec nebylo snadné vyvrátit.

Zdá se, že by firma Knedlíky Láznička mohla rychle expandovat. Majitel ji ale drží při zemi. Zvyšující se poptávka mu dělá radost, ale mnohem víc ho těší změna její struktury. Každý nový zákazník má vyšší nároky a chápe, že kvalitní knedlík není jen kus hmoty, který má strávníkům zaplnit žaludky. Jsem rád, že se nám daří vracet knedlíky na talíře i ve vybraných podnicích. Při naší velikosti nemáme ambice ovlivnit celý trh, náš tržní podíl je v řádech jednotek promile. Orientujeme se jen na určitou klientelu, která dokáže ocenit špičkovou kvalitu. Měli jsme spoustu poptávek od firem vyrábějících laciné hotovky, které chtěly naše knedlíky za určitou cenu a bylo jim jedno, jak je vyrobíme. To pro nás ale nejsou zákazníci. Nechceme být vnímáni jako běžná laciná značka a stavíme na tom i náš marketing. Ceny jsou ale rozumné. Finanční rozdíl mezi mizerným knedlíkem, který je kvůli požadavkům na nízkou cenu a trvanlivost plný chemie, a jeho špičkovou podobou, není až takový, jak by se mohlo zdát, říká Vladimír Zikmunda.

'; document.getElementById('preroll-iframe').onload = function () { setupIframe(); } prerollContainer = document.getElementsByClassName('preroll-container-iframe')[0]; } function setupIframe() { prerollDocument = document.getElementById('preroll-iframe').contentWindow.document; let el = prerollDocument.createElement('style'); prerollDocument.head.appendChild(el); el.innerText = "#adContainer>div:nth-of-type(1),#adContainer>div:nth-of-type(1) > iframe { width: 99% !important;height: 99% !important;max-width: 100%;}#videoContent,body{ width:100vw;height:100vh}body{ font-family:'Helvetica Neue',Arial,sans-serif}#videoContent{ overflow:hidden;background:#000}#adMuteBtn{ width:35px;height:35px;border:0;background:0 0;display:none;position:absolute;fill:rgba(230,230,230,1);bottom:20px;right:25px}"; videoContent = prerollDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('PREROLL sound allowed'); // setUpIMA(true); videoContent.volume = 1; videoContent.muted = false; setUpIMA(); }).catch(function () { console.log('PREROLL sound forbidden'); videoContent.volume = 0; videoContent.muted = true; setUpIMA(); }); } } function setupDimensions() { prerollWidth = Math.min(iinfoPrerollPosition.offsetWidth, 480); prerollHeight = Math.min(iinfoPrerollPosition.offsetHeight, 320); } function setUpIMA() { google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true); google.ima.settings.setLocale('cs'); google.ima.settings.setNumRedirects(10); // Create the ad display container. createAdDisplayContainer(); // Create ads loader. adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Listen and respond to ads loaded and error events. adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); // An event listener to tell the SDK that our content video // is completed so the SDK can play any post-roll ads. const contentEndedListener = function () { adsLoader.contentComplete(); }; videoContent.onended = contentEndedListener; // Request video ads. const adsRequest = new google.ima.AdsRequest(); adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Preroll advert: ' + iinfoVastUrls[iinfoVastUrlIndex]); videoContent.muted = false; videoContent.volume = 1; // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. // adsRequest.linearAdSlotWidth = prerollWidth; // adsRequest.linearAdSlotHeight = prerollHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. prerollDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( prerollDocument.getElementById('adContainer'), videoContent); } function unmutePrerollAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } } function onAdsManagerLoaded(adsManagerLoadedEvent) { // Get the ads manager. const adsRenderingSettings = new google.ima.AdsRenderingSettings(); adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; adsRenderingSettings.loadVideoTimeout = 12000; // videoContent should be set to the content video element. adsManager = adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings); // Add listeners to the required events. adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested); adsManager.addEventListener( google.ima.AdEvent.Type.ALL_ADS_COMPLETED, onAdEvent); // Listen to any additional events, if necessary. adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, onAdEvent); playAds(); } function playAds() { // Initialize the container. Must be done through a user action on mobile // devices. videoContent.load(); adDisplayContainer.initialize(); // setupDimensions(); try { // Initialize the ads manager. Ad rules playlist will start at this time. adsManager.init(1920, 1080, google.ima.ViewMode.NORMAL); // Call play to start showing the ad. Single video and overlay ads will // start at this time; the call will be ignored for ad rules. adsManager.start(); // window.addEventListener('resize', function (event) { // if (adsManager) { // setupDimensions(); // adsManager.resize(prerollWidth, prerollHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } function onAdEvent(adEvent) { const ad = adEvent.getAd(); console.log('Preroll event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: if (!ad.isLinear()) { videoContent.play(); } prerollDocument.getElementById('adContainer').style.width = '100%'; prerollDocument.getElementById('adContainer').style.maxWidth = '640px'; prerollDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); if (ad.isLinear()) { intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } prerollDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (prerollLastError === 303) { playYtVideo(); } break; case google.ima.AdEvent.Type.COMPLETE: if (ad.isLinear()) { clearInterval(intervalTimer); } playYtVideo(); break; } } function onAdError(adErrorEvent) { console.log(adErrorEvent.getError()); prerollLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { playYtVideo(); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoPrerollPosition.remove(); playPrerollAd(); } else { return false; } adVolume = 1; return true; } function onContentPauseRequested() { videoContent.pause(); } function onContentResumeRequested() { videoContent.play(); } function onActiveView() { if (prerollContainer) { const containerOffset = prerollContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (prerollPaused) { adsManager.resume(); prerollPaused = false; } return true; } else { if (!prerollPaused) { adsManager.pause(); prerollPaused = true; } } } return false; } function playYtVideo() { iinfoPrerollPosition.remove(); youtubeIframe.style.display = 'block'; youtubeIframe.src += '&autoplay=1&mute=1'; } }
Upozorníme vás na články, které by vám neměly uniknout (maximálně 2x týdně).
'; document.getElementById('outstream-iframe').onload = function () { setupIframe(); } replayScreen = document.getElementById('iinfoOutstreamReplay'); iinfoOutstreamPosition = document.getElementById('iinfoOutstreamPosition'); outstreamContainer = document.getElementsByClassName('outstream-container')[0]; setupReplayScreen(); } function setupIframe() { outstreamDocument = document.getElementById('outstream-iframe').contentWindow.document; let el = outstreamDocument.createElement('style'); outstreamDocument.head.appendChild(el); el.innerText = "#adContainer>div:nth-of-type(1),#adContainer>div:nth-of-type(1) > iframe { width: 99% !important;height: 99% !important;max-width: 100%;}#videoContent,body{ width:100vw;height:100vh}body{ font-family:'Helvetica Neue',Arial,sans-serif}#videoContent{ overflow:hidden;background:#000}#adMuteBtn{ width:35px;height:35px;border:0;background:0 0;display:none;position:absolute;fill:rgba(230,230,230,1);bottom:-5px;right:25px}"; videoContent = outstreamDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; if ( location.href.indexOf('rejstriky.finance.cz') !== -1 || location.href.indexOf('finance-rejstrik') !== -1 || location.href.indexOf('firmy.euro.cz') !== -1 || location.href.indexOf('euro-rejstrik') !== -1 || location.href.indexOf('/rejstrik/') !== -1 || location.href.indexOf('/rejstrik-firem/') !== -1) { outstreamDirectPlayed = true; soundAllowed = true; iinfoVastUrlIndex = 0; } if (!outstreamDirectPlayed) { console.log('OUTSTREAM direct'); setUpIMA(true); } else { if (soundAllowed) { const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('OUTSTREAM sound allowed'); setUpIMA(false); }).catch(function () { console.log('OUTSTREAM sound forbidden'); renderBanner(); }); } } else { renderBanner(); } } } function getWrapper() { let articleWrapper = document.querySelector('.rs-outstream-placeholder'); // Outstream Placeholder from RedSys manipulation if (articleWrapper && articleWrapper.style.display !== 'block') { articleWrapper.innerHTML = ""; articleWrapper.style.display = 'block'; } // Don't render OutStream on homepages if (articleWrapper === null) { if (document.querySelector('body.p-index')) { return null; } } if (articleWrapper === null) { articleWrapper = document.getElementById('iinfo-outstream'); } if (articleWrapper === null) { articleWrapper = document.querySelector('.layout-main__content .detail__article p:nth-of-type(6)'); } if (articleWrapper === null) { // Euro, Autobible, Zdravi articleWrapper = document.querySelector('.o-article .o-article__text p:nth-of-type(6)'); } if (articleWrapper === null) { articleWrapper = document.getElementById('sidebar'); } if (!articleWrapper) { console.error("Outstream wrapper of article was not found."); } return articleWrapper; } function setupDimensions() { outstreamWidth = Math.min(iinfoOutstreamPosition.offsetWidth, 480); outstreamHeight = Math.min(iinfoOutstreamPosition.offsetHeight, 320); } /** * Sets up IMA ad display container, ads loader, and makes an ad request. */ function setUpIMA(direct) { google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true); google.ima.settings.setLocale('cs'); google.ima.settings.setNumRedirects(10); // Create the ad display container. createAdDisplayContainer(); // Create ads loader. adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Listen and respond to ads loaded and error events. adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); // An event listener to tell the SDK that our content video // is completed so the SDK can play any post-roll ads. const contentEndedListener = function () { adsLoader.contentComplete(); }; videoContent.onended = contentEndedListener; // Request video ads. const adsRequest = new google.ima.AdsRequest(); if (direct) { adsRequest.adTagUrl = directVast; console.log('Outstream DIRECT CAMPAING advert: ' + directVast); videoContent.muted = true; videoContent.volume = 0; outstreamDirectPlayed = true; } else { adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Outstream advert: ' + iinfoVastUrls[iinfoVastUrlIndex]); videoContent.muted = false; videoContent.volume = 1; } // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. // adsRequest.linearAdSlotWidth = outstreamWidth; // adsRequest.linearAdSlotHeight = outstreamHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function setupReplayScreen() { replayScreen.addEventListener('click', function () { iinfoOutstreamPosition.remove(); iinfoVastUrlIndex = 0; outstreamInit(); }); } /** * Sets the 'adContainer' div as the IMA ad display container. */ function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. outstreamDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( outstreamDocument.getElementById('adContainer'), videoContent); } function unmuteAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } } /** * Loads the video content and initializes IMA ad playback. */ function playAds() { // Initialize the container. Must be done through a user action on mobile // devices. videoContent.load(); adDisplayContainer.initialize(); // setupDimensions(); try { // Initialize the ads manager. Ad rules playlist will start at this time. adsManager.init(1920, 1080, google.ima.ViewMode.NORMAL); // Call play to start showing the ad. Single video and overlay ads will // start at this time; the call will be ignored for ad rules. adsManager.start(); // window.addEventListener('resize', function (event) { // if (adsManager) { // setupDimensions(); // adsManager.resize(outstreamWidth, outstreamHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } /** * Handles the ad manager loading and sets ad event listeners. * @param { !google.ima.AdsManagerLoadedEvent } adsManagerLoadedEvent */ function onAdsManagerLoaded(adsManagerLoadedEvent) { // Get the ads manager. const adsRenderingSettings = new google.ima.AdsRenderingSettings(); adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; adsRenderingSettings.loadVideoTimeout = 12000; // videoContent should be set to the content video element. adsManager = adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings); // Add listeners to the required events. adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested); adsManager.addEventListener( google.ima.AdEvent.Type.ALL_ADS_COMPLETED, onAdEvent); // Listen to any additional events, if necessary. adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, onAdEvent); playAds(); } /** * Handles actions taken in response to ad events. * @param { !google.ima.AdEvent } adEvent */ function onAdEvent(adEvent) { // Retrieve the ad from the event. Some events (for example, // ALL_ADS_COMPLETED) don't have ad object associated. const ad = adEvent.getAd(); console.log('Outstream event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: // This is the first event sent for an ad - it is possible to // determine whether the ad is a video ad or an overlay. if (!ad.isLinear()) { // Position AdDisplayContainer correctly for overlay. // Use ad.width and ad.height. videoContent.play(); } outstreamDocument.getElementById('adContainer').style.width = '100%'; outstreamDocument.getElementById('adContainer').style.maxWidth = '640px'; outstreamDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); // This event indicates the ad has started - the video player // can adjust the UI, for example display a pause button and // remaining time. if (ad.isLinear()) { // For a linear ad, a timer can be started to poll for // the remaining time. intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } outstreamDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (outstreamLastError === 303) { if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } } break; case google.ima.AdEvent.Type.COMPLETE: // This event indicates the ad has finished - the video player // can perform appropriate UI actions, such as removing the timer for // remaining time detection. if (ad.isLinear()) { clearInterval(intervalTimer); } if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } break; } } /** * Handles ad errors. * @param { !google.ima.AdErrorEvent } adErrorEvent */ function onAdError(adErrorEvent) { // Handle the error logging. console.log(adErrorEvent.getError()); outstreamLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { renderBanner(); } } function renderBanner() { if (isBanner) { console.log('Outstream: Render Banner'); iinfoOutstreamPosition.innerHTML = ""; iinfoOutstreamPosition.style.height = "330px"; iinfoOutstreamPosition.appendChild(bannerDiv); } else { console.log('Outstream: Banner is not set'); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoOutstreamPosition.remove(); outstreamInit(); } else { return false; } adVolume = 1; return true; } /** * Pauses video content and sets up ad UI. */ function onContentPauseRequested() { videoContent.pause(); // This function is where you should setup UI for showing ads (for example, // display ad timer countdown, disable seeking and more.) // setupUIForAds(); } /** * Resumes video content and removes ad UI. */ function onContentResumeRequested() { videoContent.play(); // This function is where you should ensure that your UI is ready // to play content. It is the responsibility of the Publisher to // implement this function when necessary. // setupUIForContent(); } function onActiveView() { if (outstreamContainer) { const containerOffset = outstreamContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (outstreamPaused) { adsManager.resume(); outstreamPaused = false; } return true; } else { if (!outstreamPaused) { adsManager.pause(); outstreamPaused = true; } } } return false; } let outstreamInitInterval; if (typeof cpexPackage !== "undefined") { outstreamInitInterval = setInterval(tryToInitializeOutstream, 100); } else { const wrapper = getWrapper(); if (wrapper) { let outstreamInitialized = false; window.addEventListener('scroll', () => { if (!outstreamInitialized) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { outstreamInit(); outstreamInitialized = true; } } }); } } function tryToInitializeOutstream() { const wrapper = getWrapper(); if (wrapper) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { if (cpexPackage.adserver.displayed) { clearInterval(outstreamInitInterval); outstreamInit(); } } } else { clearInterval(outstreamInitInterval); } } }
OSZAR »