Na jaké změny musíte pamatovat pro letošní daňové přiznání?

4. 3. 2025
Doba čtení: 7 minut

Sdílet

Ilustrační fotografie.
Autor: Depositphotos Inc.
Ilustrační fotografie.
Část věcí bude při podávání daňového přiznání oproti předchozímu roku jinak. Na které změny musíte letos pamatovat?

Podání přiznání k dani z příjmů za minulý rok ovlivní několik změn.

Čím už si daň nesnížíte?

V nadcházejícím daňovém přiznání poprvé nebude možné odečíst daňovou slevu za umístění dítěte v předškolním zařízení (tzv. školkovné) a daňovou slevu na studenta.

Od základu daně už také neodečtete zaplacené příspěvky odborům a úhradu zkoušky ověřující další vzdělávání.

Naposledy bylo možné je uplatnit loni, tedy při podávání daňového přiznání (nebo při zúčtování daní) za rok 2023.

Další podmínka u slevy na manžela

Od roku 2024 také platí další podmínka pro vznik nároku na daňovou slevu na vyživovaného manžela (platí i pro registrované páry). 

Nárok na ni vzniká v případě, že s vámi žije daná osoba ve společné domácnosti, její příjmy (před odečtením výdajů) za minulý rok nepřesáhly hranici 68 000 Kč a pečuje o vyživované dítě do tří let věku. Může jít o vlastní či osvojené dítě nebo o dítě druhého z manželů. Sleva jde uplatnit také při péči o vnuka (vlastního, nebo druhého z manželů) za podmínky, že jde o péči nahrazující péči rodičů.

Podmínka ročních příjmů do 68 tis. Kč zůstává beze změny.

Daňové slevy 2025: Čím si letos můžete snížit daň z příjmů? Přečtěte si také:

Daňové slevy 2025: Čím si letos můžete snížit daň z příjmů?

Rozšíření u daňového zvýhodnění (slevy na děti)

Od roku 2024 podle § 35c odst. 8) platí, že pokud zletilé či (nově i) nezletilé vyživované dítě ve společně hospodařící domácnosti uzavře manželství, může uplatnit jeho manžel slevu na vyživovaného manžela (vznikne-li na ni nárok). Tato sleva se uplatňuje v takovém případě přednostně. 

Pokud se ale stane, že manžel nemá příjmy, aby se dala sleva od daně odečíst, může si rodič dítěte nebo poplatník, u něhož jde ve vztahu k dítěti o péči nahrazující péči rodičů, místo toho uplatnit daňové zvýhodnění (pokud dítě a vyživované dítě tohoto dítěte vymezené pro uplatnění slevy na manžela s ním žije ve společně hospodařící domácnosti).

Limit příjmů pro daňový bonus

V letošním roce je nutné mít pro vznik nároku na čerpání daňového bonusu vyšší příjmy (ze zaměstnání či podnikání) než loni. Změna vyplývá z růstu minimální mzdy. Daňový bonus může čerpat jeden z rodičů, pokud měl v daném roce příjem ze zaměstnání nebo podnikání minimálně ve výši šestinásobku minimální mzdy.

Pro příjmy za rok 2024 jde o částku 113 400 Kč (pro příjmy za rok 2025 pak o částku 124 800 Kč).

Zaměstnanci mohou uplatňovat slevu na dítě a tím i daňový bonus už během roku na měsíční bázi. Je ale nutné mít hrubou mzdu vyšší než polovinu minimální mzdy, tedy 10 400 Kč.

Výše daňového bonusu už není na měsíční ani roční bázi nijak zastropovaná.

Prodloužení výjimky pro vyšší limit na odpočet darů

Došlo k dalšímu prodloužení dočasného navýšení limitu pro odečet bezúplatných plnění od základu daně. Dary je i nadále možné odečítat do 30 % základu daně.

Kromě roku 2024 byla výjimka prodloužena také pro roky 2025 a 2026.

Opatření má kořeny už v době koronavirové pandemie, poté zůstalo v platnosti kvůli válce na Ukrajině a naposledy platnost prodloužila novela Lex Ukrajina

Stále je tedy možné zahrnovat do tohoto odpočtu i dary na podporu napadené Ukrajiny podle pravidel platných pro rok 2023. Vyšší limit ale platí pro všechny dary, které zákon připouští odečítat od základu daně (například tedy i dary pro likvidaci následků loňských povodní apod.).

Daň z příjmů za rok 2024: Čím si letos můžete snížit základ daně? Přečtěte si také:

Daň z příjmů za rok 2024: Čím si letos můžete snížit základ daně?

Společný limit pro podporované produkty zajištění na stáří

Od základu daně je možné odečíst platby na finanční produkty, které stát podporuje pro účely zabezpečení na stáří. Od roku pro tyto účely platí souhrnný limit 48 tis. Kč za rok, který můžete podle svých preferencí uplatnit kromě penzijního připojištění, doplňkového penzijního spoření ze třetího pilíře a životního pojištění (kromě čistě úrazového) také na další tzv. podporované produkty spoření na stáří – zejména z oblasti investic (musí jít o tzv. DIP) a případně i na pojištění dlouhodobé péče.

Abyste si mohli platby od základu daně odečítat, musí smlouva plnit zákonné podmínky z § 15a a § 15b (např. výběr až v 60 letech, platnost smlouvy aspoň na 120 měsíců, resp. 60 měsíců při sjednání do konce roku 2023 apod.).

Jak se změní penzijko? Kdo musí platit víc, aby nepřišel o příspěvek, a kdo ho už nedostane vůbec? Přečtěte si také:

Jak se změní penzijko? Kdo musí platit víc, aby nepřišel o příspěvek, a kdo ho už nedostane vůbec?

Řešíte daně? Při výpočtu vám pomůže naše daňová kalkulačka. Abyste pak měli výpočet kam zapsat, stáhněte si formuláře daňového přiznání, které obsahují i přehledy pro zdravotní pojišťovnu a správu sociálního zabezpečení.

Limit pro aplikaci druhého pásma daně

Od roku 2024 došlo ke snížení hranice pro aplikaci 23% sazby daně z příjmů z původního 48násobku na 36násobek průměrné mzdy. U příjmů za rok 2024 jde o částku 1 582 812 Kč ročně (131 901 Kč měsíčně).

Pro příjmy za rok 2025 platí hranice 1 676 052 Kč za rok (měsíčně 139 671 Kč).

U zaměstnanců se tímto limitem testuje součet hrubých mezd, u OSVČ jde o roční příjmy po odpočtu výdajů.

Limit pro zdanění penze

Pravidelně vyplácené důchody jsou od daně z příjmů osvobozené do 36násobku minimální mzdy. Pro rok 2024 to odpovídalo částce 680 400 Kč, pro rok 2025 je to částka 748 800 Kč.

Limit pro osvobození příjmů z výher

Limit pro osvobození příjmů z tombol a hazardních her (například kurzové sázky, Sportka, poker nebo ruleta) se od roku 2024 výrazně snížil. Nově je osvobozena jen částka do 50 tis. Kč místo do 1 mil. Kč. Skupina lidí, kteří budou muset za loňský rok kvůli výhře podávat daňové přiznání, se tak o dost zvětší.

Vyhráli jste loni peníze? Možná musíte podat daňové přiznání. Vysvětlíme proč Přečtěte si také:

Vyhráli jste loni peníze? Možná musíte podat daňové přiznání. Vysvětlíme proč

Termíny pro podání daňového přiznání a přehledy

Letos tedy vychází lhůty pro řádné podání přiznání k dani z příjmů takto: 

  • základní lhůta pro papírové do 1. dubna 2025,
  • lhůta pro přiznání podávané elektronicky do 2. května 2025,
  • lhůta pro přiznání podané přes daňového poradce a advokáta do 1. července 2025.

Pro většinu poplatníků z řad fyzických osob platí květnový termín kvůli zavedení povinnosti podávat přiznání související s podnikáním elektronicky za podmínky, že stát subjektu zpřístupnil datovou schránku.

Přehledy je letos za loňský rok nutné podat nejpozději do:

  • do 8. 4. 2025 pro OSVČ, které nemají povinnost podávat daňové přiznání za rok 2024 (platí pouze pro zdravotní pojišťovny),
  • 2. 5. 2025, pokud jste daňové přiznání podali ve lhůtě 3 měsíců od uplynutí minulého roku (bez ohledu na formu podání),
  • 2. 6. 2025, pokud přiznání odevzdáte elektronicky po 1. 4. 2025,
  • 31. 7. 2025, pokud jste neměli povinnost podat daňové přiznání (platí pouze pro přehled pro ČSSZ),
  • 1. 8. 2025, pokud daňové přiznání podá daňový poradce po 1. 4. 2025.

Přehled o příjmech a výdajích pro ČSSZ povinně elektronicky

Od letošního roku i pro přehled o příjmech a výdajích pro Českou správu sociálního zabezpečení (ČSSZ) platí, že máte-li ze zákona zpřístupněnu datovou schránku, musíte dělat podání pro tento úřad už jen elektronicky (k podání v papírové formě se nepřihlíží).

(V případě přehledu pro zdravotní pojišťovnu si OSVČ může vybrat, zda zvolí elektronickou formu přes rozhraní konkrétní zdravotní pojišťovny, pošle formulář datovou schránkou, poštou, nebo ho donese na pobočku osobně.)

Přehledy pro sociálku a další tiskopisy musí většina OSVČ od letoška podávat jen elektronicky Přečtěte si také:

Přehledy pro sociálku a další tiskopisy musí většina OSVČ od letoška podávat jen elektronicky

Způsob podání přehledu

Zákon předepisuje, že elektronické podání by mělo být učiněno ve formátu XML. ČSSZ ale volí benevolentnější přístup a připouští i jinou elektronickou formu.

Byť je pro podání přehledu o příjmech a výdajích OSVČ zákonem předepsaný způsob, tj. podání ve formátu XML, i přesto ČSSZ akceptuje i podání ve formátu PDF (vyplnění přehledu ve formátu PDF a jeho následné zaslání do datové schránky příslušného kontaktního pracoviště územní správy sociálního zabezpečení, které je také považováno za elektronické podání), řekla serveru Měšec.cz mluvčí ČSSZ Jitka Drmolová.

Akceptovatelné způsoby elektronického podání tedy jsou:

  • prostřednictvím interaktivního formuláře z ePortálu ČSSZ – tiskopis pak odesíláte ve formátu XML přímo vaší místně příslušné správě sociálního zabezpečení (po přihlášení do ePortálu ČSSZ – např. prostřednictvím ověření datovou schránkou – se vám značná část údajů do přehledu vyplní automaticky),
  • ve formátu XML prostřednictvím přímého kanálu (přes veřejné rozhraní pro e-Podání (VREP/APEP) za podmínky, že vlastníte uznávaný elektronický podpis),
  • v čitelném formátu (např. v PDF) doručit formulář na e-podatelnu nebo do datové schránky příslušné správy sociálního zabezpečení, pokud máte uznávaný elektronický podpis nebo datovou schránku.

Nemáte-li zpřístupněnou datovou schránku ze zákona, můžete zaslat formulář z ePortálu ČSSZ např. ve formátu PDF na e-podatelnu (máte-li uznávaný elektronický podpis) nebo ho doručit na příslušnou správu sociálního zabezpečení poštou či osobně. V situaci, kdy se potýkají s technickými obtížemi, mohou využít podání v listinné formě i OSVČ, které by měly podat formulář elektronicky. Musí ale důvod řádně vysvětlit, jinak nebude k této formě podání přihlédnuto.

bitcoin_smenarna

Připomeňme ještě, že u důchodového pojištění od loňska platí, že vyšel-li nový vyměřovací základ vyšší než ten původní, je nutné navýšit zálohu na pojistné, ale vždy až od následujícího měsíce po tom, v němž byl, nebo měl být přehled podán.

Navyšování minimálních záloh v novém roce se sjednotí. Více na důchodové pojištění zaplatíte už od ledna Přečtěte si také:

Navyšování minimálních záloh v novém roce se sjednotí. Více na důchodové pojištění zaplatíte už od ledna

U zdravotního pojištění naopak platí, že novou výši zálohy vypočtenou dle přehledu zaplatí OSVČ poprvé už za měsíc, ve kterém byl, nebo měl být přehled podán.

Do kdy podat daňové přiznání a do kdy přehledy? Přinášíme přehled termínů a důležitých informací Přečtěte si také:

Do kdy podat daňové přiznání a do kdy přehledy? Přinášíme přehled termínů a důležitých informací

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 »