Recenze Huawei MateBook 14s: skvělý displej, dlouhá výdrž a webkamera je zpět na správném místě

7. 12. 2021

Sdílet

 Autor: Cnews.cz
MateBooky jsou si všechny hodně podobné a tento je vylepšení staršího modelu 14. Model 14s nabídne procesor Intel generace Tiger Lake, výrazně lepší displej, výbornou nabíječku a opět normální webkameru. Kvalitní kovové zpracování, poměr stran 3:2 a podobnost s MacBooky zůstávají.

Nový MateBook má na první pohled velmi zajímavý odstín. Něco mezi stříbrnou a modrozelenou nazývá výrobce Spruce Green (smrková zeleň) a prodává ještě klasickou šedou variantu. Povrch je příjemně matný a neulpívají na něm otisky. V krabici dostanete kompaktní nabíječku s USB-C kabelem. Huawei prodává MateBook 14s za doporučenou cenu od 30 999 Kč podle konfigurace.

Víko displeje otevřete velmi pohodlně jednou rukou, jde to do poměrně velkého úhlu 150°. Zpracování těla díky kovu působí prémiově, provedení klávesnice ale spíše standardním dojmem. Na první pohled potěší samostatné zapínací tlačítko, ve kterém je (stejně jako v minulých modelech) integrovaná čtečka otisků pro Windows Hello.

Webová kamera je konečně na svém standardním místě nad displejem a ani kvůli tomu nebylo třeba výrazně zvětšovat rámeček. V minulých generacích mívaly MateBooky webkameru mezi tlačítky F6 a F7. Huawei zachoval stejný layout, jen vyklápěcí tlačítko vyměnil za běžné. Jeho funkcí je nyní spuštění diktování textu (od Microsoftu), což v českém prostředí zatím nefunguje. Tahle funkce jde zaměnit za jinou, musíte ovšem využít nějakou další aplikaci, například Powertoys. Ve výsledku získáte programovatelné tlačítko navíc a je škoda, že to Huawei nenabídne přímo ve svém nastavení.

Tohle tlačítko se už nevyklopí
Tohle tlačítko se už nevyklopí
ale spustí diktování textu.
ale spustí diktování textu.

Huawei upustil od tohoto experimentu, který byl sice velmi zajímavý, ale nakonec spíše nepraktický. Kamera zabírala totiž zejména vnitřek nosu. Na druhou stranu tlačítko fungovalo i jako fyzická krytka kamery. Místo toho se nyní při aktivaci kamery rozsvítí bílá dioda. Její rozlišení je standardních 720p a při horším osvětlení v místnosti má obraz výraznější zrno. Vedle kamery jsou ještě tři neznatelná čidla. Jedno pro měření okolního jasu, další dvě pro infračervené rozpoznávání obličeje přes Windows Hello.

Huawei MateBook 14s recenze7 Webkamera, senzor jasu a IR kamery

Klávesnice

Klávesnice testovaného modelu je typu ANSI a bez české diakritiky. A právě tato má být v prodeji i na našem trhu. Existuje ještě varianta s klávesnicí ISO, ovšem také bez diakritiky. Zájemci o evropské rozložení (ISO) si tak mohou směle objednat MateBook třeba z Německa.

ANSI (prodávané v Česku)
ANSI (prodávané v Česku)
ISO
ISO

Klávesnice má nízký zdvih (1,5 mm) a píše se na ní dobře. Podle Huawei je proti starým modelům přepracovaná, na pohled ale vypadá stejně. Je o něco tišší. Všechna tlačítka jsou v jednom bloku včetně kurzorových šipek, což ergonomii moc nepomáhá. Oddělené zapínací tlačítko je však super.

Zapínací tlačítko s integrovanou čtečkou otisků
Zapínací tlačítko s integrovanou čtečkou otisků
Neergonomické šipky
Neergonomické šipky

Horní řada slouží primárně pro přídavné funkce a se současným stiskem Fn pak fungují klasické F-klávesy. Pokud Fn stisknete samostatně, dojde k jeho aretaci a rozsvítí se na něm dioda. V tomto druhém režimu už ale podržení a opačný režim nefunguje, což mi přijde jako chyba v návrhu.

Potěšilo mě naopak, že zkratka alt+F4 funguje v obou módech, většina značek notebooků toto neumí. Bílé podsvícení kláves má dvě úrovně a po nějaké době pohasne. V nastavení lze aktivovat jeho trvalé svícení, vliv podsvícení na celkovou výdrž je velmi malý.

Vedle Touchpadu je umístěn čip NFC pro spárování se smartphonem značek Huawei či Honor. Ke klávesnici bych měl mnoho ergonomických výhrad, ovšem velký touchpad s hladkým povrch je naopak velmi příjemný.

Displej

14,2" displej má poměr stran 3:2 a vysoké rozlišení 2520 × 1680 px. Je lesklý a dotykový, výrobce ovšem zůstává neznámý. Jako vendor je uveden kód TL142GDXP02-0 a z tohoto kódu jsme jej nezjistili. Jde o typ LPTS s obnovovací frekvencí 90 Hz, která je adaptivní. Vyšší frekvenci aktivujete klávesovou zkratkou Fn+R, což už vliv na výdrž má. Zaznamenal jsem asi o 1,5 hodiny kratší.

Huawei MateBook 14s recenze5 Maximální úhel otevření

Rozsah jasu je výborných 5 až 445 nitů při vysokém kontrastu okolo 1500:1. Jas se umí díky senzoru přizpůsobit okolnímu osvětlení. Vyvážení bílé i přesnost barev jsou na vysoké úrovni a homogenita směrem ke krajům klesá velmi málo. Displej můžu jen chválit.

Huawei MateBook 14s displej Displej

Huawei slibuje i vylepšený zvuk. Tiger Lake má funkce pro odfiltrování hluku pomocí AI a čtyři vestavěné reproduktory hrají nadprůměrně dobře.

Výbava, výkon, výdrž

Notebook pohání 11. generace procesoru od Intelu s TDP 35 W a grafikou Iris Xe. K tomu dostanete 16 GB operační paměti a 512GB SSD. Disk je od výrobce rozdělený na dva oddíly, 120 GB pro systém a 337 GB pro data. Osobně mám toto rozdělení v případě jediného disku rád a přispívá k pořádku v datech. Výrobcem disku je Samsung, ale zahraniční recenze hlásí i použití SSD od jiných značek.

Huawei MateBook 14s CrystalDiskMark 20211112211300 peak Výkon SSD
Výkon (zásuvka/akumulátor)
PCMark 10 5005 / 3840 bodů
Cinebench R23 6001 / 5485 bodů
3DMark (Time Spy) 1582 / 1548 bodů

Paměti jsou však trošku přiškrcené a taktéž disk umí pouze PCIe 3.0 (ač čipset zvládne PCIe 4.0). Nejen díky tomu je ale notebook velmi tichý a příliš se nezahřívá. Režim vyššího výkonu se zde zapíná zkratkou Fn + P.

Huawei MateBook 14s hwinfo1Akumulátor má kapacitu 60 Wh a velmi dobrou výdrž. Při práci i při přehrávání videa vydrží shodně 10 hodin a za půl hodiny v nabíječce se dostanete na 51 %. Nabíjení funguje i slabším adaptérem pro mobily, jen výrazně pomaleji. Se zapnutou vyšší frekvencí displeje se výdrž zkrátí asi na 9 hodin. V kategorii výdrž a nabíjení patří MateBook 14s ke špičce.

Výdrž
kapacita akumulátoru 60 Wh
PCMark 10 (Modern Office) 10:04 h
přehrávání Full HD videa 10:10 h
PCMark 10 (Gaming) 1:52 h
rychlost nabití za 30 minut 51 %
rychlost nabití za 60 minut 90 %
Huawei MateBook 14s pcm6 Režimy akumulátoru

Portová výbava zahrnuje dvojici USB-C, HDMI a USB-A. Bezdrátové sítě jsou standardu Wi-Fi 6 a Bluetooth 5.2 (byť Huawei uvádí jen 5.1). V nejvyšší konfiguraci s Intel Core i7 je jedno USB-C nahrazeno Thunderboltem 4. Je trochu škoda, že užitečný Thunderbolt v nižších verzích chybí.

USB-A
USB-A
HDMI, 2× USB-C (v nejvyšší konfiguraci je tu i Thunderbolt)
HDMI, 2× USB-C (v nejvyšší konfiguraci je tu i Thunderbolt)

Rozborka

Ač má spodní kryt přístupné šroubky, nepodařilo se mi tentokrát s obyčejnými plastovými „páčidly“ kryt sundat. S lepšími nástroji by to šlo, ale kryt tentokrát drží velmi pevně, a pokud už hrozí, že bych jej poškodil, dál se o to nepokouším. Pod krytem byste měli už snadný přístup k SSD, paměti jsou na desce napájené. Uvnitř je dvouokruhové chlazení.

Huawei MateBook 14s recenze13 Tyhle nástroje pro tentokrát nestačily

Konfigurace

Dvě základní konfigurace se liší procesorem (i7-11370H a i5-11300H), operační pamětí (8/16 GB) a diskem (512 GB/1 TB). Vedle šedozelené existuje ještě standardní šedá (Space Gray). Ta nižší přijde na 30 999 Kč, silnější varianta pak na 33 999 Kč.

zabbix_tip

Hodnocení

MateBook 14s má tenké kovové tělo (zvláště barva Spruce Green je nádherná), je svižný a s dlouhou výdrží. Displej umí přesné barvy, má nadstandardní rozlišení i rychlost obnovování obrazu. Při tloušťce 17 milimetrů a hmotnosti 1,4 kg je i dostatečně kompaktní, přesto se nijak nepřehřívá. Thunderbolt dostanete jen s nejvyšší konfigurací a právě proto jen ta získala certifikaci Intel Evo.

Vedle skvělého displeje i dlouhé výdrže musím pochválit nabíjení. Je velmi rychlé a stačí jen kompaktní nabíječka s portem USB-C, kterou využijete i pro mobil. Klávesnici schází české znaky a není příliš ergonomická. Vedle čtečky otisků patří k nadstandardní výbavě také infračervené kamery. Potěší ale návrat webkamery nad displej při zachování tenkých rámečků. Tlačítko, které nahradilo webkameru, ale v Česku příliš nevyužijete.

model Huawei MateBook 14s HKD-W5651T
displej 14,2" (3:2) | LTPS | 2520 × 1680 px | (TL142GDXP02-0 lesklý dotykový, 90 Hz
procesor Intel Core i5-11300H (10nm, Tiger Lake) na 0,4–3,1 GHz (turbo 4,4 GHz), 4/8 jader, TDP 35 W
grafický čip Intel Iris Xe
operační paměť 16 GB Quad-Channel
disk 512 GB SSD NVMe PCIe4 (Samsung MZVLB512HBJQ)
klávesnice ANSI / alfanumerická, podsvícená, bez diakritiky
porty 2× USB-C 3.2 (nabíjení a DisplayPort), USB 3.2 Gen1, HDMI, jack (poznámka: v jedné konfiguraci též Thunderbolt)
sítě Wi-Fi 6 (802.11ax Intel AX201), Bluetooth (5.2), LAN (ne), LTE (ne)
biometrika/čtečka otisků čtečka otisku v zapínacím tlačítku
akumulátor 60 Wh
rozměry a hmotnost 313 × 229 × 16,7 mm / 1,43 kg
OS Windows 10 Home
záruka 2 roky
doporučená cena 30 999 Kč

Autor článku

Nadšenec do notebooků a příznivce kompaktních smartphonů. Najdete mě na Twitteru nebo LinkedInu.

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