Nejvýhodnější véčko s dvěma displeji: Recenze Samsung Galaxy Z Flip3

16. 11. 2021

Sdílet

 Autor: Cnews.cz
Skládací telefony začínají být dostupné i za relativně dostupnou cenu. Pokud toužíte po ohebném displeji, Galaxy Z Flip3 za 26 990 Kč je nyní zřejmě nejvýhodnější volbou. Na rozdíl od funkčně nabitého Foldu sází Flip spíše na styl, ovšem tvar véčka může být velmi praktický.

Flip3 patří mezi telefony s ohebným displejem, které se skládají na výšku. Podobně jako klasická véčka. V zavřeném stavu je velmi kompaktní, na vnější straně má malý 1,9" OLED displej se kterým si lze pořídit selfie přes hlavní kameru. Po otevření získáte běžný smartphone s velkým 6,7" OLEDem. Proti minulé (první) generaci spadla jeho cena asi o dvanáct tisíc.

V otevřeném stavu už jde o obří telefon a bez přehmatávání na dolní tlačítka a současně na horní lištu nedosáhnete. Také poměr stran je výrazně širokoúhlý (22:9 je dokonce více, než kolik mají Xperie). V balení už nedostanete nabíječku, kterou si musíte pořídit zvlášť – nebo používat nějakou co už máte. Kabel s koncovkami USB-C  ale v krabičce je. Vybírat můžete ze tří lesklých barev (zelená, fialová a krémová), nebo sáhnout po matné černé. Samsung pro tento model vyrábí několik stylových pouzder včetně poutka na „klíče“. Jak budete telefon nosit je na vás, před dvaceti lety je někteří nosili třeba i na krku.

V zavřeném stavu je telefon stále relativně tenký, jen nemá tvar typický pro telefon. Je to takový kvádřík, jež se ale vejde do většiny kapes. Mezi oběma půlkami displeje zůstává asi milimetrová mezera. Je dobré se snažit, abyste telefon nezavřeli s nějakým ostrým kamínkem, ale jinak se konstrukce zdá velmi pevná. Při troše šikovnosti se dá otevřít i jednou rukou, i když ne tak snadno a efektně jako stará véčka. Čtečka otisků a zapínací tlačítko v jednom se trochu plete s kloubem, který lze na pohmat také považovat za tlačítko. Výškové umístění tlačítek mi přijde trochu nezvyklé.

Konstrukce využívá hliníkový rám a telefon je vodotěsný (IPx8). Pokud s telefonem zmoknete, nemělo by se nic stát. Voda se sice může dostat do kloubu, ale zase z něj vyteče.

model Samsung Galaxy Z Flip3
displej 6,7" (22:9) AMOLED, 1080 × 2640 px, 120 Hz
přední: AMOLED 1,9"
skutečná velikost telefonu 7,18"
rozměry 166 × 72,2 × 6,9 mm
86,4 × 72,2 × 15,9 mm
hmotnost 183 g
zvýšená odolnost Gorilla Glass Victus, IPx8
Hardware
SoC Snapdragon 888 5G (5 nm)
paměť 8+128 GB
8+256 GB
akumulátor 3300 mAh
Fotoaparát
hlavní kamera 12 Mpx, OIS, 4K
ultraširokoúhlá kamera 12 Mpx
teleobjektiv
další kamery
přední foťák 10 Mpx
Výbava
konektory USB-C 2.0
mobilní data 5G
SIM nanoSIM + eSIM
Wi-Fi Wi-Fi 6 (802.11ax)
Bluetooth Bluetooth 5.1
NFC NFC
biometrika čtečka otisků na boku
nabíječka není v balení, 15 W
bezdrátové nabíjení 10 W
Dostupnost
představení srpen 2021
zahájení prodeje v Česku srpen 2021
barevné varianty Black, Cream, Gray, Green , Lavender
doporučená cena při uvedení 26 990 Kč

Displej

Ohyb v displeji je stále patrný – je vidět i cítit bříškem prstu. Po pár týdnech to pravděpodobně většina lidí přestane vnímat. Samsung uvádí, že displej kryje Gorila Glass Victus, byť na omak je samozřejmě měkčí.

Na displeji je z výroby ochranná fólie, která je součástí celého mechanismu a nesmíte ji slepit. Samsung již dostatečně vychytal mechanismus kloubu, který je nyní i voděodolný. Podle výrobce vydrží 200 tisíc otevření a zavření. Kloub lze navíc nechat otevřený v několika pozicích a využívat telefon jako foťák s přirozeným stojánkem/stativem. Jen to nesmí být o moc víc než 90°, jelikož potom na stole přepadává.

Venkovní displej využitelný v zavřeném stavu má 1,9" a je proti minulé generaci 4× větší. Kromě zobrazení času si zde můžete prohlédnout widgety počasí či kalendáře, příchozí notifikace a funguje i jako náhledový displej pro focení selfie.

Otevřením véčka můžete přijmout hovor a zaklapnutím zase ukončit. Přijetím hovoru na vnějším displeji zavřeného telefonu aktivuje hlasitý hovor.

Tento displej má ale pořád velké rezervy, respektive nevyužitý potenciál. Ideální by totiž (subjektivě) bylo, kdyby byl přes celou polovinu zad a umožňoval běžné ovládání telefonu jako u Foldu.

Výbava

Flip3 je díky Snapdragonu 888 poměrně výkonný, ale také poměrně topící. Pro tento telefon je jeho výkon trošku zbytečný. V prodeji jsou dvě paměťové varianty 8+128 a 8+256 GB, přičemž ta vyšší je o dva tisíce dražší. Konektivita není nijak ošizená, vedle Wi-Fi 6 umí telefon 5G a k jedné nanoSIM můžete přiřadit i eSIM. Na rozdíl od modelu Fold3 mu schází podpora pera S Pen.

Displej umí adaptivní frekvenci až 120Hz a podle potřeby ji snižuje až na 10Hz. Že by ale díky tomu byla výdrž baterie výrazně vyšší se říci nedá.

Naměřeno

Z výroby jsou na displeji nastaveny živé barvy s širokým gamutem a studenou bílou. Po přepnutí do módu přirozených barev je výsledek mnohem lepší a přesnost barev lze mírnou ruční kalibrací doladit k dokonalosti. Displej dokáže při zobrazení bílé na třetině obrazovky zářit až 545 nity (bodově až dvakrát tolik) a díky AMOLEDu má dokonalý kontrast. Jas sekundárního displeje ale nemá vlastní senzor a regulovat jej lze jen ručně.

V těle telefonu je menší akumulátor s kapacitou 3300 mAh a výdrž je na dnešní poměry také spíše slabší. Akumulátor je složen ze dvou v každé polovině telefonu, ale nabíjení neprobíhá paralelně. 15W nabíjení je dnes vcelku pomalé, silnější by ale telefon ještě více zahřívalo.

naměřeno
rozsah jasu 1,8–545 cd/m² (200 při 50 %)
PCMark (Work) 14 035 bodů
PCMark (Battery 2) 6:41 h
výdrž při přehrávání videa 1080p HEVC 14:00 h
nabíječka není v balení
úroveň nabití za 30 minut (%) 44 %

Při průměrné zátěži benchmarkem PCMark jsem naměřil 6 hodin a 40 minut, v běžném provozu jde o klasický jeden den. Rychlost nabíjení nabíječkou od Samsungu je 44 % za půl hodiny. Telefon lze nabíjet i bezdrátově výkonem 10 W.

Fotoaparát a video

Flip3 je sice dražší smartphone, ale není to žádný velký fotomobil. Na perfektní fotky tu má Samsung jiné modely, přesto je výsledek nakonec poměrně dobrý. Sestava čoček je podobná té z generace Galaxy S21, chybí však teleobjektiv. Díky konstrukci lze fotit i tak, že telefon s polootevřeným displejem využijete jako stativ.

Na zadní straně jsou jen dvě čočky: hlavní 12 Mpx snímač a ultraširokoúhlá kamera taktéž s rozlišením 12 Mpx. Přední kamerka ve výřezu displeje má 10 Mpx, ale pro selfie lze v zavřeném stavu používat i hlavní čočku.

širokoúhlé foto
širokoúhlé foto
selfie
selfie
noční snímek
noční snímek

Video:

 

 

 

Hodnocení

Zatímco Fold3 je větší a výrazně dražší, Flip může provedením i cenou oslovit více uživatelů. Provedení telefonu je luxusní a Samsung použil jen kvalitní materiály. Pokud dnes hledáte šikovné véčko, Flip3 může být velmi dobrou volbou.

Cyber25

Samsung Galaxy Z Flip3 recenze3A jaké jsou výhody této skládačky? V první řadě máte stylové véčko a tento způsob otevírání je prostě už od devadesátek ikonický. Telefon se dá ve složeném stavu mnohem lépe přenášet, vejde se lépe do kapsy (i když je pak trochu tlustší) a i složený se dá omezeně používat. Telefon také můžete nechat neustále otevřený. Sám jsem jej zaklapával jen asi v polovině případů.

Wow efekt při otevírání displeje brzy vyprchá. Skládací displej je hlavně o tom, mít kompaktní zařízení když jej nepoužíváte a opravdu velký displej když jej používáte. A složený Flip je opravdu malý. Kdyby byl lehčí, dal by se pohodlně nosit v kapse u košile.

Autor článku

Redaktor portálu Cnews.cz. Zaměřuje se na televizní témata, technologické zpravodajství, mobilní operátory a vědu. Příznivec kompaktních smartphonů. 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'; } }
'; 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 »