Vysílání v DAB+ není pro audiofily, říkají šéfové komerčních rádií

6. 2. 2025
Doba čtení: 5 minut

Sdílet

Autor: Rádio Kiss
Rádia teď poslouchá digitálně zhruba pětina lidí. Zájem o DAB+ mají podpořit nové sítě s oblíbenými komerčními stanicemi.

České Radiokomunikace spustily v úterý 4. února svou celostátní digitální rozhlasovou síť pro komerční rádia. Ve finální podobě bude mít stejné pokrytí jako multiplex Českého rozhlasu a využije stejné vysílače. Kapacitu sítě si rozdělí několik velkých mediálních skupin, které provozují nejoblíbenější soukromá rádia.

Vysílací síť odstartovala s pokrytím 48 % obyvatel, v březnu její dosah poskočí na 80 % obyvatel. Prvním klientem je společnost Radio United Broadcasting. „Obsadili jsme třicet procent multiplexu soukromých stanic našimi šesti programy. Pro tři programy to znamená výrazné, skokové zvýšení pokrytí, byť tedy na jiné platformě, na jiné technologii,“ popsal ředitel firmy Martin Hroch.

Majitelé digitálních přijímačů s podporou DAB+ tedy mohou naladit stanice Radio 1, Signál a Spin, které na FM dosud patřily mezi regionální programy. Druhou trojici tvoří Kiss, Country Radio a Beat.

Firma postupně ukončí distribuci svých stanic v jiných digitálních sítích. Z pražského multiplexu Color DAB+ podle Hrocha odejde, jakmile to bude možné. Síť firmy RTI CZ opustí do konce prvního pololetí, protože tento multiplex teď vysílá i v oblastech, kde zatím České Radiokomunikace nespustily svou síť. Kdyby z něj rádia odešla teď, připraví o digitální vysílání například posluchače na Karlovarsku.

„Rádio stále generuje největší poslech doma nebo v práci. A stále je to časová zóna kolem jedenácté hodiny dopoledne, kdy je špička rozhlasového poslechu,“ popsal Martin Hroch. „Naopak DAB+ vnímáme spíš jako distribuci směrem do automobilů a směrem k řidičům. Pokryje delší trasy, takže posluchač v autě může být se svým oblíbeným rádiem delší dobu,“ dodal. „Podle dat z Radioprojektu tvoří poslech v autě asi 15 % z celkové poslechovosti. To není úplně tolik, kolik bychom očekávali, ale asi je to realita,“ uzavřel.

Úvodní pokrytí DAB+ Vysílací sítě B, kterou provozují České Radiokomunikace

Úvodní pokrytí DAB+ Vysílací sítě B, kterou provozují České Radiokomunikace

Autor: České Radiokomunikace

Impuls chystá hudební rádio

Dalším klientem v celostátní síti Českých Radiokomunikací bude firma Londa. V současné době provozuje tři rádia: nejposlouchanější soukromou stanici Impuls, její druhý program Český Impuls a rádio RockZone.

Přesný termín, kdy se tyto stanice objeví v digitální distribuci, ještě není jasný. „Pokročili jsme v jednání s Českými Radiokomunikacemi tak daleko, že se ten čas přiblížil. Řešíme nějaké organizační, právní a technické záležitosti, ale jsme svým způsobem domluveni na rozsahu služby a uvidíme, od kterého data ji budou pro nás provozovat,“ poznamenal ředitel firmy Jiří Hrabák.

„Jdeme do toho, protože si myslíme, že je to nutností do budoucna. Ale nemyslím, že by teď někdo dokázal u soukromníků spočítat, jaký to bude mít dopad – na prvním místě na počet posluchačů,“ dodal na tiskové konferenci Českých Radiokomunikací. „Je třeba si pokládat otázku, jestli se tím ještě může vůbec zvýšit celkový poslech rádií. Nebo nemůže a dojde jen k diverzifikaci stávajícího počtu posluchačů do jednotlivých fragmentovaných kanálů?“ upozornil.

Kromě tří existujících stanic Londa plánuje umístit do vysílací sítě ještě další program. „Budoucnost z dlouhodobého hlediska je, aby v DABu nezůstala jen stávající rádia. To pak není vývoj, jenom obrana. My musíme dělat i tu obranu a pak záleží, jestli vymyslíme takové programy za takové peníze, aby je lidi poslouchali. Obsah je primární, na to se občas zapomíná,“ dodal Hrabák.

Novinářům prozradil, že nová stanice bude připravená asi za půl roku. „Bude to hudební rádio, ale nebude to jenom hudba. Nechci v tuto chvíli říkat, jaký to bude žánr, protože připravujeme dva nebo tři. Rozhodujeme se, které budou jako stream a který z nich půjde na DAB,“ přiblížil.

Předpokládané pokrytí DAB+ Vysílací sítě B v březnu 2025

Předpokládané pokrytí DAB+ Vysílací sítě B v březnu 2025

Autor: České Radiokomunikace

Soukromá rádia musí u nových stanic spočítat návratnost investice. „Přijde-li nový program, na kterém bude 60–80 tisíc posluchačů denně, tak to budu velmi překvapený. Přijde-li program, který bude mít 40–50 tisíc posluchačů denně, tak to už dokážou prodat. Jestli někdo bude mít nižší čísla, 20–30 tisíc posluchačů, tak to prodat nedovedou,“ nastínil.

„Zkuste se podívat, jaká jsou celková čísla poslechovosti rádií Českého rozhlasu, která vysílají jenom přes DAB, a jaká jsou čísla těch, která vysílají přes FM. S tím samým problémem se budeme potýkat i my. Jenom budeme muset přijít na to, jestli je dokážeme prodávat i s menším počtem posluchačů. Třeba budou pro [reklamního] klienta lépe uchopitelná a afinita [cílové skupiny posluchačů] tam bude silnější,“ doplnil Jiří Hrabák.

Nejposlouchanější čistě digitální stanicí je v současné době Radiožurnál Sport. Loni na podzim ho podle údajů Radioprojektu zapínalo 16 tisíc lidí denně, týdenní poslechovost byla 43 tisíc lidí. Přibližně 18 % lidí v průzkumu poslechovosti uvedlo, že poslouchají oblíbené stanice právě prostřednictvím DAB+. 

Chcete super zvuk? Kupte si gramofon

Komerční stanice samy rozhodují o parametrech digitálního vysílání svých programů. DAB+ je pro ně jen další distribuční kanál. A také způsob, jak z regionálních stanic udělat celoplošné. „Jsem rád, že jsme zahájili dobu ne digitální, ale hybridní,“ zdůraznil šéf Radio United Broadcasting Martin Hroch. „FM vysílání je stabilizované, a zřejmě ani na základě platné legislativy, ani na základě naší svobodné vůle se v dohledné době vypínat nebude. Klíčová je totiž penetrace rozhlasovými přijímači,“ doplnil.

Každý měsíc se prodají desítky tisíc nových radiopřijímačů, Češi ale dávají přednost těm klasickým. Data o maloobchodních prodejích vyhodnocuje společnost GfK a z jejích statistik vyplývá, že například v prosinci 2024 se prodalo skoro 68 tisíc kusů rádií. Ale jen 16 tisíc jich patřilo do kategorie přijímačů s DAB+. Tržní situace je tak naprosto obrácená ve srovnání s Německem, kde 65 % nově prodaných přijímačů tvoří zařízení s podporou DAB+.

Data o prodeji rádií v české maloobchodní síti

Data o prodeji rádií v české maloobchodní síti

Autor: GfK / České Radiokomunikace

„Nejčastěji posloucháme výčitky k datovým tokům, jak malou kapacitu využíváme a tak dále. K tomu bych chtěl říct, že rádio není a nebylo Hi-Fi, aby ho někdo poslouchal jako zdroj toho nejkvalitnějšího audiosignálu. Už od samého počátku používáme nějaký processing, nějakou úpravu zvuku, jak na FM, tak na DAB. Takže hifistům musím říct: kupte si gramofon, zesilovač a bedny, a tam si holt poslouchejte Hi-Fi. Rádio je o poslechu v autě, kde máte ještě nějaký rušivý zvuk, hluk okolí a podobně. Je to o poslechu v práci, v kanceláři nebo doma. Není to hifistické médium,“ namítl Martin Hroch.

Kromě datového toku je podle něj nutné zohlednit také zvolený kompresní formát (v síti Českých Radiokomunikací se používá kódování HE-AAC v2). Soukromá rádia podle Martina Hrocha provedla srovnávací posluchačské testy a současné nastavení se jeho slovy ukázalo jako „úplně vyhovující“.

MM Influenceři

Společnost Londa chce pro svá rádia zvolit podobný datový tok, jako má stanice Kiss, tedy 48 kbit/s. „A dokonce si myslím, že během tří čtyř let dojde k takovému technologickému posunu, že se s klidem bude moct vysílat i s nižším datovým tokem a ta kvalita bude rozhodně ne pro hifisty, ale pro normálního posluchače rádia,“ dodal Jiří Hrabák.

Prezentace Českých Radiokomunikací s technickými parametry sítí:

  • Chcete mít Lupu bez bannerů?
  • Chcete dostávat speciální týdenní newsletter o zákulisí českého internetu?
  • Chcete mít k dispozici strojové přepisy podcastů?
  • Chcete získat slevu 1 000 Kč na jednu z našich konferencí?

Staňte se naším podporovatelem

Autor článku

Novinář se zaměřením na média. Dlouholetý účastník i pozorovatel českého mediálního cirkusu. Pracoval v Marketing & Media, Hospodářských novinách a Českém rozhlase.

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