Ve Sněmovně leží návrh, který řadu zaměstnanců donutí podávat daňové přiznání

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

Sdílet

Autor: Depositphotos
Ministerstvo financí navrhuje zrušit srážkovou daň. Pokud změna projde, bude to pro spoustu zaměstnanců znamenat nutnost podávat daňové přiznání.

Řada zaměstnanců možná bude muset podávat daňové přiznání. Ministerstvo financí totiž navrhuje zrušení srážkové daně, která umožňuje některým poplatníkům vypořádat svou daňovou povinnost (nebo její část) jednoduše přes zaměstnavatele, jenž srážkovou daň strhne ještě před vyplacením odměny. To možná už od roku 2027 nepůjde.

Jednotné měsíční hlášení

Stát plánuje nahradit v rámci informační povinnosti zaměstnavatelů různým úřadům desítky formulářů tzv. Jednotným měsíčním hlášením zaměstnavatele (JMHZ). Jak vyplývá ze zprávy Ministerstva práce a sociálních věcí, změna by měla pomoci i zaměstnancům, například v podobě předvyplnění daňového přiznání ze strany Finanční správy. 

Co už ministr práce nemínil je to, že změna zároveň bude znamenat pro řadu zaměstnanců vznik povinnosti podat daňové přiznání. Ministerstvo financí totiž v souvisejícím návrhu (sněmovní tisk 926) počítá se zrušením srážkové daně u příjmů ze závislé činnosti.

To by znamenalo, že by například poplatníci s drobnými příjmy z brigád v řadě případů měli podávat daňové přiznání.

Srážkovou daň (jde o daň z příjmů) ve výši 15 % rovnou sráží plátce daně, který ji následně odesílá finančnímu úřadu. Příjmy daněné srážkou tvoří samostatný daňový základ. Není nutné kvůli nim podávat daňové přiznání, ale nelze uplatnit odčitatelné položky ani slevy na dani. Proto se takto daněné příjmy dají uvést do přiznání a srážkovou daň započíst na celkovou daňovou povinnost nebo poté, co poplatník učiní prohlášení lze srážkovou daň započíst v rámci ročního zúčtování.

Aplikuje se např. u dohody o pracovní činnosti (nepodepsané prohlášení a příjem do 4500 Kč měsíčně) a u dohody o provedení práce (nepodepsané prohlášení a příjem do 11 500 Kč měsíčně).

Zrušení srážkové daně ve dvou fázích

Zrušení srážkové daně by podle návrhu mělo proběhnout ve dvou krocích kvůli přípravě informačních systémů orgánů finanční správy. Ta by měla nabídnout dotčeným poplatníkům, kteří budou muset podávat kvůli rušení srážkové daně daňové přiznání, pohodlnější způsob, jak to udělat.

Během první fáze by došlo od ledna 2026 k částečnému zrušení institutu srážkové daně vybírané zvláštní sazbou u příjmů ze závislé činnosti u fyzických osob – daňových nerezidentů, které jsou členy orgánů právnických osob. Jak poukázal Stanislav Kafka ze společnosti Ernst & Young, v praxi by se např. jednatelům nebo členům představenstva, kteří budou zároveň daňovými nerezidenty, zvýšilo daňové zatížení (struktura odvodů na sociální zabezpečení a zdravotní pojištění by zůstala nezměněna).

Srážkovou daň by nahradila standardní zálohová daň ve výši 15 % (případně i ve výši 23 % u příjmů, které za rok překročí 36násobek průměrné mzdy – letos jde o částku 1 676 052 Kč).

Zároveň zákon nově výslovně upraví povinnost těchto poplatníků podat daňové přiznání za zdaňovací období od roku 2026, pokud souhrnná výše těchto příjmů za zdaňovací období překročí 36násobek průměrné mzdy (tj. hranici pro zdanění 23% sazbou daně), dodal Kafka.

K částečnému zrušení srážkové daně dojde v první fázi u daňových nerezidentů s příjmy ze závislé činnosti (členové orgánů právnických osob). U členů statutárních orgánů právnických osob se zrušení srážkové daně uplatní jen na situace, kdy členem statutárního orgánu je fyzická osoba (nikoliv právnická osoba). U právnických osob zůstává zachován režim srážkové daně. Důvodem pro zařazení této změny již do první fáze je co nejdříve eliminovat negativní rozpočtové dopady stávajícího řešení, vysvětlují autoři předlohy.

Druhá fáze, která by měla být účinná od roku 2027, by pak zrušila srážkovou daň u některých příjmů fyzických osob ze závislé činnosti úplně. Změna by se dotkla například zaměstnanců, kteří pracují na dohodu. Daň by se u těchto poplatníků vybírala zálohou, kterou bude srážet a finančnímu úřadu odvádět zaměstnavatel. 

Zaměstnanec by si pak mohl nechat zálohy na daň a slevu na děti zúčtovat od zaměstnavatele. Takovým poplatníkům by v této fázi žádná práce nepřibyla. Pokud by ale měli nárok i na další odpočty snižující daň, museli by už podat daňové přiznání. Pokud by přiznání nepodali, daň by se vyměřila ve výši zálohy.

S ohledem na potřebu nastavit údaje, které budou uváděny v rámci jednotného měsíčního hlášení (JMH) tak, aby odpovídaly druhé fázi změn pro oblast daní z příjmů, je nutné zrušit institut daně vybírané srážkou podle zvláštní sazby daně u příjmů ze závislé činnosti (srážková daň). Jde tedy o změnu vyvolanou tím, že v důsledku zavedení JMH, které správci daně poskytne na měsíční bázi informace od plátců daně (zaměstnavatelů) o zálohách k dani z příjmů fyzických osob (DPFO) ze závislé činnosti připadajících na jednotlivé poplatníky (zaměstnance), dojde k zásadní změně správy DPFO ze závislé činnosti včetně té části, kterou tvoří srážková daň, vysvětluje důvodová zpráva, proč je podle autorů předlohy nutné srážkovou daň zrušit.

Nyní má finanční úřad podle nich jen neindividualizovanou informaci o výši zálohy za plátce daně. Nově získá informaci o všech příjmech ze závislé činnosti jednotlivých poplatníků (i těch, které se v současnosti spravují jako daň vybíraná srážkou). Na všechny tyto příjmy tak má být aplikovaný stejný režim. 

Poplatník se pak rozhodne, zda u zaměstnavatele učiní prohlášení k dani a požádá si o roční zúčtování záloh a daňového zvýhodnění (tím bude jeho daňová
povinnost splněna), anebo si podá daňové přiznání sám (což je nutné např. při souběhu více druhů příjmů, včetně současného pobírání příjmů ze závislé činnosti od více plátců),
uvádí důvodová zpráva s tím, že pro tuto druhou skupinu poplatníků bude připravena služba „předvyplněného daňového přiznání“. 

Ta by jim měla kompenzovat zvýšenou administrativu spojenou se zrušením srážkové daně. Poplatníci by v rámci služby měli pro účely podání přiznání k dispozici informace, které finanční úřad získal od jejich zaměstnavatelů, ale také informace od poskytovatelů finančních produktů, které zakládají nárok na uplatnění nezdanitelné části základu daně a které by finančnímu úřadu museli tyto informace předávat (jde např. banky, stavební spořitelny, pojišťovny, penzijní společnosti či poskytovatelé dlouhodobého investičního produktu).

Výjimky

Daňový nerezident ČR je osoba, která nemá na území ČR bydliště, ani se tu obvykle nezdržuje (méně než 183 dnů za rok), ale má příjmy ze zdrojů na území ČR.

U osob vykonávajících činnost umělce, sportovce, artisty a u spoluúčinkujících osob dojde podle návrhu ke zrušení srážkové daně jen u daňových nerezidentů, kteří mají uzavřený pracovněprávní vztah přímo se zaměstnavatelem, který je daňovým rezidentem ČR nebo je daňovým nerezidentem v postavení plátce daně dle § 38c odst. 2 ZDP

U ostatních umělců, sportovců, artistů a spoluúčinkujících, kterým neplyne příjem ze závislé činnosti, by se měla srážková daň zachovat. V těchto případech daňový nerezident stále může podat přiznání, započíst si sraženou daň na celkovou povinnost a uplatnit si i související výdaje a případná zvýhodnění.

Ve vztahu k paušální dani pak dojde k doplnění speciálního pravidla. Poplatníci v režimu paušální daně nemusí podávat daňové přiznání, pokud je jejich daň rovna paušální dani. Jednou z podmínek této rovnosti je absence příjmů ze závislé činnosti – s výjimkou příjmů daněných srážkou. V souvislosti s jejím zrušením má být zavedena výjimka, podle které nebude muset poplatník s paušální daní při splněný daných podmínek podávat přiznání ani v případě, pokud bude mít příjmy ze závislé činnosti, ze kterých bude daň vybírána sražením zálohy na daň, bude-li zálohou konečnou.

Později by měli zaměstnanci komunikovat s finančákem napřímo

Ministerstvo financí v návrhu připouští, že z hlediska střednědobého horizontu zamýšlí i třetí fázi (do současné novelizace se nepromítá). V rámci té předpokládá i zrušení institutu ročního zúčtování záloh a daňového zvýhodnění prováděné zaměstnavatelem jako plátcem daně (tedy tím, kdo posílá daň za sebe i za zaměstnance finančnímu úřadu). Finanční úřad by tedy s těmito zaměstnanci pak jednal napřímo, bez zaměstnavatele.

Díky individualizaci a rozšíření možnosti získávat potřebné údaje přímo od zdroje by správce daně pro futuro mohl konečné vypořádání daňové povinnosti
poplatníků, kteří nemají jiné příjmy, které by je předurčovali k aktivnímu podání daňového přiznání, zajistit místo plátce daně tím, že by výsledek dal formou dálkového přístupu k dispozici poplatníkovi, který by aktivně (eventuálně pasivně – omisivním jednáním) výsledek potvrdil. Současně by došlo k další redukci odpovědnosti a administrativy, která podle stávající konstrukce zatěžuje plátce daně,
uvádí důvodová zpráva. Zaměstnanci, kterým z jiného titulu nevznikla povinnost podat daňové přiznání, by správci daně buď aktivním způsobem nebo naopak absencí reakce, tedy potvrdili údaje o příjmech (nebo by podali daňové přiznání).

bitcoin_smenarna

Zruší se zrušení?

Zrušení institutu srážkové daně je kritizováno jako krok, který zaměstnancům zkomplikuje život a zruší institut, který funguje. Alena Schillerová například podala k tisku pozměňovací návrh, který části týkající se rušení srážkové daně…ruší. Zástupci ANO avizují, že budou při schvalování návrhu o zrušení srážkové daně obstruovat.

Jak upozornil náš sesterský server Podnikatel.cz, ministr práce Jurečka během prvního čtení ve Sněmovně uvedl, že celý projekt jednotného měsíčního hlášení nemůže ztroskotat na sporech o zrušení srážkové daně. Je tak možné i to, že nakonec vláda od nápadu rušení srážkové daně ustoupí.

Zůstane nakonec srážková daň? Ministerstvo o tom mlží Přečtěte si také:

Zůstane nakonec srážková daň? Ministerstvo o tom mlží

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 »