Jsou dotace na vysokorychlostní internet skutečně tak zásadní?

8. 11. 2017
Doba čtení: 7 minut

Sdílet

Autor: Depositphotos
Stále je omílána mantra o digitální společnosti, s digitálním vládnutím, digitálním vzděláváním a vůbec celou digitální společností. Svět je ale třeba vnímat v souvislostech.

Digitalizace, elektronizace, to všechno se stalo i předmětem předvolebního boje. Úspěch Pirátů dokazuje, že téma společností rezonuje. I celá Evropská unie vidí ve vlastní digitalizaci příležitost k hospodářskému růstu a k vyřešení některých problémů členských států.

Jedním z velkých problémů je vylidňování venkova, odchod kvalifikované pracovní síly do velkých měst. Bezesporu bychom našli nádherné vize společnosti 21. století, jenže bez potřebné vysokorychlostní infrastruktury nezbude nic více nežli krásná slova. Infrastruktura vysokorychlostního internetu příští generace (NGA) je základním kamenem všech těch vzletných slov.

Co je to vlastně NGA infrastruktura?

Laicky zkrácená definice zní, že je z části nebo zcela postavená na technologiích optických vláken. Poskytuje stabilní připojení rychlostí alespoň 30 Mb/s. Přesné definice se zabývají technickými detaily podrobně, ten nejdůležitější je parametr uploadu.

NGA je správně. Nikdo nezpochybňuje, že základní připojení domácnosti například v roce 2020 by mělo mít možnost zvládat souběžně dva kanály internetové televize IPTV v HD kvalitě, k tomu běžný provoz pro brouzdání na webu, s rychlým nahráváním souborů, třeba videí ze školní slavnosti ve 4K kvalitě, na server pro sdílení s partou ze třídy.

Tohle všechno je 21. století. Z pohledu cílů EU je dobré zmínit, že takové základní připojení už neomezuje nikoho v práci z domova. Pokud bude dobré napojení na silniční a internetovou síť, zůstávají v regionech i zaměstnavatelé. A o to také jde, nechceme mít všechny firmy v Praze a v Brně.

Investice se musí zaplatit

Zmínili jsme silniční síť. Všichni víme, jak „dobře“ se staví v České republice silnice a dálnice. Všichni jste jistě slyšeli v médiích o průtazích při povolování staveb. Telekomunikační infrastruktura je liniová stavba. Její výstavba je svázaná nadmíru složitou administrativou, poplatky a vyrovnáním za umístění optických vláken do pozemků po cestě. K tomu se ještě vrátíme, tak popořadě.

Představme si analogii k silniční síti. Takové dálnice a silnice prvních tříd jsou v internetovém světě definované jako páteřní sítě a vzhledem ke strategické poloze státu je backbone dobře rozvinutý. Staví se v železničních koridorech, podél plynovodů, ropovodů, kapacita není problém. Jeho vybudování se „svezlo“ s velkými stavbami.

Vlákna mají rozličná využití, tečou přes ně desítky až stovky gigabitů rozličného provozu. Pouze menší procento jsou data vygenerovaná provozem v domácnostech. Do všech krajských, velké většiny okresních měst a oblastních center vedou optické kabely páteřní infrastruktury mnoha poskytovatelů.

Jenže k NGA domácnosti ještě musí data vyjet po silnici 2., nebo 3. třídy po přípojné části sítě. Právě tady je zakopaná polovina psa. Druhá polovina psa je zakopaná v rozvodech sítě po samotné obci.

K výstavbě sítě musí být komerční důvod, investice se musí zaplatit. Výstavba a provoz infrastruktury telekomunikační sítě jsou hodně odborné disciplíny, svázané stovkami regulací a nařízení. Samotné poskytování služeb elektronických komunikací je téma, které by vydalo na samostatný článek.

Řízení sítí, provozu, bezpečnosti dat, ochrana osobních údajů včetně nového GDPR nařízení – tohle všechno musí operátor zvládat a hlavně zaplatit. Pro někoho zbytečná věta, jenže těch pár stokorun měsíčně bez DPH za připojení domácnosti není zisk.

Je přirozenou snahou podnikatelů, že investují do infrastruktury především tam, kde je hodně zákazníků. A to nenahrává do karet malým obcím v regionech.

Jak rozšířit optiku i do malých obcí?

Například ve Středočeském kraji je skoro 1100 obcí. V přibližně 300 obcích žije od desítek po čtyři stovky lidí. Při přepočtu na domácnosti dostaneme počty zákazníků, přidáme konstantu 1000 korun za metr výkopu optické sítě a dojdeme k zajímavému výsledku návratnosti z poskytování služeb.

Modelová obec má náves 3 km od přípojného bodu páteřní optické sítě. V tohle místě je třeba zmínit, že pravděpodobně v každé obci například Středočeského kraje je připojení dostupné, a tam, kde není optické vlákno dostupné, tam místní regionální operátoři používají radiové datové spoje v profesionálních pásmech.

Co udělat proto, aby přinejmenším přípojná část sítě byla optická? Udělal jsem si malou anketu přímo mezi středočeskými operátory. Odpovídali mi zástupci regionálních sítí, kteří kromě optických přípojek poskytují služby pomocí bezdrátového připojení.

Pavel Ježdík ze společnosti Eurosignal provozuje optickou síť v Berouně, v Mníšku pod Brdy a snaží se rozšiřovat optické aktivity i mimo tato větší města. Petr Dvořák z UVT nedávno dostavěl optickou síť v Berouně, v Jesenici u Prahy a v částech hlavního města. Na názor na výstavbu optických sítí v malých obcích v dosahu pokrytí jeho sítě jsem se ptal i Jana Pilného z Újezd.Net.

Všichni tito pánové poskytují na území Prahy a Středočeského kraje služby tisícům domácností. Odpovídali na otázky:

  • Je reálné dodržet cíle vládního dokumentu Digitální Česko 2.0?
  • Co by vám nejvíce ulehčilo výstavbu?
  • Které administrativní překážky jsou největší brzdou výstavby?
  • Počítáte s využitím dotací z EU?
  • Pánové, DigiČesko 2.0 je vládní strategie, podle které bude mít v roce 2020 každá domácnost možnost připojovat se k internetu rychlostí nejméně 30 Mb/s a polovina z nich 100 Mb/s. Je takový cíl dosažitelný?

Petr Dvořák odpovídá na první otázku ke strategii DigiČesko. „Největší problém bude s kapacitou přípojné sítě do malých obcí. V zásadě je to jednoduché. Samotná distribuce po obci je řešitelná, částečně optickou sítí, částečně bezdrátovými přípojkami. Přichází nové bezdrátové technologie, regulátor otevírá nová pásma. Máme před sebou výstavbu sítí 5. generace, proběhla aukce na 3,7GHz kmitočty. Kdo se bude chtít na trhu udržet, musí investovat. To je především ku prospěchu zákazníka. U nás ve firmě ale řešíme problém s přechodem zákazníků z bezdrátů na vybudovanou optickou síť. I přes dostupnost vláknové optiky, za v podstatě stejnou cenu, zůstávají zákazníci věrní stávajícímu připojení. Problém je přivedení optického vedení přes pozemek zákazníka. Bezdrátová služba pokrývá jejich potřeby. To se ale časem může změnit.“

Jan Pilný hovoří o usnadnění výstavby: „Nyní probíhají práce na výstavbě čistě optické sítě ve dvou lokalitách. V jedné jsme se dobře domluvili se zastupitelstvem na ceně věcných břemen za použití obecních chodníků. Paralelně s opravami povrchů silnic pokládáme mikrotrubičky. Podmínkou obce bylo budování infrastruktury jako otevřené sítě. Každý další operátor může využít naši infrastrukturu za nediskriminačních cenových podmínek. Naproti tomu v jiné obci jsme stále ve fázi přípravy projektu. Jedná se o obec s malým sídlištěm, z obchodních důvodů neuvádím její jméno. Některé pozemky patří státním organizacím, nikoliv obci. Cena věcných břemen je zde nejvyšší položkou celé investice. Přívod optické páteře leží za železniční tratí a státní silnicí. Administrativa spojená s přechodem takových komunikací je časově náročná. Nemluvíme o měsících, ale o letech. Málokdo by to byl řekl, ale velkou překážkou je zelený koridor v cestě. Naprosto respektujeme ochranu přírody, jenomže jsme toho názoru, že tahu žab zakopané optické vedení nějak nepřekáží. Jsme ochotní respektovat omezení při výstavbě a provozu sítě. Stanovisko dotčeného oboru životního prostředí je negativní. Práci se zasíťováním nám nějak neulehčuje forma správy domů. Jedná se o SVJ a souhlas s umístěním stavby musíme získat prakticky od všech vlastníků. To je velká úloha, časově a finančně náročná.“

Pavel Ježdík hovoří o dotacích: „V první výzvě dotací z EU na rozvoj NGA infrastruktury byly dvě podmínky, kvůli kterým jsme si projekt nepodali a raději stavíme z vlastního. Projekty na pokrytí bílých míst bez dostatečné rychlosti přípojek jsou příliš velké. Pokud si představíte, že musíte pokrýt z vlastních prostředků investici ve výši několika desítek milionů korun, o územním rozsahu třeba pětiny okresu, a máte na to dejme tomu maximálně 5 let času i s projektovou přípravou… Nakonec vyhoříte na administrativních překážkách. Dotace jsou vypláceny zpětně a každý nedostatek v projektu dotace krátí. Navíc jsou určené pouze na pasivní části sítě, tedy nikoliv na celou investici. Když jsme si modelovali projekty, tam, kde by to dávalo smysl, tam jsme nedocílili minimální předepsané územní velikosti. MPO, které dotace připravuje, musí snížit rozsah intervenčních oblastí a podpořit i dotace na aktivní technologie.“

Když vás tíží břemena

Tito tři středočeští operátoři se shodují, že zásadní je především koordinace. Pokud třeba ŘSD, krajská Správa údržby silnic či obec plánuje rekonstrukci komunikací, veřejného osvětlení, vodovodů, měla by takové investice dávat s dostatečným předstihem operátorům na vědomí.

Ostatně jim to nařizuje i zákon, jenomže ten byl přijat teprve v červnu. Mnoho správ a samospráv o něm zatím netuší. Přitom operátoři by se rádi za účast na stavbě finančně podíleli. Pravidla pro čerpání veřejných prostředků totiž neumožňují přidat se ke stavbě v momentě, kdy jsou již výkopové práce zahájené.

CIF25 SE debata

Stát si schválil strategie rozvoje sítí, ale musí pro rozvoj digitalizace udělat mnohem více. Dotace sítě NGA nepostaví. Operátoři všech velikostí potřebují neinvestiční pobídky. Odstranění zbytečné administrativy je jen jeden z nezbytných kroků pro výstavbu infrastruktury.

Nutné je snížení odpisové doby z 20 let na nějakou přiměřeně dlouhou dobu. Pro přivedení optických páteří i do malých obcí je nutná koordinace krajských samospráv. Každá obec, která se cítí být ochuzená o vysokorychlostní přípojky pro své obyvatele, by měla držet cenu věcných břemen v rozumné výši.

Autor článku

Autor je prezidentem Výboru nezávislého ICT průmyslu, asociace českých telekomunikačních společností. V letech 2020 – 2024 působil jako člen zastupitelstva Středočeského kraje za ODS.

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