Vyvinuto v ČR, vyrobeno však v Číně. Firmu u soudu zachránil „průměrný spotřebitel“

14. 6. 2023
Doba čtení: 5 minut

Sdílet

Ilustrační obrázek
Autor: Depositphotos.com, podle licence: Rights Managed
Ilustrační obrázek
Chrudimská firma, která prodávala v Číně vyrobené respirátory s nápisem „vyvinuto v ČR“, vyhrála soud nad Českou obchodní inspekcí ohledně údajného klamavého sdělení.

Nejvyšší správní soud (NSS) dal společnosti za pravdu, že inspekce ve svém rozhodnutí opomněla „průměrného spotřebitele“. Přitom právě hledisko průměrného spotřebitele je pro hodnocení nekalého jednání podle soudu klíčové. 

Co se dozvíte v článku
  1. Vyvinuto v ČR, vyrobeno však v Číně
  2. Co je nekalá praktika
  3. Kdo je průměrný spotřebitel
  4. Úřad nespecifikoval, v čem byla pravdivá informace klamavá
  5. Inspekce bude znovu rozhodovat

Vyvinuto v ČR, vyrobeno však v Číně

Česká obchodní inspekce (ČOI) uskutečnila na jaře roku 2021 na základě několika podnětů od spotřebitelů kontrolu v chrudimské firmě Pharmawex a konstatovala nekalou obchodní praktiku – klamavé sdělení. Firma totiž prodávala respirátory, na jejichž krabičce byla v kruhu znázorněna česká vlajka spolu s nápisem „vyvinuto v České republice“ (což byla i dle inspekce pravda). Stejnou kombinaci vlajky a nápisu měla žalobkyně na svých internetových stránkách. Respirátory nicméně byly vyrobeny v Číně, což na zadní straně obalu a na internetových stránkách firma také uváděla.

Podle ČOI mohl nápis „vyvinuto v České republice“ ve spojení s českou vlajkou ve spotřebitelích vyvolat mylný dojem o jednom z hlavních znaků výrobku, jeho zeměpisném původu. ČOI proto vydala dočasný zákaz uvedení na trh, distribuce včetně nákupu, dodávky, prodeje nebo použití výrobků podle § 7 odst. 1 písm. a) zákona o České obchodní inspekci.

Co je nekalá praktika

Firma se však s rozhodnutím inspekce nesmířila a podala žalobu. U Krajského soudu v Hradci Králové sice neuspěla, před několika dny jí však dal za pravdu Nejvyšší správní soud (NSS). Firmě přisvědčil, že úřad zapomněl vzít v potaz „průměrného spotřebitele“. Hodnocení, zda jde o nekalou praktiku, je totiž nutné dle právních předpisů dělat právě s ohledem na průměrného spotřebitele.

Zákon o ochraně spotřebitele v § 4 odst. 1 uvádí, že nekalou obchodní praktikou je obecně obchodní praktika, která je v rozporu s požadavky odborné péče a podstatně narušuje nebo je způsobilá podstatně narušit ekonomické chování spotřebitele, kterému je určena nebo který je jejímu působení vystaven, ve vztahu k výrobku nebo službě. Je-li obchodní praktika zaměřena na určitou skupinu spotřebitelů, posuzuje se podle průměrného člena této skupiny.

Podle § 5 odst. 2 písm. b) zákona o ochraně spotřebitele se pak za nekalou obchodní praktiku považuje také klamavé konání v podobě obchodní praktiky obsahující pravdivou informaci, jestliže vede nebo může vést spotřebitele k rozhodnutí ohledně koupě, které by jinak neučinil, pokud jakýmkoli způsobem uvádí nebo je schopna uvést spotřebitele v omyl ohledně hlavních znaků výrobku nebo služby, jako jsou údaje mimo jiné též o zeměpisném nebo obchodním původu. § 5 zákona sice „průměrného spotřebitele“ neobsahuje, úřady musí podle NSS s tímto pojmem vždy pracovat, jelikož česká právní úprava vychází z evropské směrnice o nekalých obchodních praktikách, která je na tomto konceptu postavena.

Kdo je průměrný spotřebitel

Pro oblast nekalých obchodních praktik je dnes pojem průměrného spotřebitele kodifikován v bodu 18 odůvodnění směrnice 2005/29/ES, dle něhož průměrný spotřebitel má dostatek informací a je v rozumné míře pozorný a opatrný, s ohledem na sociální, kulturní a jazykové faktory, jak je vykládán Soudním dvorem. 

Dále platí, že pojem průměrného spotřebitele není statistickým pojmem. Pro stanovení typické reakce průměrného spotřebitele v daném případě musí vnitrostátní soudy a orgány vycházet z vlastního úsudku, s přihlédnutím k judikatuře Soudního dvora. Je tedy na žalované a správních soudech, aby určily reakci průměrného spotřebitele v konkrétních okolnostech (tedy např. průměrného spotřebitele určitého výrobku). Lze tedy na tomto místě shrnout, že směrnice 2005/29/ES nechrání každého spotřebitele, ale pouze spotřebitele, který má dostatek informací a je v rozumné míře pozorný a opatrný, upřesnil NSS.

Je to podle vás nápis "vyvinuto v ČR" klamavý, pokud zboží bylo opravdu vyvinuto v ČR, ale vyrobeno v Číně?

Úřad nespecifikoval, v čem byla pravdivá informace klamavá

V daném případě tak měla inspekce dle soudu jasně vymezit, v čem i přes uvedení pravdivých informací spatřuje problém a jak tato praktika působí na průměrného spotřebitele. Jak doplnil NSS, inspekce musí pamatovat na to, že prodávající spotřebitelům sděluje pravdivé informace, které samy o sobě nekalou obchodní praktiku „nedělají“. Naopak se musí zaměřit na to, jaké další prvky obchodní praktiky nad pravdivými informacemi převažují, jak ovlivňují konečný dojem průměrného spotřebitele. Nutno uznat, že prokázání takové obchodní praktiky bude pro žalovanou často složitější než případy, kdy prodávající sdělí nepravdivé informace či určité informace opomene či zatají, připustil NSS.

Jelikož firma tvrdila, že z pohledu průměrného spotřebitele nejsou výrazy „vyvinuto“ a „vyrobeno“ shodné a že průměrný spotřebitel proto dokáže rozeznat, že respirátory nebyly vyrobeny v Česku, měla se inspekce ve svém rozhodnutí touto argumentací zabývat a vyvrátit ji. To však neučinila a průměrného spotřebitele prvně začala řešit až ve svém vyjádření ke kasační stížnosti. A to už je podle soudu pozdě. 

NSS navíc doplnil, že ČOI i tak konkrétně neuvedla, v jakých prvcích obchodní praktiky spatřuje problém nebo jakým způsobem celkové vyznění praktiky naplňuje skutkovou podstatu klamavého konání. Žalovaná např. hovoří obecně o „násobení klamavých frází, informací a grafických upozornění“, nevysvětluje ale konkrétně, co jsou třeba ona grafická upozornění a jak působí na průměrného spotřebitele. Stále také nereaguje na dokola opakovanou námitku stěžovatelky, že průměrný spotřebitel chápe význam slova „vyvinout“ a neplete si jej se slovem „vyrobit“, napsal v rozsudku NSS.

Marketing meeting Influenceři a sociální sítě

Soud rovněž uznal, že ani podněty „běžných“ spotřebitelů nemohou nahradit chybějící úvahy o reakci průměrného spotřebitele. Závěr inspekce a krajského soudu, že podněty dokazují, že „nějací“ spotřebitelé ovlivněni byli, není dostačující.

Inspekce bude znovu rozhodovat

Přestože dal NSS firmě za pravdu, zcela vyhráno společnost nemá. Samotný soud totiž uvedl, že nelze definitivně vyloučit, že posuzovaná praktika ve výsledku může uvést průměrného spotřebitele v omyl, dovést jej k rozhodnutí ohledně koupě, které by jinak neučinil, a porušovat tak § 5 odst. 2 zákona o ochraně spotřebitele. Česká obchodní inspekce tak bude o případu znovu rozhodovat.

Co je nekalá obchodní praktika?
Nekalou obchodní praktikou je obecně obchodní praktika, která je v rozporu s požadavky odborné péče a podstatně narušuje nebo je způsobilá podstatně narušit ekonomické chování spotřebitele, kterému je určena nebo který je jejímu působení vystaven, ve vztahu k výrobku nebo službě. Je-li obchodní praktika zaměřena na určitou skupinu spotřebitelů, posuzuje se podle průměrného člena této skupiny.
Kdo je průměrný spotřebitel?
Pro oblast nekalých obchodních praktik je dnes pojem průměrného spotřebitele kodifikován v bodu 18 odůvodnění směrnice 2005/29/ES, dle něhož má průměrný spotřebitel dostatek informací a je v rozumné míře pozorný a opatrný, s ohledem na sociální, kulturní a jazykové faktory.

Autor článku

Daniel Morávek píše o daních, zákonech a důchodech. Vysvětluje, jak legislativa ovlivňuje podnikatele a živnostníky. Profil autora →

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