Suší jídlo mrazem. Lyofilizace potravin má budoucnost, věří výrobce

6. 11. 2018

Sdílet

Lyofilizované potraviny nepotřebují chlad ani mráz. Pokud jsou dobře usušené a zabalené, vystačí si s pokojovou teplotou. „Potenciál takto upravených potravin je velký a nedovedu dohlédnout na jeho konec,“ říká Karel Schmiedberger.

Lyofilizace potravin se dostává stále více do popředí zájmu spotřebitelů. Uvádí se, že jídlo sušené mrazem je zdravé a bez přístupu vzduchu vydrží dlouho. Hodí se pro přímou konzumaci, třeba jako přísada do suchých snídaňových směsí. Cena je však poměrně vysoká. O tom, jak uchovat potraviny pomocí procesu lyofilizace, ví nejvíce Karel Schmiedberger – člověk, který lyofilizační přístroje vyrábí.

Kde vznikla myšlenka na založení firmy vyrábějící lyofilizační přístroje a jak dlouho už fungujete na trhu?

Laboratorní lyofilizátory dovážíme do Česka už přes dvacet let. V úzce specializované firmě, kterou založil můj táta, sám působím patnáctým rokem. Díky našemu zaměření nás v posledních letech začali více vyhledávat zájemci o sušení potravin mrazem – lyofilizaci. Naši tradiční výrobci sice nabízejí přístroje pro nevědecké použití, například pro lyofilizaci květin nebo kávy, ale poptávka po malém, a především cenově dostupném přístroji je nechávala chladnými. Proto jsme se před dvěma lety dohodli s kolegou, který zajišťuje servis těchto strojů, že dáme dohromady vlastní produkt, který bude splňovat požadavky zájemců o tento segment.

První rok a půl zabral pouze vývoj, testování, pokusy a omyly. Teprve loni jsme získali potřebné certifikáty pro uvedení přístroje na trh v rámci EU a letos jsme začali prodávat první kusy. Potraviny se ve větším měřítku lyofilizují už deset, možná dvacet let, ale je to jako se vším – nejprve si to mohou dovolit jenom ty největší nadnárodní firmy, a my dnes přinášíme tuto možnost pro rodinné farmy a malé podnikatele.

Kolik takový stroj stojí a co všechno potřebuje ke své práci?

Náš AMARU, který poskytne kapacitu 5–7 kg surových potravin, nabízíme za necelých 390 tisíc korun bez DPH. Umíme ale nabídnout i větší, průmyslové přístroje zahraničních výrobců s kapacitou 18, 80 nebo až 1500 kg. Tyto ovšem začínají na ceně kolem 4,5 mil. Kč bez DPH, a tak nejsou úplně vhodné pro začínající podnikatele a živnostníky, kteří si chtějí vyzkoušet vlastní výrobu sušených potravin v menším měřítku. Z energií náš lyofilizátor pro práci potřebuje pouze jednofázovou elektrickou 16A zásuvku. Pokud si zájemce chce počítat náklady, je třeba také zahrnout minerální olej pro vakuovou vývěvu. Ten se mění poměrně často a vychází na necelých 50 korun za jeden sušící proces.

A existují různé přístroje pro mražení různých potravin a předmětů, nebo vše splňuje za stejných podmínek pouze jedno zařízení?

Univerzální zařízení neexistuje. Existují laboratorní lyofilizátory pro biotechnologický průmysl, které umožňují i vysušení alkoholu. Jde o přístroje, které za dané peníze nenabízejí moc velkou kapacitu, avšak jsou zpravidla naplněny řadou funkcí, sond a programů pro výzkum. Řada světových výrobců nabízí tzv. GPFD (General Purpose Freeze Dryer) lyofilizátory, které sám označuji za „nevědecké“. Ty mohou sloužit pro lyofilizaci knih postižených povodněmi nebo květin. Využívají je také archeologové, kdy se v gigantickém přístroji půl roku vysouší dřevěný vrak středověké lodi vytažený ze dna oceánu. V Evropě nepříliš časté je použití i v oblasti taxidermie neboli vycpávání zvířat. Samostatnou kapitolou jsou pak potravinářské lyofilizátory, které se zdaleka nesnaží být tolik citlivé vůči produktu, protože jde především o co nejkratší proces. Lyofilizace květin běžně trvá osm až čtrnáct dní, u potravin je akceptováno maximum tří dnů.

Pracujete na nějakém zdokonalování přístrojů?

V první řadě bychom rádi náš lyofilizátor AMARU dostali do nabídky pro Evropskou unii. V současnosti distribuujeme pouze v rámci České republiky a Slovenska, naši stávající zákazníci jsou takoví beta-testeři. S každým se znám osobně a často řešíme, co za funkce by uvítali nebo co se jim podařilo usušit. Předpokládám, že do dalších zemí budeme expandovat v roce 2019. Zjevně nevyhnutelné bude také stěhování do nové výrobní dílny. Ta naše, umístěná v suterénu činžovního domu na Břevnově, nám pomalu přestává stačit.

Na zlepšení stávajícího přístroje pracujeme průběžně. Zkoušíme různé výrobce součástek i všelijaké materiály tak, abychom docílili dlouhé životnosti a snadné manipulace ze strany obsluhy. Snadno se vymyslí například GSM modul, aby lyofilizátor poslal SMS, že proces je hotový, ale dostat toto k zákazníkům už vyžaduje mnoho času na testování a ještě více peněz na získání certifikace.

Četla jsem, že lyofilizované potraviny se využívaly u kosmonautů. Víte něco o tom?

Jednou z hlavních vlastností lyofilizovaných potravin je snížená hmotnost až o 90 %. Toto si NASA dobře uvědomovala již začátkem 60. let minulého století u programu Mercury. Jídlo během misí Mercury a Gemini asi nebylo žádný gurmánský zážitek, ovšem při misích Apollo už astronauti měli k dispozici horkou vodu. NASA jim tak mohla připravit speciální balení vybavené lžící a ventilkem pro rehydrataci jídla. Astronautům toto údajně pomáhalo i po psychické stránce, protože předem viděli, co budou jíst, a nemuseli si do úst mačkat pastu z neprůhledné tuby.

Jaké si myslíte, že má lyofilizace do budoucna uplatnění? Je možné, že bude poptávka po takto upravených potravinách z nějakého důvodu stále větší?

Lyofilizované potraviny se vyznačují sníženou hmotností, dlouhou trvanlivostí, zachováním vzhledu, možností rehydratace a snadným skladováním. Pro každého může hrát roli jiný z těchto aspektů. Někdo bude chtít doma rezervu lyofilizovaných vajec, když dojdou čerstvá, jiný zase upotřebí suchou zmrzlinu ve svém receptu. A samozřejmě outdoorový turista ocení, že s sebou nemusí tahat zbytečnou vodu.

Sám přisuzuji lyofilizaci dobrou budoucnost. Vezměte si historii mrazicích boxů. Ledničku nebo mrazák měly nejprve velké potravinářské podniky, následně se dostaly v menším provedení do vybraných restaurací a záhy v ještě kompaktnější verzi do bohatých rodin. Dnes je má každý, lednice váží o třetinu méně a cenu ani nemá smysl zmiňovat. Hodně lidí si kupuje ledničku s malým mrazákem do kuchyně a objemný pultový box pro uchování větších zásob do sklepa. Lyofilizované potraviny nepotřebují chlad ani mráz. Pokud jsou dobře usušené a zabalené, vystačí si s pokojovou teplotou.

A jak dlouho vlastně jídlo sušené mrazem vydrží?

Záleží na mnoha faktorech. Řešili jsme tuto otázku s odborníkem z Výzkumného ústavu potravinářského Praha a prakticky bude mít každá potravina jinou životnost, stejně jako v čerstvém stavu. Maso obsahující tuky vydrží méně než třeba ryze sacharidové ovoce. Velkou proměnnou je obal, protože lyofilizované potraviny musí být uchovány bez přístupu okolního vzduchu, ve kterém je vlhkost. Někdo může použít zatavovací pytlíky s pohlcovačem kyslíku, případně vakuovou baličku nebo balení v ochranné atmosféře s inertním plynem. Zcela špatně je ovoce zabalené v pytlíku, do kterého může vzduch a sluneční světlo. Dokonalé balení je neprůhledné a naprosto vzduchotěsné. Pak se z lyofilizovaných potravin stává taková konzerva – teoreticky může vydržet až desítky let bez újmy, ačkoliv výrobcem stanovená expirace je dávno minulostí. V praxi lze mluvit o letech.

Galerie: Obaly potravin od středověku po současnost

Ale třeba to lyofilizované ovoce se může snadno rozdrobit až na prášek…

Ano, lyofilizace nám umožňuje přejít na něco, co pracovně nazývám práškovou kuchyní 2.0. Většina lyofilizovaných potravin je tak suchá, že je lze rozemlít na prášek. Teď si představte různá barviva, dochucovadla, zahušťovadla, zdobení cukrovinek nebo posypky, které ovšem nebudou obsahovat žádnou chemii, ale 100 % přírodního produktu. Sám si ovocné knedlíky sypu práškem z rozemletých jahod namísto cukru a můj pes lépe tráví mrkev v prášku, než kdybych mu ji nakrájel na kostičky a dal do žrádla. Občas lyofilizuji kuřecí srdce, která pak pro naše psiska fungují jako pamlsek. Potenciál takto upravených potravin je velký a nedovedu dohlédnout na jeho konec.

Já si třeba jahodový prášek sypu do kaše nebo i do těsta na koláč. Ale ještě se nabízí otázka, zda ty jahody byly před usušením kvalitní a bez chemického ošetření.

Zde bych asi předně spotřebitele vybídl, aby se zajímal o původ lyofilizovaných potravin. Můžeme lyofilizaci považovat za „raketovou vědu“, ale v praxi je to jenom metoda sušení. Bohužel, velká část dnešní nabídky nám podsouvá především informaci, že ovoce bylo lyofilizované, ale už docela opomíjí říct, kde ovoce vyrostlo a jestli bylo nějak chemicky ošetřeno. Vezměte si za příklad klasicky sušená jablka – křížaly. Asi vám nebude stačit, když na obalu bude napsáno „sušená jablka“, ale budete chtít vědět, odkud surovina pochází a kdo ručí za její kvalitu. Pokud výrobce usuší nahnilá jablka, určitě nebudou zdravá jenom proto, že jsou sušená. Stejné je to s lyofilizací a je smutné vidět některé prodejce, kterak za zemi původu uvádí Českou republiku, ačkoliv jde o lyofilizovaný ananas nebo banán.

A co třeba bakterie nebo plísně?

Stejně tak je důležité zmínit, že lyofilizace nefunguje jako sterilizace a zachová jak živé kultury v jogurtu, tak třeba salmonelu v syrovém mase. Je pak opět na prodejci, aby upozornil, zda maso je syrové, anebo jej předtím tepelně zpracoval.

Co všechno jste už usušili? Co třeba něco netradičního?

S naším prototypem, na kterém provádíme testy, máme za sebou už více jak stovku různých lyofilizací. Z těch netradičních bych jmenoval ruskou zmrzlinu nebo dětské tvarohové dezerty. Kromě toho provádíme testy pro potenciální zájemce, kteří chtějí vědět, jak lyofilizace probíhá a jak vypadá jejich produkt sušený mrazem. Z této kategorie bych určitě zmínil cvrčky nebo včelí med, který ovšem neměl dobrý výsledek a vlastně nám ukázal, že nelze lyofilizovat vše.

Karel Schmiedberger

Zakladatel, jednatel a vlastník společností Biotrade a Lyotrade Freeze Dryers, s.r.o. Vystudoval Obchodní Akademii v Praze. Absolvoval mnohá odborná školení o procesu lyofilizace v USA. Podílí se na vývoji a distribuci lyofilizačních přístrojů a nových technologií v procesu lyofilizace potravin.

Autor článku

Externí redaktorka a copywriterka píšící pro webové i tištěné magazíny. Zaměřuje se na oblast zdraví, historie medicíny, psychologie, filozofie, etikoterapie a alternativní medicíny.

'; 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 »