Spirometrie zkoumá plicní objemy, kapacity a průtoky. Jak toto vyšetření probíhá?

26. 7. 2021 7:30
přidejte názor
Autor: Depositphotos

Trápí vás respirační potíže a dlouhodobý kašel, potýkáte se s nějakým nepříjemným plicním onemocněním nebo se chystáte na operaci hrudníku? Pak vás s největší pravděpodobností čeká spirometrické vyšetření, které se používá k měření ventilace. Prozradíme, kdy je nutné spirometrii podstoupit, jak probíhá a co lékaři napoví o vašem zdravotním stavu.

Dechový cyklus člověka

Dýchání je proces, při němž dochází k výměně plynů (zejména kyslíku a oxidu uhličitého) mezi organismem a jeho externím prostředím. Nádech a výdech pak tvoří dechový cyklus, který se opakuje zhruba šestnáctkrát za minutu, a to v bdělém stavu, ale i v noci, když člověk spí. Během dýchání tak dochází k ventilaci, díky které je čerstvý vzduch neustále v kontaktu s povrchem dýchacího orgánu.

Při jednom nádechu je do plic přiváděno průměrně půl litru čerstvého vzduchu, který obsahuje asi 21 % kyslíku a zhruba 0,04 % oxidu uhličitého. Při výdechu pak z plic také odchází půl litru vzduchu, ale zastoupení jednotlivých složek se zde mění na 15 % kyslíku a 4,5 % oxidu uhličitého.

Kyslík umožňuje buňkám účinnější získávání energie ze živin a na jeho nedostatek nejcitlivěji reaguje nervová soustava. Oxid uhličitý naopak představuje odpadní produkt metabolismu. Zatímco při nedostatečném dýchání dochází k překyselení organismu, což se označuje jako acidóza, příliš intenzivní vylučování oxidu uhličitého plícemi naopak vede ke vzniku respirační alkalózy.

Co je spirometrie?

Spirometrie je fyziologický test měřící objem vzduchu, který pacient vdechuje nebo vydechuje v závislosti na čase. Představuje jednu ze základních interních vyšetřovacích metod, kam se dále řadí měření krevního tlaku nebo třeba záznam EKG. Stejně jako v případě těchto testů jde o poměrně nenáročné a nebolestivé fyziologické vyšetření.

V rámci spirometrie se lékaři soustředí hned na několik faktorů, přičemž k základnímu vyšetření patří měření statických i dynamických parametrů. V rámci těch statických (klidových) se jedná o různé objemy a kapacity respiračního systému (dechový objem, vitální kapacita a podobně), u těch dynamických pak jde o průtoky či objemy při maximálně usilovném dýchání (minutová ventilace…).

Jaké parametry spirometrie zkoumá?

  • exspirační vitální kapacita,
  • inspirační vitální kapacita,
  • usilovná vitální kapacita,
  • vrcholový výdechový průtok,
  • usilovně vydechnutý objem vzduchu za 1 sekundu,
  • maximální průtoky vzduchu v různých úrovních usilovné vitální kapacity.

Protože i po maximálním výdechu zůstane v plicích nějaký vzduch, což se odborně označuje jako reziduální objem, lékaři nejsou schopní pomocí spirometrického vyšetření určit celkovou kapacitu plic. Pokud tuto informaci z nějakého důvodu potřebují, je nutné doplnit spirometrii o další testy, jako je například celotělová pletysmografie.

Kdy se spirometrie provádí?

Pacienty většinou nejvíce zajímá, proč se používá test spirometrie a jaká onemocnění je možné s jeho pomocí odhalit. Lékař toto vyšetření indikuje především u osob, které trápí respirační potíže, jako je dlouhotrvající kašel, dušnost nebo bolest na hrudi. Někdy je pak důvodem opakované spirometrie také astma, které pacientovi znemožňuje normální fungování.

Vyšetření měřící objem vdechovaného a vydechovaného vzduchu se dále provádí u pacientů trpících jakýmkoliv onemocněním plic. Lékařům totiž dokáže hodně napovědět o tom, s jakým stupněm postižení plicních funkcí se potýkají. Kromě toho pak spirometrie poskytuje také komplexní pohled na systémové choroby, jako je revmatoidní artritida, systémový lupus erythematodes či systémová sklerodermie.

Z hlediska ventilace existují dva druhy onemocnění, která od sebe spirometrie dokáže účinně odlišit. Jedná se o poruchy restrikční, kam patří například plicní fibróza, kdy jsou objemy plic menší, ale rychlost výdechu zůstává normální. V rámci obstrukčních poruch, jako je astma, chronická bronchitida nebo chronická obstrukční plicní nemoc, dochází k zúžení dýchacích cest, zhorší se průtok a následně i ventilace, takže je maximální výdechová rychlost nízká.

Spirometrie dále slouží k monitorování účinnosti léčby plicních nemocí, používá se pro detekci nežádoucích efektů léků a chemických látek, které toxicky působí na plicní tkáň, a pomáhají lékařům odhadnout prognózu respiračních onemocnění. Navíc se provádí také v rámci obecného předoperačního vyšetření (hlavně u specifických operací nebo u operací kuřáků a pacientů trpících respiračními obtížemi).

Indikace k provedení spirometrie

  • plicní onemocnění,
  • chronický kašel a dušnost,
  • recidivující respirační infekce,
  • astma,
  • výrazná obezita,
  • deformity hrudníku,
  • operace hrudníku,
  • operace břicha,
  • plicní resekce (odstranění plicní tkáně),
  • neuromuskulární onemocnění,
  • dlouhotrvající anestezie,
  • laboratorní anomálie,
  • vyšší věk pacientů (nad 70 let),
  • kouření (více než 20 cigaret denně).

Kromě výše zmíněných důvodů, proč se ke spirometrii přistupuje, může lékař doporučit toto vyšetření také pro posudkové účely (lázně, rehabilitace, pracovní schopnosti) a používá se také před nástupem do rizikových profesí. V neposlední řadě pak lékaři pomocí tohoto vyšetření zkoumají veřejné zdraví (epidemiologické studie) a často slouží i ke klinickému výzkumu.

A kdy se naopak spirometrie neprovádí? Mezi kontraindikace se v tomto případě řadí například závažné infekční onemocnění pacienta, jakýkoliv defekt v orofaciální oblasti (stavy po extrakci zubů, herpes simplex a podobně) nebo třeba cévní mozková příhoda s postižením, které znemožňuje adekvátní spolupráci pacienta s lékařem.

Spirometry

Přístroj, pomocí kterého je možné účinně změřit jednotlivé ventilační parametry, se nazývá spirometr. Pacient do něj postupně dýchá, čímž roztáčí malou turbínu, která je uložená uvnitř. Kromě toho může být ve spirometru přítomná také síťka, kterou vzduch vytváří tlak přímo úměrný jeho objemu.

Díky tomu, že přístroj měří také čas, jsou lékaři schopní odhalit rychlost proudu vzduchu či závislost průtoku vzduchu dýchacími cestami na objemu plic. Jelikož v dnešní době existují nejen stolní, ale také kapesní spirometry, je měření navíc snadno proveditelné i pro praktické lékaře nebo pro samotné pacienty, kteří přístroj mohou dle instrukcí použít sami.

Podstoupili jste někdy spirometrii?

Co dělat před vyšetřením?

Chystáte se podstoupit spirometrii? Pak mějte na paměti, že se nemusíte předem nijak speciálně připravovat, ale měli byste se řídit pokyny svého ošetřujícího lékaře. Před vyšetřením nekuřte a nejezte těžko stravitelná jídla. Ranní dávku bronchodilatancií vynechte, nebo po jejich užití v žádance tuto skutečnost vyznačte.

Spirometrie se neprovádí po invazivních vyšetřovacích metodách, jako je například fibroskopie nebo rektoskopie. Chystáte-li se na vyšetření, nezapomeňte si na sebe obléknout něco pohodlného, v čem se vám bude volně dýchat (tedy žádný utažený pásek ani stahující spodní prádlo), a pokuste se během cesty do ordinace příliš nezadýchat.

Jak probíhá spirometrie?

Vyšetření se obvykle provádí vsedě, přičemž pacientovi je na nos upevněn kolíček, jenž zamezí dýchání nosem, a do úst mu lékař vloží speciální náustek, skrze který pak vdechuje a vydechuje. Aby ovšem byl prováděný test úspěšný, pacient musí s lékařem spolupracovat a dýchat do přístroje přesně podle jeho pokynů, nebo případně podle pokynů zdravotní sestry.

Zpočátku se většinou provádí tři normální nádechy a výdechy. Poté lékař pacienta požádá o maximální nádech a maximální výdech, což znamená, že je nutné se co nejvíce zhluboka nadechnout a poté co nejprudčeji vydechnout, aby z plic odešlo co největší množství vzduchu. Dalším úkolem, který lékař pacientovi uloží, pak může být co nejusilovnější dýchání po dobu 15 sekund.

Vyšetření obvykle trvá 5–10 minut, přičemž proces nadechování a vydechování je někdy nutné opakovat z důvodu náhlého kašle či nedodechnutí, což zkresluje výsledky měření. Nádechy a výdechy se přitom zaznamenávají do počítače ve formě grafů a sloupků čísel.

Spirometrii mohou podstoupit také těhotné ženy nebo děti. Pro ty jsou k dispozici různé počítačové animace, které podporují lepší spolupráci malých pacientů s lékařem. Děti se přitom nesnaží pouze o maximální výdech, ale mohou sfoukávat také hořící svíčky, což je pro ně zábavnější.

Hodnoty spirometrie

Cílem vyšetření je odhalit příčinu respiračních obtíží a zjistit, zda jsou dýchací cesty pacienta normálně průchodné. Jaké má spirometrie výsledky, lékař zjistí hned na místě. Výstupem vyšetření jsou totiž dva grafy, z nichž jeden ukazuje objem plic v závislosti na čase a druhý sleduje závislost průtoku vzduchu dýchacími cestami na objemu plic.

V rámci spirometrie se v první řadě provádí vyšetření klidových objemů a plicních kapacit. Spirometr v takovém případě vykáže křivku objem/čas. Mezi zkoumané parametry se pak řadí:

  • VT – objem vzduchu vdechnutý či vydechnutý jedním normálním vdechem nebo nádechem,
  • ERV – exspirační rezervní objem,
  • IRV – inspirační rezervní objem,
  • VC – vitální kapacita,
  • IC – inspirační kapacita,
  • df – dechová frekvence neboli počet dechů za 1 minutu.

Dále lékaři provádějí vyšetření usilovaného výdechu a nádechu. Výsledky poté mohou vyčíst ze dvou křivek, které ukazují průtok/objem a objem/čas. Zkoumané parametry tentokrát zahrnují:

  • FVC – maximální objem vzduchu, který lze po maximálním nádechu prudce vydechnout,
  • FEV1 – objem vzduchu vydechnutý po maximálním nádechu s největším úsilím během 1 sekundy,
  • FEV1/VC – Tiffeneaův index,
  • PEF – nejvyšší průtok na vrcholu usilovného výdechu,
  • PIF – maximální průtok, kterého bylo dosaženo na vrcholu nádechu,
  • FEF – usilovné exspirační průtoky na různých úrovních již vydechnuté FVC,
  • MEF – maximální výdechové průtoky na různých úrovních FVC, kterou je stále nutné vydechnout (MEF25, MEF50, MEF75).

Podle tvaru křivek a zaznamenaných hodnot dokáže lékař orientačně stanovit obstrukci dýchacích cest a míru ventilační poruchy, která pacienta trápí. Je tedy schopný říct, s jakým konkrétním plicním onemocněním se člověk potýká, zda něco brání vykonání doporučené operace nebo jak se pacientův stav postupem času vyvíjí.

Důležitým zdrojem informací je pro lékaře hlavně inspirační rezervní objem (IRV), který udává, kolik vzduchu může pacient po normálním vdechu ještě do plic přijmout. Druhým zajímavým údajem je exspirační rezervní objem (ERV), jenž určuje, kolik vzduchu může pacient po normálním výdechu ještě vydechnout. Tyto objemy pak lidský organismus využívá při jakékoliv zvýšené zátěži.

Různé dechové objemy lékaři dále sčítají v kapacity. Zkoumá se například vitální kapacita plic (VC), která představuje součet dechového objemu, inspiračního rezervního objemu a exspiračního rezervního objemu, nebo celková kapacita plic, která je součtem vitální kapacity a reziduálního objemu. Ten je ovšem spirometrem nezměřitelný.

Stejně důležitá je pak i jednosekundová vitální kapacita, která určuje, kolik procent vitální kapacity je pacient schopný vydechnout během jediné sekundy. Zatímco u zdravých lidí se tato hodnota pohybuje nad 80 %, u pacientů trpících respiračními obtížemi a plicními chorobami bývá nižší. Rovnoměrné snížení FEV1 a VC pravděpodobně signalizuje pokles vitální kapacity, hodnoty FEV1/VC pod 70–75 % pak obvykle značí obstrukční ventilační poruchu.

Jaké má spirometrie normální hodnoty?

Ačkoliv je spirometrie vyšetření, které je pro všechny pacienty prakticky stejné, jednotlivé hodnoty je nutné hodnotit na základě několika specifických parametrů. Důležitý je věk pacienta, jeho pohlaví, výška a hmotnost. Mladý muž, který často sportuje, totiž zcela jistě bude mít jiný dechový objem než obézní seniorka, která tráví většinu času na lůžku.

Spirometrie: správné hodnoty

  Ženy Muži
Klidový dechový objem 0,5 litru 0,6 litru
Inspirační dechový objem 2,9 litru 3,2 litru
Exspirační dechový objem 1,6 litru 1,8 litru
Reziduální objem 1,2 litru 1,4 litru
Vitální kapacita 4 litry 5,6 litru
Celková plicní kapacita 5,2 litru 7 litrů
Funkční reziduální kapacita 2,8 litru 3,2 litru

Zdroje: pneumologie.cz, wikiskripta.eu, vysetreni.vitalion.cz

  • Žádné názory
  • Našli jste v článku chybu?
'; 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'; } }
'; 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 »