Diabetická retinopatie oslepila stovky pacientů. Jak ji lze odhalit a léčit

9. 3. 2023

Sdílet

Autor: Depositphotos
Neléčená diabetická retinopatie patří k nejčastějším příčinám oslepnutí. Přesto se o tomto závažném onemocnění příliš nemluví a řada rizikových pacientů se nedostane k preventivnímu vyšetření. Teď se v tuzemsku rozbíhá nová možnost prevence.

Diabetická retinopatie postihuje cévy očního pozadí, tedy sítnice. Pokud není léčena včas, může vést ke slepotě. Všeobecná zdravotní pojišťovna (VZP) uvádí, že v Česku je evidováno cca 100 tisíc lidí s diabetickou retinopatií, přičemž asi 2000 z nich už způsobila slepotu.

Co se dozvíte v článku
  1. Proč diabetická retinopatie vzniká
  2. Proč je nemoc nevyzpytatelná
  3. Kdo a jak často má chodit na oční prevenci
  4. Fáze diabetické retinopatie
  5. Jak se diabetická retinopatie léčí 

Jak název tohoto onemocnění napovídá, je úzce provázáno s diabetem, a to 1. i 2. typu. Diabetes neboli cukrovku, tedy poruchu regulace metabolismu glukózy, má v České republice ovšem diagnostikovánu už tolik pacientů, že čekací lhůty na preventivní vyšetření zraku jsou v některých lokalitách neúměrně dlouhé„VZP stále eviduje cca 40 % pacientů, jimž požadované vyšetření chybí,“ hlásila loni v srpnu zdravotní pojišťovna. Ta v roce 2021 evidovala 562 tisíc klientů léčených s diabetem.

Proto VZP a postupně i další zdravotní pojišťovny přistoupily na hrazení očního screeningového vyšetření (plošné prevence) přímo v ordinacích diabetologů. Podmínkou je, aby lékař použil při vyhodnocování snímků sítnice tzv. umělou inteligenci. Jak jsme na Vitalia.cz nedávno informovali, první ordinace už speciální vybavení mají a pacienty vyšetřují.

Proč diabetická retinopatie vzniká

„Diabetická retinopatie je onemocnění označované jako pozdní komplikace diabetu,“ říká oftalmolog Martin Šín, přednosta Oční kliniky v pražské Ústřední vojenské nemocnici (ÚVN). Pro Vitalia.cz vysvětlil, proč k onemocnění dochází a jak jej lze léčit.

Podstatou vzniku diabetické retinopatie je cukrovku doprovázející mikroangiopatie. „Jde o onemocnění malých cév, jež vede k jejich ucpávání a také k oslabení jejich stěny – ta se následkem toho vyklenuje. Jedním z míst, kde se mikroangiopatie projevuje nejdříve a nejvíce, je oční pozadí,“ doplňuje lékař. Oční pozadí je citlivé i na malé změny ve funkci cév, protože sítnice patří mezi nervové tkáně velmi citlivé na prokrvení. Jakmile není vše v pořádku, zhoršuje se její výživa a okysličování. Následkem toho dochází postupně ke změnám funkce, které mohou vygradovat úplným a nevratným poškozením zraku.

Diabetická retinopatie nepatří k onemocněním vznikajícím ze dne na den. Dochází k němu až po určité době od propuknutí cukrovky. Čím déle cukrovku máte, tím vyšší je pravděpodobnost, že budete mít poškozenou i sítnici. „Každá tkáň má k patologickým reakcím určitou toleranci, protože k nim v malé míře dochází i ve zdravém lidském těle. U cukrovky jsou ale tkáně trvale metabolicky ‚přetěžovány‘, takže se postupně vyčerpají rezervní mechanismy a začnou se projevovat funkční poruchy. Čím déle toto ‚přetěžovaní‘ trvá, tím více vzrůstá pravděpodobnost patologie,“ vysvětluje Martin Šín obecný princip platný pro všechny orgány. Rizikovější skupinou pro výskyt diabetické retinopatie jsou pacienti s cukrovkou 2. typu. „Protože se velmi často pojí s metabolickým syndromem doprovázeným obezitou a hypertenzí,“ podotýká oftalmolog.

Proč je nemoc nevyzpytatelná

Retinopatie se teoreticky časem vyvine u každého diabetika. „Je-li neléčená, vede téměř vždy z hlediska zraku k fatálnímu konci. Je jen otázkou, kdy nastane,“ říká Martin Šín. Fakticky ovšem takto jednoduše nefunguje, protože část lidí postihuje až po letech. Takže dříve, než přijde, pacient například umírá na komplikaci spojenou se svými chronickými nemocemi.

Diabetická retinopatie je nevyzpytatelná, protože může postihnout i toho, kdo pečlivě dodržuje léčbu diabetu. „Jsou pacienti s dobrou kompenzací, ale diabetická retinopatie se jim rozvine relativně rychle, protože kromě cukrovky mají i jiné faktory, jež vznik retinopatie umocňují a které ještě všechny dnes ani neznáme,“ popisuje odborník a dodává: „Na druhou stranu jsou diabetici s rozkolísanými hodnotami glykémie, ale retinopatii nikdy nedostanou. Jde o dva extrémní příklady, na nichž chci demonstrovat to, že doporučení každoroční prevence platí pro každého diabetika, protože předem nikdy nevíte, do které skupiny patří,“ popisuje odborník.

První diabetologové vyšetřují oči, dokážou tak včas odhalit poškození zraku Přečtěte si také:

První diabetologové vyšetřují oči, dokážou tak včas odhalit poškození zraku

Kdo a jak často má chodit na oční prevenci

V drtivé většině případů je rozvoj retinopatie odvislý od toho, jak dlouho pacient diabetes má a jak jsou jeho projevy u něj kompenzované léčbou. Za jak dlouho se diabetická retinopatie rozvine, nedokáží lékaři přesně určit, protože v tom, kdo a kdy jí onemocní, hraje roli kromě průběhu diabetu také řada rizikových faktorů včetně genetiky. „Někdy může ke komplikacím se zrakem dojít v řádu měsíců, jindy to trvá mnoho let,“ říká Martin Šín. A tak je důležité, aby na preventivní kontroly chodili všichni diabetici, kterým cukrovka zatím nepoškodila zrak.

Aby byla prevence retinopatie efektivní, musí ovšem pacient nejprve vědět, že má diabetes. Cukrovka nebolí, léta se nemusí nijak projevovat, takže ne každý nemocný o ní ví. Potřebné je také na oční prevenci chodit, a to opakovaně. „Pokud prevence funguje, onemocnění můžeme zachytit v časných stádiích a zachovat tím funkční vidění, protože diabetická retinopatie znamená pro zrak fatální následky,“ připomíná Martin Šín s tím, že pokud o retinopatii lékař i pacient ví a léčbu jí přizpůsobí, jde o léčitelný stav.

Preventivní prohlídku očního pozadí by měli pacienti s diabetem podstupovat jednou ročně. V této frekvenci je také hrazena z veřejného zdravotního pojištění. Prohlídku provádí oční lékaři nebo nově na pojišťovnu také diabetologové. Zatím je jich ovšem jen hrstka. Vyšetřovat oči totiž mohou jen ti s potřebnými vybavením ambulance včetně speciálního softwaru – tzv. umělé inteligence. Takto vybavených ordinací bude ale zcela jistě postupně přibývat, protože jde o novinku, které se diabetologové teprve přizpůsobují.

Pojišťovna nově hradí pacientům s cukrovkou vyšetření zraku u diabetologa Přečtěte si také:

Pojišťovna nově hradí pacientům s cukrovkou vyšetření zraku u diabetologa

Možnost prevence v diabetologických ambulancích je podle Martina Šína zásadní. „Předpokládáme, že většina pacientů se dostane k diabetologovi. Návštěva diabetika u očního lékaře z preventivních důvodů ale už tak častá není. Tam je počet vyšetření řádově nižší, proto využití umělé inteligence zásadním způsobem zefektivňuje plošnou prevenci diabetické retinopatie,“ uvádí přednosta Oční kliniky ÚVN.

Osobně mu to, že diabetologové provádí nově oční vyšetření, nevadí. „Nežárlím na ně, prioritou je zdraví pacienta. A my oční lékaři práce máme dost a dost,“ říká Martin Šín pobaveně. Ostatně on sám se na vyvíjení české umělé inteligence spojené s prevencí diabetické retinopatie podílí. Navíc systém prevence je nastavený tak, že jakmile software u diabetologa zachytí změny na sítnici, pacient se musí objednat k oftalmologovi, protože jedině on může stanovit diagnózu. Martin Šín věří, že efektivní screening u diabetologů do ordinací očních lékařů přivede větší množství pacientů, jejichž stav vyžaduje péči. A díky prevenci ji dostanou včas.

Fáze diabetické retinopatie

  • Neproliferativní diabetická retinopatie – podle portálu NZIP se vyznačuje změnami cév, krvácením a tvorbou usazenin. Dochází k poškození sítnice (retiny) oka, následkem je snížená schopnost vidění. Podle míry a rozsahu změn se dělí neproliferativní diabetická retinopatie na formu lehkou, střední a těžkou.
  • Proliferativní diabetická retinopatie – závažný zdravotní stav, při kterém cévy vrůstají do sklivce, dochází k častějšímu krvácení v oku, tvorbě jizev a důsledkem může být i odchlípení sítnice.

Všechna stádia mohou být komplikována diabetickým makulárním edémem, což je otok místa nejostřejšího vidění, jenž zhoršuje vidění.

Jak se diabetická retinopatie léčí 

Pokud preventivní vyšetření diabetickou retinopatii odhalí, léčba je závislá na tom, v jaké fázi se onemocnění nachází. Žádné zázračné pilulky ani oční kapky ovšem neexistují a poškození očí touto nemocí se neléčí ani dioptrickými brýlemi. 

Při lehčích formách diabetické retinopatie se přímo oko neléčí, ale lékař pracuje s nastavením léčby samotného diabetu. Pokud je cukrovka léčena dobře, změny na očním pozadí se mohou výrazně zpomalit.

Léčba laserem

Při závažnějších stádiích diabetické retinopatie oftalmolog může zvolit léčbu laserem. „Této metodě se říká laserová fotokoagulace. Při ní selektivně pálíme méně potřebné buňky, aby kyslík zbyl pro potřebnější nervová zakončení v sítnici,“ vysvětluje Martin Šín.

Léčil se s vleklým ekzémem, testy odhalily cukrovku. Část diabetiků nemá nejmodernější léčbu Přečtěte si také:

Léčil se s vleklým ekzémem, testy odhalily cukrovku. Část diabetiků nemá nejmodernější léčbu

Biologická léčba

Nejmodernější metodu v současnosti představuje biologická léčba. Spočívá v podání steroidů nebo v tzv. anti-VEGF terapii. „Což je aplikace protilátek proti vaskulárnímu růstovému faktoru nebo steroidních implantátů. Obě tyto metody mají formu injekcí aplikovaných do sklivce,“ popisuje lékař. Injekce aplikované přímo do oka se mohou zdát na první pohled jako brutální a riskantní, podle Martina Šína jde ale dnes již o běžnou, nebolestivou, rutinní praxi s minimálními riziky. „V oku je místo nazývané pars plana, přes které do něj můžete ‚beztrestně‘ vstoupit,“ objasňuje princip léčby přednosta s tím, že před injekcí je oko lokálně umrtveno kapkami. 

Trpí někdo ve vaší blízké rodině cukrovkou?

Biologická léčba je hrazena zdravotními pojišťovnami (je-li indikovaná) a lékaři ji používají zejména u pacientů, u nichž diabetickou retinopatii provází tzv. diabetický makulární edém. Na tento typ léčby ovšem pacienti musí dojíždět do specializovaných očních center.

Operace oka

Možná je také operace oka, tzv. pars plana vitrektomie. K té lékaři přistupují, pokud do sklivce vrůstají novotvořené drobné cévy, jež se začnou jizvit. „To už ale jde o ta nejzávažnější stádia diabetické retinopatie,“ dodává Martin Šín. 

Pokud je léčba včasná a správně zvolená, ke slepotě v současné době diabetická retinopatie již většinou nevede. „Samozřejmě nejlepší je zdravé oko, jakýkoliv zásah oftalmologa je vždy kompromis, u kterého musíte zvažovat přínosy a rizika,“ podotýká odborník. 

Lékařská věda dnes již umožňuje léčbu posouvat do včasnějších stádií onemocnění, takže brzdění patologických změn v oku přichází dříve a u většiny pacientů lékaři zachovají funkční vidění. „Léčba má zabránit rozvoji patologií, eventuálně zlepšit vidění. Jak moc se to podaří, to je vždy individuální. Stále existuje, bohužel, i skupina pacientů, kterým přes veškerou péči nedokážeme pomoci,“ doplňuje Martin Šín.

Odborná spolupráce:

doc. MUDr. Martin Šín, Ph.D.

Přednosta Oční kliniky 1. lékařské fakulty Univerzity Karlovy a Ústřední vojenské nemocnice – Vojenské fakultní nemocnice Praha. Podílí se na vývoji českého softwaru s názvem Aireen. Je určen pro vyšetření oční sítnice s pomocí umělé inteligence.

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 »