Cukrovkářům budou s jídelníčkem přímo v ordinaci diabetologa radit nutriční terapeuti. Na pojišťovnu

7. 9. 2023

Sdílet

Autor: Depositphotos
Část diabetologů začne příští rok ve svých ordinacích zaměstnávat nutriční terapeuty. Tedy zdravotníky, kteří dokáží s pacienty řešit odborně jejich životosprávu. Klienti VZP budou mít jejich služby hrazené.

Všeobecná zdravotní pojišťovna (VZP) oznámila, že příští rok začne proplácet některým pacientům s cukrovkou konzultace nutričních terapeutů. Podmínkou je, aby terapeuti pracovali přímo v ordinacích vybraných diabetologů.

Co se dozvíte v článku
  1. Podoba nové hrazené služby
  2. Pro koho je určená
  3. Jak bude terapie vypadat
  4. V praxi až za několik měsíců
  5. Proč novinka vznikla

Novinka přinese podstatnou změnu v péči o nemocné. Nutriční terapeuti dosud působili především v nemocnicích, nově se ve vyšší míře zapojí také do ambulantní péče. Navíc konzultace u nich budou mít pacienti hrazené, takže nebudou platit nic ze svého. „Jde o významný pokrok, který otevírá v diabetologii zcela nové možnosti,“ říká Martin Prázný, předseda České diabetologické společnosti.

To, zda lékař nutričního terapeuta zaměstná, či nikoliv, bude na něm. Zapojení do nového projektu je pro lékaře i nutriční terapeuty, stejně jako pro pacienty, dobrovolné.

300 tisíc lidí netuší, že má cukrovku. Testy z lékárny časná stadia neodhalí Přečtěte si také:

300 tisíc lidí netuší, že má cukrovku. Testy z lékárny časná stadia neodhalí

Podoba nové hrazené služby

Novinku VZP spustí od Nového roku. Bude mít podobu rozšíření služeb již stávajících diabetologických ordinacíPojišťovna chce takto upravit smlouvy 80 diabetologickým ordinacím. V budoucnu by měl mít každý okres minimálně jednu, kde spolu s lékařem a zdravotní sestrou bude působit i nutriční terapeut. „Ambulance proto zvládnou širší spektrum činností zaměřených nejen na analýzu pacientova těla a jeho stravovacích návyků, ale také umožní terapeutickou intervenci v jeho životosprávě,“ podotýká Martin Prázný.

Nutriční terapeuti budou pacientům k dispozici v ordinačních hodináchZda pokryjí celou ordinační dobu, nebo jen část z ní, záleží na tom, jaký pracovní úvazek si lékaři s nimi sjednají. VZP si ale při upravování smlouvy s ordinací klade podmínku, aby v ní terapeuti pracovali přinejmenším na poloviční úvazek.

Které ordinace budou mít nárok na proplácení práce nutričních terapeutů ze strany VZP:

  • Musí mít v péči alespoň 500 pacientů, kteří jsou pojištěnci VZP,
  • zkušenost s kontinuálním monitoringem glykémie a inzulínovými pumpami,
  • možnost stahování dat z glukometrů a se vzdáleným monitorováním dat,
  • návaznost na centrum abariatrické a metabolické chirurgie,
  • vybavení bioimpedační metodou pro stanovování složení těla z tuků, svalů a vody,
  • software pro monitorování sledovaných parametrů, např. glykémie či antropometrických parametrů.

Pro koho je určená

Hrazená novinka je určena pouze pro pacienty s cukrovkou. Ale ne pro všechny. Nárok na hrazenou nutriční terapii budou mít od roku 2024 pouze ti:

  • s nově diagnostikovanou cukrovkou 2. typu v předchozích šesti měsících,
  • s nasazenou injekční léčbou,
  • s diabetem a BMI > 30 kg/m2,
  • s chronickým onemocněním ledvin,
  • s vysokým a velmi vysokým kardiovaskulárním rizikem,
  • kteří mají také další onemocnění vyžadující úpravu jídelníčku (např. dna, celiakii aj.),
  • kteří mají také poruchu příjmu potravy (a jsou v péči psychologa),
  • kteří jsou léčeni v režimu flexibilního dávkování inzulínu,
  • s neuspokojivou kompenzací diabetu charakterizovanou hodnotou HbA1c >  53 mmol/mol.

Zatím jde jen o klienty VZP, protože ostatní zdravotní pojišťovny se ještě nevyjádřily, zda ji také budou hradit, nebo nikoliv. A pokud ano, tak za jakých podmínek. Nicméně existuje předpoklad, že konzultace nutričního terapeuta, pokud se osvědčí, postupně začnou proplácet také, takže by bezplatné služby těchto specialistů měly být v budoucnu dostupné vyššímu počtu nemocných. Režim úhrad se ale u dalších pojišťoven může od VZP lišit.

Kdo je nutriční terapeut

Jedná se o vysokoškolsky vzdělaného zdravotníka nelékařského typu s tituly Bc. (nutriční terapeut) nebo Mgr. (nutriční specialista). S pacientem dokáže probrat jeho tělesnou konstituci i to, jakým způsobem upravit jídelníček a pitný režim tak, aby žil zdravěji. A to s přihlédnutím na aktuální zdravotní stav i případná chronická onemocnění.

Zdroj: Česká asociace nutričních terapeutů

VZP předpokládá, že péči navíc zaplatí opakovaně jen motivovaným pacientům, kteří jsou ochotní se na změně své životosprávy podílet a alespoň zčásti jí dosáhnout.

Pokud snaha na straně pacienta bude, ale výsledky hned nikoliv, nevadí. Pokud ale pacient bude doporučení specialisty ignorovat, lékař a zdravotní pojišťovna mu opakovanou možnost nutriční terapie nedají.

„Zdravotní pojišťovna bude u pacientů na nutriční terapii sledovat, do jaké míry se jim daří doporučený režim naplňovat a zda u nich díky tomu dochází ke zlepšení sledovaných hodnot,“ uvádí VZP v tiskové zprávě. Mezi kritéria úspěšnosti terapie se tak řadí např. redukce tělesné hmotnosti alespoň o pět procent u obézních pacientů, zlepšení kompenzace diabetu (pokles hodnoty glykovaného hemoglobinu), zlepšení hladiny glukózy v krvi po jídle nebo snížení výskytu hypoglykémií. 

Nemoc starých způsobená sladkým. Pořád ještě věříme úplným nesmyslům o cukrovce Přečtěte si také:

Nemoc starých způsobená sladkým. Pořád ještě věříme úplným nesmyslům o cukrovce

Jak bude terapie vypadat

V tuto chvíli službu VZP nastavila tak, že proplatí na jednoho pacienta čtyři konzultace za půl roku. Respektive pacientovi a terapeutovi na ně dává až jeden rok. 

Pokud se spolupráce osvědčí a přinese prokazatelné zlepšení zdravotního stavu, může pacient cyklus konzultací na vrub veřejného zdravotního pojištění zopakovat. Nejdříve ovšem po roce.

Jedna nutriční konzultace by měla trvat zhruba 30 až 40 minut. To, zda bude spojena s kontrolou u diabetologa, nebo na ni bude muset pacient přijít zvlášť, bude záležet na tom, jak si to nastaví lékař, u nějž se nemocný s diabetem léčí.

Už na první schůzce si nejspíš pacient přinese rozpis svého obvyklého jídelníčku. Ideálně půjde o záznam toho, co jedl, po dobu jednoho týdne. „Určitě budeme chtít znát hodnoty či data z glukometru. Ideální by bylo, kdyby nutriční terapeut díky datům sdíleným s lékařem viděl v počítači také hodnoty laboratorních vyšetření,“ vysvětluje klinická nutriční terapeutka Aneta Hásková, která na zavedení novinky spolupracuje s Českou diabetologickou společností.

Přesná podoba konzultací se ale bude u každého pacienta lišit, protože terapie je vždy šitá přímo na míru. „Určitě ale nebude vypadat tak, že pacient dostane letáček a půjde domů,“ říká v nadsázce Aneta Hásková. Podle ní je péče od nutričního terapeuta na rozdíl od výživových poradců kvalifikovaná. Navíc nutriční terapeut je zdravotník s jasně vymezenými kompetencemi zákonem a je zvyklý a oprávněný pracovat třeba i s chronickými pacienty.

Podle ní by pacienti měli najít odvahu a zkusit alespoň jedno sezení. „Nepracujeme na bázi zákazů a striktních diet, ostatně to by ani dlouhodobě nefungovalo. A třeba bude pacient na první konzultaci mile překvapen tím, že vše je věcí dohody a kompromisu. Stačí nemít extrémní cíle a nebýt na sebe přísný,“ dodává klinická nutriční terapeutka. 

Odborník pacientům dokáže vyvrátit třeba i některé mytý, s nimiž se mohli setkat a zbytečně jsou jimi omezováni. Třeba že při cukrovce nesmí jíst banány, natož odpoledne a večer. Nebo že jedinou příčinou vzniku je to, že jíme moc cukru. „Přitom příčinou není to, že by člověk extrémně cukroval. Je to metabolické onemocnění, které se ve finále týká primárně tuků,“ dodává Aneta Hásková.

Vysvětlivky: ZUM = zdravotnické prostředky, ZULP = zvlášť účtované léčivé přípravky, LP = léčivé přípravky, PZT = prostředky zdravotnické techniky

Graf ukazuje, jak za posledních deset let stouply náklady na léčbu pojištěnců VZP s diabetem. Loni už se začaly přibližovat deseti miliardám korun.

Autor: VZP

V praxi až za několik měsíců

Aby lékaři mohl pojišťovně práci nutričního terapeuta vykazovat, nově pro něj musí najít ve své ordinaci prostor. Ordinaci musí také nově dovybavit, a to přístroji i počítačovým programem. „Předpokládáme, že náklady na zavedení této nové zdravotní služby se budou pohybovat kolem čtvrt milionu korun na jednu ordinaci,“ řekl pro Vitalia.cz Martin Prázný. Úhrada od pojišťovny je ale dle něj nastavena tak, aby byla dostatečnou motivací pro to změny v části ordinací udělat. 

Jak nutriční terapeut, tak diabetolog navíc za sebou budou muset mít kurzy diabetologické společnosti, aby poskytování této služby bylo jednotné napříč ČR. První z nich vypíše odborná společnost na konci letošního roku, nejspíš v listopadu.

Využili byste služeb nutričního terapeuta?

Tyto podmínky a to, že zavedení nové služby je dobrovolné, budou znamenat, že do praxe se ambulantní péče nutričních terapeutů bude prosazovat postupně. Pacienti proto musí být trpěliví a počítat s tím, že může trvat měsíce, než jejich lékař novinku zavede. Nicméně není na škodu, když se o případném plánu novinku zavést budou u svých lékařů zajímat již nyní. 

Může se ale stát i to, že ambulance o zaměstnání nutričního terapeuta nebude mít zájem, nebo neuspěje ve výběrovém řízení. V takovém případě nezbyde pacientovi, který o ambulantní hrazenou nutriční terapii stojí, nic jiného než změnit diabetologa. Musí ale počítat s tím, že VZP preferuje, aby se v ordinacích s rozšířenou zdravotní péčí léčili jen nemocní z daného regionu, kde ordinace působí. 

Proč novinka vznikla

VZP novinku zavádí, protože diabetes má nemalá část populace – onemocnění aktuálně postihuje zhruba její desetinu. Tento podíl ale setrvale narůstá. Cukrovka přitom patří k onemocněním vedoucím k řadě dalších závažných komplikací. Např. poškození zraku, ledvin nebo nebo nervů. Diabetici mají také zvýšené riziko infarktů, cévních mozkových příhod a aterosklerózy a provází je častěji nehojící se rány.

Pojišťovna chce intervencí nutričních terapeutů snížit zdravotní rizika spojená s cukrovkou. To by mohlo přibrzdit také vzrůstající náklady na léčbu diabetiků. Jen prostřednictvím plateb z VZP, jež má mezi pojištěnci 575 tisíc diabetiků, stála loni 9,3 miliardy korun. „Pokud se tyto náklady nepokusíme nějak zvrátit, brzy budou atakovat deset nebo jedenáct miliard ročně, protože neustále narůstají,“ uvádínáměstek ředitele VZP Jan Bodnár„Co se týká hrazený konzultací nutričních specialistů jde o zcela novou funkci ordinací, s pomocí které chceme zabránit vzniku či rozvoji přidružených onemocnění spojených s diabetem,“ dodává. 

VZP předpokládá, že služby nutričních terapeutů budou stát ročně desítky milionů korun. Na druhé straně by případná změna hmotnosti u některých pacientů s cukrovkou mohla jen na medikaci (tj. podávání léků) ušetřit systému veřejného zdravotního pojištění stovky milionů korun ročně. Další úspory mohou přinést méně časté hospitalizace spojené s komplikacemi při cukrovce.

Autor článku

Redaktorka Vitalia.cz. Vystudovala žurnalistiku a češtinu na Univerzitě Palackého v Olomouci, pracovala v Deníku, na webu TV Nova a iDNES.cz. Píše o zdravotnictví. Je držitelkou novinářských cen Psychiatrické společností ČLS JEP za rok 2021 a 2022. 

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