Plyn může domácnostem za dva roky zdražit až o polovinu. Cena se zvýší i na pumpách. Někomu se to ale vyhne

29. 5. 2025
Doba čtení: 7 minut

Sdílet

Autor: Depositphotos
Domácnosti, které odebírají zemní plyn, si za něj za dva roky připlatí kvůli novému ekologickému poplatku. Zdraží také benzin a nafta. O jakém navýšení ceny odhady mluví a kdo se mu vyhne?

Domácnostem za dva roky zdraží zemní plyn a pohonné hmoty. Od roku 2027 totiž budou za emise skleníkových plynů platit i ti, kteří s ním topí nebo ho využívají na vaření. Změnu chystá Evropská unie v rámci spuštění tzv. ETS II, tedy nové verze systému emisních povolenek, které mají motivovat ke snižování emisí CO2 do ovzduší.

Emisní povolenky

Evropský systém obchodování s emisemi skleníkových plynů EU ETS (Emissions Trading System) byl na základě Směrnice Evropského parlamentu a Rady 2003/87/ES spuštěn v roce 2005. Kromě zemí EU je v něm zapojeno také Norsko, Island a Lichtenštejnsko. Systém má být nástrojem pro snižování emisí skleníkových plynů právě přes tzv. emisních povolenky. 

Jedna povolenka totiž opravňuje k vypuštění tuny oxidu uhličitého. Stát určitým sektorům stanoví, kolik emisí CO2 mohou produkovat. Pokud nějací větší znečišťovatelé hranici přesáhnou, musí si povolenky dokupovat. V případě, že někdo naopak vypustí emisí méně, může nevyužité povolenky prodávat. V současnosti (v tzv. první vlně – ETS I) platí za povolenky například průmyslové podniky (např. ocelárny, železárny, cementárny), letecké společnosti, námořní přeprava nebo elektrárny a systém je má motivovat k úsporám emisí.

V roce 2027 by se ale vedle současného systému měla rozjet druhá vlna ETS II, která bude fungovat trochu jinak a dotkne se také domácností. Zásadní novinkou je, že povinnost nakoupit povolenky nebudou mít výrobci, ale dodavatelé plynu, kteří je budou muset pořídit v objemu odpovídajícím spotřebě svých zákazníků. Jinými slovy, každý kubík plynu, který domácnost spotřebuje, bude zatížen emisní přirážkou, vysvětlil Michal Kulig, ředitel společnosti Yello v ČR s tím, že dodavatelé energií nejsou výrobci a nemají jak emise snižovat, proto budou nuceni celou cenu emisní povolenky přenést na konečného zákazníka. Stávající systém ETS I ale nekončí. Ti, kteří jsou v něm zapojeni, budou s povolenkami pokračovat dál.

Na rozdíl od původního systému z první vlny ale nebudou povolenky z druhé vlny přidělovány. Místo toho se budou prodávat v aukcích. Cílem je, aby jejich cena odrážela reálnou poptávku a zároveň tlačila na úspory. Bude existovat samostatný trh, kde se s těmito povolenkami bude obchodovat podobně jako s těmi „velkými“ v ETS I, vysvětlil Kulig.

Druhá vlna ETS II vyplývá ze strategie, jež má vést ke klimatické neutralitě do roku 2050 (European Green Deal). Součástí „zelené dohody“ je také klimatický balík opatření Fit for 55, který obsahuje mimo jiné závazek ke snižování emisí  CO2 do roku 2030 o 55 % oproti roku 1990. Jedním z průvodních opatření bylo právě rozšíření stávajícího systému obchodu s povolenkami o samostatný systém povolenek pro osobní dopravu a bydlení (zmíněné EU ETS II).

Od roku 2027 se tedy mají do systému obchodování s emisními povolenkami zahrnovat i kapalná paliva pro osobní dopravu a fosilní paliva (pevná a plynná) pro rezidenční bydlení (zahrnuje plyn, uhelná paliva, topné oleje). Opatření tak kromě plynu pravděpodobně povede i ke zdražení nafty, benzinu, zemního plynu nebo uhlí.

Zdražení je jisté

Povolenky nebudou kupovat přímo domácnosti, ale dodavatelé paliv a energií. Bylo by však naivní si myslet, že je nepromítnou do cen, které nakonec zaplatí koncoví spotřebitelé.

Podle šéfa společnosti Yello to z hlediska cen zemního plynu pro domácnosti znamená prakticky jisté zdražení. Nyní však zatím není jasné, jak velké bude. První náznaky z trhu s emisními deriváty pro ETS II už ale ukazují možný nárůst ceny o 50 %. Na burze Intercontinental Exchange proběhly první obchody na rok 2028, kde se cena povolenky pohybovala kolem 100 EUR za tunu CO₂. To by odpovídalo nárůstu ceny plynu zhruba o 15 eur za MWh. Tedy z dnešních přibližně 35 na 50 eur za MWh, vypočetl Michal Kulig.

Dodavatelé plynu teď nejsou v lehké situaci. Musí počítat s tím, že už na rok 2027 by měli zajistit povolenky, které odpovídají spotřebě jejich zákazníků. Pro stanovení konkrétní ceny, která by se promítla například do nabídek fixací i na rok 2027, je tu ale stále příliš mnoho neznámých.

Trh s povolenkami neexistuje, neproběhla aukce povolenek a ani není dokončena legislativa, a tak dodavatelé netuší, kolik budou zákazníkům účtovat. To vytváří nejistotu, kvůli které řada dodavatelů nenabízí fixní ceny. Nevědí, za kolik povolenky pořídí, a proto nechtějí uzavírat fixované smlouvy na období po roce 2026, vysvětlil Kulig, podle kterého se tak budou místo konkrétních cen zavádět často spíš cenové vzorce vycházející z budoucího vývoje cen povolenek.

Dopady na elektřinu by nyní podle něj měly být naopak minimální. Elektřina už povolenkami zatížena je, včetně elektřiny, která je vyrobena z plynu. Vzhledem k tomu, že pro výrobu tepla je plyn a elektřina zdrojem, zvýšení ceny plynu by mohlo vést k mírnému nárůstu ceny elektřiny, protože se může zlevnit výroba tepla z elektřiny a zvýšit se tak poptávka po elektřině. Pro záměnu zdroje energie je ale nutná změna technologie, takže krátkodobě k tomu nedojde, protože zatím není cena povolenky známa a není tedy možné spočítat návratnost takové změny. Nyní bych neočekával zvýšení ceny elektřiny v důsledky zavedení systému ETS II, odhaduje pro Měšec.cz šéf společnosti Yello.

Jak už jsme naznačili, změny by se měly odrazit také v ceně pohonných hmot. Zatím je však brzy spekulovat o tom, o kolik přesně by to mělo být. Odhady však už existují. Ekonomický dopad zavedení ETS II by byl značný. I za předpokladu, že by cena povolenek alespoň v prvních dvou letech po jejich zavedení nepřevýšila 45 eur za tunu CO2, dojde ke zvýšení ceny pohonných hmot o ~3,20 Kč/lt (vč. DPH). Každých dalších 10 eur v ceně povolenky pak cenu zvýší o ~0,71 Kč/lt. Při množství nafty a benzínu prodaných roce 2024 by výdaje za tyto pohonné hmoty byly vyšší o ~23,1 mld. Kč bez DPH a změna ceny povolenky opět o 10 eur mění tyto výdaje o dalších 5,1 mld. Kč, vyčíslila na svém webu Česká asociace petrolejářského průmyslu a obchodu.

V absolutních číslech (bez DPH) by se jednalo o zvýšení nákladů spotřebitelů o 22,3 mld. Kč (navíc k současným 84,1 mld. Kč ze spotřební daně), tedy o výrazný dopad do ekonomiky domácností i řady odvětví, upřesnil pro server Měšec.cz také Marek Roll ze společnosti ČEPRO.

Na co pamatovat při prodlužování nebo uzavírání smluv na rok 2027?

Při prodlužování smluv nebo uzavírání nových smluv o dodávkách zemního plynu na období od roku 2027 byste měli zkoumat, jak dodavatel plynu emisní povolenky do ceny promítne. Zda stanoví fixní cenu, bude ji odvozovat od té tržní, zda stanoví nějaký cenový strop apod. Podle Kuliga jsou zatím rozdíly v odhadech ceny povolenky enormní, a to od 55 do 91 eur za tunu CO₂. Odhadovat nyní dopady je tedy zatím těžké.

Varuje však před smlouvami, ve kterých bude zastropování. Cena pak bude neúměrně vysoká, aby pokryla rizika neexistující tržní ceny povolenky. Lze očekávat, že zákazník zaplatí mnohem větší cenu, než bude reálná cena v roce 2027. Pokud bude smlouva obsahovat pevnou cenu, je nutno hledat, zda si dodavatel nedal možnost v budoucnu cenu změnit. V tuto chvíli je určitě bezpečnější a transparentnější cenový vzorec, který sice neodstraní nejistotu z výše ceny, ale zaručí, že cena nebude příliš vysoká, řekl nám Kulig.

I když se zatím nedá odhadnout konkrétní zdražení, jasné už je, že domácnostem se vyplatí investovat do snižování spotřeby fosilních paliv. Plyn bude dražší a každá MWh, kterou nahradíte například tepelným čerpadlem nebo FVE, vám přinese finanční úsporu, protože nebudete muset platit další ekologickou přirážku, zdůraznil Kulig.

Na koho se budou vztahovat výjimky?

Výjimka z ETS II by se měla vztahovat na lesnictví, zemědělství, železniční a lodní dopravu a armádu.

Výnosy z prodeje povolenek v rámci ETS II by měly být přerozdělované zpět mezi členské státy na podporu investic za účelem snižování emisí. Druhá část bude vyčleněna na Sociální fond pro klimatická opatření, zřízený se zavedením nového systému. Z něj budou moci členské státy čerpat financování na opatření, která by měla mírnit dopady pro:

Školení pro účetní - podzimní novinky

  • zranitelné domácnosti, 
  • mikropodniky, 
  • uživatele dopravy. 

Sociální klimatický fond umožní i přímou podporu nízkopříjmovým domácnostem, uživatelům dopravy a malým podnikům. Jsem velmi rád, že se nám podařilo navýšit celkový objem fondu z 59 na 65 mld. eur, uvedl ještě jako ministr životního prostředí Marian Jurečka v roce 2022, když v rámci českého předsednictví v EU došlo k vyjednání nového systému.

Členské země musí podle novelizované směrnice na nový systém ETS II přejít. Změny do českého práva implementuje novela zákona o emisním obchodování. V případě nestandardně vysokých cen plynu nebo ropy mohou členské státy maximálně platnost opatření o rok odložit. Vláda chce usilovat o zastropování cen povolenek i zmíněný roční odklad.

Neutrální ikona do widgetu na odběr článků ze seriálů

Zajímá vás toto téma? Chcete se o něm dozvědět víc?

Objednejte si upozornění na nově vydané články do vašeho mailu. Žádný článek vám tak neuteče.


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