Recenze Huawei Nova 9: S pořádnou selfie a bez 5G zacíleno na mladé

21. 10. 2021

Sdílet

 Autor: Radomír Kejduš / Cnews.cz
Dnešní vídeňská premiéra nového smartphonu cílí na střední třídu. Huawei totiž letos v Evropě nepředstavilo žádný top model a místo P50 Pro u nás začne prodávat novou generace telefonu Nova. Ten má být zaměřen na mladou „tiktokovou“ generaci a být pro ně flagshipem ve střední třídě.

Do strategie firmy nikdo příliš nevidí, ale pravděpodobně nyní Huawei nevidí smysl v prodeji P50 Pro v našem regionu. Když Huawei poprvé před pěti lety vydal smartphone označený jako Nova, byl to neoficiálně telefon zaměřený designem na ženy. Byl velký 5" (IPS), poháněl jej Snapdragon 625, stále deset tisíc a šlo o jeden z mála telefonů s USB-C.

Nejnovější Nova 9 (Huawei píše oficiálně nova s malým n) je na dnešní poměry také vcelku malý, byť už jde o 6,57" AMOLED. Kompaktní smartphony Huawei již dávno nevyrábí, ale v rámci portfolia je Nova 9 příjemně malá, tenká a lehká. Na tloušťku má jen 7,7 mm (plus modul kamery). V prodeji budou dvě barvy, které se liší i materiálem. Stříbrnomodrá (Starry Blue) má velmi příjemný matný povrch, který je výborně odolný proti otiskům prstů, černá varianta je lesklá.

Huawei Nova 9 recenze10 Černá varianta. Na fotce to nevypadá, ale tahle je lesklá

Jakou barvu doporučíme je asi jasné, nicméně černá je i tak více konzervativní, neboť stříbrnomodrá má mírně extravagantní efekt s odlesky, jež mají evokovat hvězdnatý povrch. Huawei uvádí, že je nechytá otisky a neklouže v ruce. To první mohu potvrdit, to druhé moc ne. V zahraničí jsou v prodeji i zelená a růžová. Telefon nemá podporu 5G a zvládá nejvýše LTE, což je zapříčiněno sankcemi. Huawei použil Snapdragon 778G ve verzi 4G, čímž sankcím unikl, ale 5G mít zatím nemůže. Obdobný model od Honoru se stejným čipsetem již 5G má.

Displej má tenké rámečky a zakřivení po stranách. Čelní kamera si vyžádala díru uprostřed. Na spodní straně je nabíjecí port USB-C 2.0 a šuplík na dvě nanoSIM bez podpory paměťových karet. Ani NMCard. Byť přímo na šuplíku není vyznačen nápis SIM2, jde opravdu o Dual SIM. V balení dostanete 66W Supercharge nabíječku a silikonové pouzdro.

Zadní strana je u testované modrostříbrné varianty příjemně matná, byť duhové odlesky teček bych si osobně asi odpustil. Zajímavé je logo NOVA, které je graficky ztvárněno tak, že má představovat piktogram pro chlapce a dívku. Když vám to někdo řekne, možná to tam uvidíte.

Huawei Nova 9 recenze3 Odlesky mají evokovat hvězdnatý povrch

Modul fotoaparátu je výrazný a telefon se kvůli této kapličce na stole samozřejmě kolíbe. Ale to platí prakticky pro všechny dnešní telefony. Hlavní kamera má kolem čočky designový kruh. Další tři snímače jsou pak ve společném druhém kruhu. Jde o makro, hloubku ostrosti, ultraširokoúhlý snímač a blesk.

O výkon se stará Snapdragon 778G, který nemá podporu 5G a v telefonu není ani separátní čip. Absence 5G je vcelku výrazným mínusem, byť jeho rozšíření v Česku ještě nějakou dobu potrvá.

Pro čínský trh má tento telefon systém Harmony OS 2.0, ale u nás se bude prodávat s Androidem 11 a nadstavbou EMUI 12. Jedna ze zajímavých funkcí nového EMUI je například velká složka pro aplikace na ploše, ze které lze přímo aplikace přímo spouštět bez nutnosti nejdříve složku otevírat. Lze tím trochu ušetřit místo na ploše.

Huawei-Nova-9-recenze9-largePanel nástrojůPanel nástrojůAppGalleryAppGallery

Místo virtuálních ovládacích tlačítek v displeji vám nadstavba na začátku nabídne ovládání pomocí tří gest (ale můžete jej ihned změnit na tlačítka). Subjektivně jsem si na ně během testovacího týdne nezvykl a na konci se vrátil ke klasickému ovládání. Tohle mám ale stejné u všech značek, které se pokoušejí předělat ovládání a i u Samsungu si třeba vracím tlačítko Zpět na levou stranu.

V Česku bude v prodeji jediná paměťová varianta 128+8 GB, v zahraničí existuje i 256+8 GB. Akumulátor o velikosti 4300 mAh zajistí klasicky jednodenní výdrž, při nenáročném používání pak necelá dva dny.

Displej

Displej AMOLED o velikosti 6,57" má poměr stran 19,5:9 a rozlišení Full HD. Neměl by ale být úplně obyčejný – jeho obnovovací frekvence je totiž 120 Hz a přesnost barev slibuje pod 1 dE (tedy jako pro fotografy). Pro snadné přihlašování máte pod displejem klasickou optickou čtečku otisků.

Rozsah jasu jsem naměřil standardně dobrý: 1,2 až 414 nitů (při zobrazení bílé na čtvrtině displeje). V základu jsou barvy nastaveny v režimu Normální, který má barvy opravdu poměrně přesné; až na výraznější odchylku u tyrkysové. Teplota je ale stále posunuta trochu směrem ke studeným barvám.

Huawei Nova 9 displej Huawei Nova 9 displej
Huawei Nova 9 displej zkalibrovaný Huawei Nova 9 displej zkalibrovaný

Barvy lze mírně kalibrovat, čímž normální režim vylepšíte a přesnost je potom o kus lepší. Jelikož jde o AMOLED, ani tím nepřijdete o kontrast. Tímto jsem se zabýval hlavně kvůli tvrzení Huawei o přesném displeji, čehož drobným posunem barev docílit lze. Přepnutím do režimu Živých barev pak získáte klasické přesaturované barvy, ale někomu se to líbí.

Výkon a výdrž

S průměrným akumulátorem se žádné překvapení nečekalo, přesto je výdrž lepší než jsem čekal. Pracovní zátěž zvládne téměř deset hodin a přehrávat video skoro celý den, což je na 4300 mAh docela dobré.

Huawei Nova 9 recenze6 Huawei Nova 9 a dodávaná nabíječka

Huawei inzeroval plné nabití za 38 minut, což tak úplně neplatí. Za půl hodiny v nabíječce se s originálním adaptérem dostanete na 67 %, což se ale dá označit a rychlé. Pokud budete mít po ruce jinou nabíječku (slabší nebo od jiného výrobce), tak jste a půl hodiny na 35 %.

V AppGallery nejsou některé aplikace pro měření výkonu, ale PCMark ano. Benchmark v něm ukáže na 9696 bodů.

Kamera

Hlavní kamera má 50 Mpx a využívá barevnou masky RYYB, kde zelené filtry nahrazují žluté pro získání více světla. Ze čtyř sousedních pixelů se skládá jeden výsledný, ale lze zvolit i režim fotografie s plným rozlišením, kdy při dostatku světla můžete u nepohybujících se scén získat lepší výsledek. Tento režim pracuje s delší expozicí, ale není nutné použít stativ.

Huawei Nova 9 recenze4Kamera nemá optickou stabilizaci, ale využívá tzv. AIS, tedy stabilizaci pomocí umělé inteligence. Přední selfie kamera má 32 Mpx, což je dokládá zaměření telefonu na mladší uživatele. Navíc stejně jako zadní umí natáčet ve 4K. Když jsme u videa, tak telefon zvládá nahrávání přední i zadní současně na jeden záběr (střídáním) a umí i oba obrazy dostat do jednoho videa jako PIP.

Huawei Nova 9 kamera kamera

Digitální zoom se má aretační bod na 2×,což je úplně jedno, neboť tento mobil nemá teleskopickou čočku a vše je digitální. Kvalitě fotografií dopomáhá samostatný snímač měření hloubky ostrosti. Pokud by se vám nelíbilo vylepšování fotografií, tak režim AI lze snadno vypnout či zapnout přímo z hlavní nabídky.

Fotogalerie:

Huawei-Nova-9-fotogalerie9-largeHuawei-Nova-9-fotogalerie8-large
Huawei-Nova-9-fotogalerie7-largeHuawei-Nova-9-fotogalerie6-large
Huawei-Nova-9-fotogalerie5-largeselfieselfie
50 Mpx snímek50 Mpx snímeknoční režimnoční režim

Parametry

model Huawei Nova 9
displej 6,57" (19,5:9) AMOLED, 1080 × 2340 px, 120 Hz
skutečná velikost telefonu 6,98"
rozměry 160 × 73,7 × 7,8 mm
hmotnost 175 g
zvýšená odolnost
Hardware
SoC Snapdragon 778G 4G (6 nm)
paměť 8+128 GB
akumulátor 4300 mAh
Fotoaparát
hlavní kamera 50 Mpx, 4K
ultraširokoúhlá kamera 8 Mpx
teleobjektiv
další kamery 2 Mpx makro a 2 Mpx hloubka
přední foťák 32 Mpx 4K
Výbava
konektory USB-C 2.0
mobilní data 4G
SIM 2× nanoSIM
Wi-Fi Wi-Fi 6 (802.11ax)
Bluetooth Bluetooth 5.2
NFC NFC
biometrika čtečka otisků pod displejem
nabíječka 66 W, Supercharge
bezdrátové nabíjení
Dostupnost
představení září 2021
zahájení prodeje v Česku říjen 2021
barevné varianty Black, Starry Blue
doporučená cena při uvedení 12 999 Kč

Hodnocení

Huawei se snaží tento telefon představit jako svého druhu flagship, což je logické. Top model k nám letos asi nepřiveze a pro cílovku Novy 9 může jít skutečně o něco zcela dostatečného. Není to jen díky 32Mpx selfie kameře, ale i propracovanějšímu nahrávání videa.

Doporučená cena 12 999 Kč není úplně nízká, navíc telefon nemá 5G. I když ještě pár let to u nás možná ničemu vadit nebude. Zároveň u nás prodává jen dvě barvy ze čtyř a pouze nižší paměťovou konfiguraci. U výběru barev potom pozor na to, že to není jen o odstínu a mají i různý povrch.

Huawei Nova 9 recenze1 Huawei Nova 9

Stejně tak by se mohlo zdát, že nás výrobce ochudil o model Nova 9 Pro. Když si ale prohlédnete jeho parametry, neliší se prakticky v ničem. Tedy kromě toho, že je výrazně větší a má slabší akumulátor. Model Pro se měl spíše jmenovat Plus a jeho absence nikomu vadit nebude. Vlastně jednu výhodu má – jeho selfie kamera má i ultraširokoúhlou čočku.

Stále je nutné mít na paměti, že jde o telefon bez služeb Googlu. Aplikace do něj získáváte přes vlastní obchod AppGallery, případě Petal Search a některé zkrátka pořád chybí. Naposledy jsme to zjišťovali u bankovních aplikací a bankovnictví pro AppGallery nabízí aktuálně polovina ústavů.

CIF25

U Huawei jsme byli v minulých letech zvyklí hlavně na top modely, které soupeřily s těmi nejlepšími od Samsungu i Applu. Letos je to tedy Nova 9, kterou si vzhledem k ceně možná koupí více zákazníků. Jinak průměrný telefon vylepšuje 120Hz displejem, vzhledem k tenkému tělu slušnou výdrží, rychlým nabíjením i docela kvalitní fotoaparátem.

obrázky v článku: zdroj Cnews.cz

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 »