AMD uvádí mobilní Ryzeny 4000: „nejlepší procesor pro laptopy“, překvapení u GPU

7. 1. 2020

Sdílet

Ilustrační obrázek Autor: loriklaszlo – Depositphotos
Ilustrační obrázek

Minimálně pro fanoušky AMD byl asi včerejší večer na CES 2020 to nejzajímavější z celého veletrhu. Ale možná nejen pro ně, AMD včera odhalilo očekávaná 7nm APU Renoir, a to pro začátek v jejich mobilní podobě určené pro notebooky. A ta by zdá se mohla být hodně přínosná: přináší totiž spolu s novým výrobním procesem první 15W procesory s osmi jádry a díky tomu hodně velké navýšení výkonu v mainstreamových noteboocích. CEO firmy Lisa Su o mobilních Ryzenech 4000 sebevědomě tvrdí, že jsou to nejlepší procesory pro laptopy, jaké kdy byly vyvinuty, což je třeba brát s rezervou, ale pro oblast x86 PC procesorů by to skutečně mohl být zajímavý pokrok.

Ryzeny s jádry Zen 2 a 7nm technologií přicházejí do notebooků

Ryzeny 4000 pro notebooky přebírají architekturu Zen 2 (o jejích zlepšeních viz zde) a jsou vyráběné na 7nm procesu, tom samém, jako mají desktopové Ryzeny 3000 Matisse. Rozdíl je ale v tom, že Renoir již není čipletový design. Na CES 2020 byl ukázán vzorek procesoru v BGA pouzdře, takže víme, že jde o nový monolitický křemík a úplně celé APU je tedy 7nm. Stejný čip a pouzdro používá jednak 15W ULV verze Ryzen 4000U, ale zároveň i výkonný 45W verze Ryzen 4000H – obojí budou BGA procesory (pájené na desku) v pouzdru FP6. Tyto dvě řady budou konkurovat stejně značeným procesorům řad U a H od Intelu (ale ovšem také 10nm procesorům řady Ice Lake se značením Gx).

AMD Ryzen 4000 pro notebooky nalepkaAMD hned z kraje prezentace potvrdilo, že Renoir neboli mobilní Ryzeny 4000 mají osm jader Zen 2  a minimálně v některých konfiguracích i SMT, tedy 16 vláken. V nabídce budou modely se čtyřmi a šesti jádry bez SMT, šestijádro s SMT (12 vlákny) a osmijádra s a bez SMT. Poněkud se tedy rozmohla tzv. segmentace, která se často stran vypínání HT kritizovala u Intelu.

GPU s jen 512 shadery…?

Co je překvapení (či možná i zklamání), je konfigurace integrovaného GPU. Už před odhalením existovaly indicie o tom, že by GPU mohlo mít méně stream procesorů, než co již bylo v 14nm APU Raven Ridge (11 CU, 704 shaderů). Moc se tomu nechtělo věřit, ale toto se teď naplňuje. AMD u APU Renoir ubralo CU (nebo grafická jádra, jak se jim teď říká) a v procesoru je jich fyzicky jenom osm. Většina modelů je však navíc ořezaná, takže nejčastěji obsahují jejich GPU 5 až 7 CU, čili 320, 384 nebo 448 stream procesorů.

Toto vzbuzuje otázky, zda snad firma rezignovala na snahu zvýšit grafický výkon. Ale v prezentaci AMD tvrdí, že výkon je přes redukci z 11 na 8 CU vyšší než předtím. Architektura je stále použitá Vega, ale údajně optimalizovaná a na 7nm procesu se shadery daří taktovat na velmi vysoké frekvence – jeden z modelů má maximální takt GPU až 1750 MHz. Toto, ale možná i další zlepšení údajně zvýšila výkon jedné jednotky CU až o 59 %.

AMD Ryzen 4000 pro notebooky slajdy CES 02 AMD Ryzen 7 4800U proti Intel Core i7-1065G7 v Cinebench a 3D Marku Time Spy (Ice Lake)

V prezentaci AMD uvedlo, že integrovaný Radeon v mobilním APU Ryzen 7 4800U, což je nejvýkonnější 15W model (s 512 shadery na 1750 MHz), údajně o porazí GPU Intelu Core i7-1065G7 (10nm Ice Lake) o 28 %, měřeno v 3DMarku Time Spy; v 3DMarku 11 už ale jen o 18 %. AMD myslím nesdělilo, o kolik má toto GPU být rychlejší proti integrovanému Radeonu Vega 10 či 11 v APU Raven Ridge či ideálně poslední 12nm generaci Picasso. Výkon GPU bude tedy asi ostře sledován v recenzích a uvidíme, zda nebude trošku zklamáním.

AMD Ryzen 4000 pro notebooky slajdy CES 04 Grfika Ryzenu 7 4800U proti Intel Core i7-1065G7 (Ice Lake) ve hrách. Jde ovšem o oficiální benchmarky, které je třeba brát s rezervou

Snaha zmenšit čip kvůli ceně?

Toto opižlání grafických jader bylo možná vynuceno potřebou zmenšit celý čip, jelikož 7nm proces je drahá technologie. APU Ryzen jsou totiž kompletní SoC s funkcionalitou čipové sady integrovanou přímo v hlavním křemíku. AMD zde nemůže šetřit jako u čipletového Matisse tím, že tyto bloky vystrčí do 12nm IO čipletu – nebo jako Intel, který má externí čipset u mobilních procesorů napojený na pouzdru. Podle odhadu Iana Cutresse z AnandTechu by plocha čipu měla být asi jako velikost dvou CPU čipletů z Matisse/Epycu Rome. To by znamenalo plochu asi 150 mm², zatímco předchozí APU na 14nm mělo 210 mm².

Zen 2 s jen 4MB L3 cache bez PCIe 4.0

Snaha omezit plochu je možná i za jednou další věcí, která možná někoho zklame. Jádra Zen 2 v čipu Renoir mají jen 4MB L3 cache na jeden blok CCX (tj. u osmijádra 2×4 MB L3). Proti 16MB „Game Cache“ v čipu Matisse je to jen čtvrtina. Původně se asi dalo doufat, že by desktopová verze těchto APU mohla být dobré CPU pro hry, protože monolitický čip by mohl mít lepší latence paměti RAM než Matisse. Ovšem malá L3 cache tento potenciál asi může zase pokazit. Mimochodem, další kompromis proti desktopové verzi Zenu 2 je v konektivitě. Renoir neumí na rozdíl od Matisse PCI Express 4.0 – nebo alespoň ne v mobilní verzi. Ryzeny 4000H i 4000U budou podporovat stále jenom PCIe 3.0. Další informace o konektivitě (například jaká rozlišení umí integrované GPU) ale zatím nemáme.

AMD Ryzen 4000 pro notebooky BGA pouzdro AMD Ryzen 4000 pro notebooky, BGA pouzdro FP6

Zlepšení spotřeby a výdrže na baterii

Pro výkon integrované grafiky bude hodně důležité, zda řadič pamětí bude umět vyšší frekvence. Mobilní Ryzeny 4000 v 15W verzi budou nyní umět oficiálně DDR-3200 (u generace 2000/3000 byla podporována jen DDR4-2400) a LPDDR4X na 4266 MHz. U 45W modelů je specifikace úplně stejná, nepodporují tedy rychlejší DDR4 než na 3200 MHz. LPDDR4x umožní snížit klidovou spotřebu a výdrž na baterie v luxusnějších noteboocích. Všechny modely podporují až 64 GB RAM.

Nejen paměti LPDDR4x by měly vylepšovat energetickou efektivitu a výdrž na akumulátor. Velkou roli zde mají hrát architektonická zlepšení. SoC umí v klidu vypnout více různých svých bloků než předchozí generace. Dále byla ušetřena energie díky tomu, že v tomto APU není již takt interní propojovací logiky Infinity Fabric pevně navázán na frekvenci pamětí. Renoir také umí mnohem svižněji vstupovat a vystupovat do a z úsporných stavů – latence přechodu je zredukována až o 80 %. To umožňuje agresivnější použití těchto spánkových režimů. V předchozích APU totiž musely tyto stavy být používány opatrněji či některé bloky nemohly být uspávány, aby neutrpěla responzivnost systému.

Podle AMD má spotřeba SoC Renoir být snížena až o 20 %, což by mělo přímo zlepšit výdrž na baterie podobně jako použití LPDDR4X. Také CPU jádra jsou při práci efektivnější (proto jich také může být tolik). AMD uvádí, že u Renoiru je jejch poměr spotřeby a výkonu 2× příznivější než u předchozích generací. Přičemž asi 70 % tohoto zisku dělá 7nm proces sám od sebe a 30 % je dosaženo lepší efektivitou architektury Zen 2 samé, ve srovnání se Zenem 1/1+.

Článek pokračuje na další straně.

Galerie: Odhalení procesorů AMD Ryzen 4000 pro notebooky

Modely: dva 45W, pět 15W Renoirů

Zatím jsme kličkovali kolem parametrů konkrétních modelů, k nim tedy teď. AMD sice ještě neodtajnilo úplně všechny informace, ale frekvence a hlavní věci sdělilo. Soupisku modelů můžete vidět zde v oficiální tabulce.

Ryzeny 4000U pro mainstreamové notebooky budou začínat levnějším modelem Ryzen 3 4300U se čtyřmi jádry a jen čtyřmi vlákny. Jeho základní frekvence je 2,7 GHz a maximální boost 3,7 GHz. L3 cache bude jen 4MB, takže tento model má asi jen jeden CCX. Grafika bude obsahovat 5 jader/CU (takže 320 shaderů) ty ale poběží na 1400 MHz. Nad tím budou šestijádra Ryzen 5 4500U4600U – oboje má maximální takt boostu 4,0 GHz a grafiku s 384 shadery (6 CU) na frekvenci 1500 MHz. Rozdíl je v tom, že nižší model je bez SMT s takty 2,3–4,0 GHz a druhý má SMT (12 vláken) a takty 2,1–4,0 GHz.

Nejzajímavější budou přirozeně dva nejdražší procesory Ryzen 7 s osmi jádry. Nejlepší bude Ryzen 7 4800U s 16 vlákny (SMT aktivní), ten má základní frekvenci 1,8 GHz a maximální boost až 4,2 GHz. Integrovaná grafika ponese plný počet 512 stream procesorů (8 CU) s frekvencí až 1750 MHz. Levnější varianta Ryzen 7 4700U (která už unikla minulý měsíc) má bohužel vypnuté SMT a jen osm vláken. Frekvence bude 2,0–4,1 GHz a trošku bude odrbnutá i integrovaná grafika – ponese jen 7 CU (448 shaderů) s taktem až 1600 MHz.

Všechny tyto modely mají 15W TDP. To je volitelně možné nastavit na 25 W, pokud výrobce notebooku chce – tím se vylepší stabilně dosažitelný výkon, krátkodobé turbo bude mít výkon stejný. TDP lze jinak i snížit na 12 W (podle některých zdrojů 10 W), tam se zase výkon/frekvence logicky sníží.

Výkonné modely: 45 W, exkluzivně 35W verze

45W modelů je v nabídce méně, v tabulce od AMD jsou jen dva. Ryzen 5 4600H nabídne šest jader a 12 vláken na taktu 3,0–4,0 GHz. Jeho GPU má jen 384 stream procesorů (6 CU) a takt 1500 MHz. Nad tím pak je Ryzen 7 4800H s osmi jádry a 16 vlákny. Jeho frekvence budou 2,9 GHz v základu a 4,2 GHz v boostu. Integrovaná grafika má jen 448 shaderů (7 CU) a takt 1600 MHz. Bude mít tedy asi nižší výkon než u 15W modelu. To je asi proto, že u procesorů řady H se počítá s tím, že uživatelé vyhledávající vysoký výkon grafiky budou mít přídavné GPU. Integrovaný Radeon tedy bude mít spíše roli úsporného GPU pro přepínání v klidu či nenáročné práci.

Oba modely mají stejné 45W TDP, ale v boostu může spotřeba dynamicky jít až na 54 W. V praxi můžete ale potkat ještě Ryzen 7 4800HS. To je exkluzivní model, který bude mít Asus v notebooku ROG Zephyrus G14. Jeho parametry jsou stejné jako u modelu 4800H, ale používá speciální výběrové čipy s nižším napětím či úniky proudu, díky kterým má podávat stejný výkon jako 45W model, ale s TDP jen 35 W. V parametrech zmíněného notebooku byl jinak nalezen také „Renoir 4900HS“, což může znamenat, že AMD si ještě schovává mobilní Ryzen 9 4900H s vyšším výkonem. Možná jako trumf, až Intel odhalí vlastní nové procesory Core i9 10. generace (Comet Lake-H) pro notebooky.

Specifikace Ryzenu 4000 pro notebooky Specifikace Ryzenů 4000 pro notebooky (oba Athlony 3000 jsou stále 14nm APU)

AMD SmartShift

Ryzenů 4000H se bude týkat ještě jedna technologická novinka, kterou AMD na CES 2020 prozradilo. Technologie SmartShift má umožňovat v noteboocích s Ryzenem 4000H sladit řízení spotřeby procesoru s řízením spotřeby přídavného GPU – tedy alespoň grafiky Radeon. Jde vlastně o obdobu sdílení a přerozdělování TDP v čipech APU s integrovanou grafikou. V těch je možné přidělit větší nebo menší díl spotřeby jádrům CPU nebo GPU podle toho, co je pro danou aplikaci nebo hru třeba. V notebooku může být chlazení prakticky sdílený zdroj, takže dává smysl takovéto přesouvání tepelného rozpočtu mezi procesorem a samostatnou grafikou také využít.

Podle AMD to umožňuje efektivnější využití energie, což přináší zlepšení výkonu téměř „zadarmo“. Technologie SmartShift je zatím pořád ve vývoji, ale i nefinální sestavení tohoto softwaru (patrně pracujícího přes ovladače nebo snad firmware) má prý zvyšovat výkon ve hře Divison 2 o 10 % a v benchmarku Cinebench o 12 %.

Jak dobrá bude finální verze, na to si asi bude třeba počkat na chvíli, kdy vyjdou notebooky, v nichž bude SmartShift implementovaný. Je možné, že tato funkce bude potřebovat ladění specifická pro každý konkrétní typ notebooku, takže nebude dostupná na všech noteboocích s Ryzenem 4000H a grafikou Radeon. Bylo ale přislíbeno, že se má objevit v minimálně jednom modelu, plánovaném na druhou čtvrtinu letoška: tím je Dell G5 SE s Ryzeny 4000H a grafikou Radeon RX 5600M.

První notebooky s Ryzeny 4000 mají přijít do třech měsíců

V obchodech se mají první notebooky s těmito procesory začít objevovat ještě během první čtvrtiny tohoto roku (pravděpodobně během března). Další mají asi vycházet v dubnu či květnu a do konce Q2 by jich snad mohlo být větší množství.

AMD si od Renoiru slibuje větší úspěch svých procesorů v mobilní sféře, kde zatím má menší tržní podíly než v desktopu. Letos totiž prý má vyjít přes 100 různých typů, v nichž bude nějaký mobilní Ryzen 4000, což by asi pro AMD bylo rekordně vřelé přijetí.

Jaký bude reálně úspěch, v tuto chvíli ale není lehké předpovídat. Intel má v notebookovém segmentu velkou setrvačnost a dlouhodobé smlouvy, navíc může mít i výhodu levnější výroby díky vlastním továrnám a masovému měřítku. Teprve také uvidíme, jak dopadnou Ryzeny 4000 v reálných recenzích a jak dobře optimalizované budou notebooky s nimi. Toto je oblast, kde poskytuje Intel výrobcům hodně dobré služby, což se pak projevuje například ve velmi dobré výdrži na baterii u lepších notebooků. Jak dobře se bude AMD dařit tomuto konkurovat a zda dokáže získat na svou stranu masového zákazníka, to se teprve ukáže.

Zdroje: AMD, AnandTech

Galerie: Odhalení procesorů AMD Ryzen 4000 pro notebooky
'; 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 »