AMD vydalo první mobilní Ryzeny 7000 – 6nm Zen 2 „Mendocino“ pro levné notebooky

21. 9. 2022

Sdílet

 Autor: AMD, via: ComputerBase
AMD má konečně něco „nového“ pro nejlevnější notebooky. Athlony a Ryzeny 7020 ale používají starou architekturu Zen 2. Naštěstí se to bude dát poznat z označení, když budete vědět, na které číslo koukat (sedmička na začátku to není).

Na začátku léta oznámilo AMD během Computexu, že vedle nových procesorů s architekturou Zen 4 chystá ještě levné úsporné procesory pro notebooky a chromebooky s kódovým označením Mendocino. Ty teď firma oficiálně představila (naschvál chvíli před odhalením nových GeForce) a paradoxně to vlastně budou první Ryzeny 7000 pro notebooky na trhu. Nicméně Mendocino používá starší architekturu Zen 2 a není zaměřené na výkon, ale na úspornost.

Procesor Mendocino je vyráběný na 6nm procesu a jde o dost malý čip s plochou jen 100 mm². Vyráběný je samozřejmě v pouzdru BGA pájeném na desku a zatím spíš očekáváme, že nebude mít desktopovou verzi pro socket AM5, jelikož konektivita je hodně osekaná. Nicméně asi by mohly vzniknout desktopové Mini-ITX desky a mini-PC s mobilní BGA verzí osazenou napevno.

Zen 2 a integrovaná grafika RDNA 2

SoC má nativně čtyři jádra Zen 2 s osmi vlákny a 4MB L3 cache (respektive by podle některých indicií mohlo jít o jejich kompaktní zjednodušenou verzi architektury, kterou používá například procesor PlayStation 5). Jejich takt bude v boostu dosahovat až hodnot okolo 4 GHz (nejrychlejší model bude mít boost 4,3 GHz), z čehož si lze udělat představu o tom, jaký bude dosahovaný jednovláknový výkon.

Tyto procesory jsou určené pro 15W TDP, ale některé notebooky je asi budou provozovat na nižších spotřebách, protože by TDP měla být konfigurovatelná v rozsahu 8–15 W. Jeden z hlavních důrazů při vývoji byla podle AMD výdrž na baterie. Notebooky mají s tímto SoC/APU dosahovat údajně výdrže až 12 hodin (přičemž se bavíme o levných modelech, takže je to asi s malým akumulátorem a nelze úplně porovnávat s výdrží u „prémiových“ modelů).

Mendocino má umožnit levným notebookům dosáhnout výdrže na baterii až 12 hodin Mendocino má umožnit levným notebookům dosáhnout výdrže na baterii až 12 hodin (zdroj: AMD, via: ComputerBase)

Integrovanou grafiku Mendocina zajišťuje malé jádro architektury RDNA 2, které má 2 CU, tedy 128 shaderů běžících na frekvenci 1900 MHz (jde asi o boost). Tato konfigurace a takt jsou stejné u všech modelů včetně nejlevnějších a má označení „Radeon 610M“. Vzhledem k nižší frekvenci by měla být o něco pomalejší než integrované GPU desktopových Ryzenů 7000 (to jede až na 2200 MHz).

SoC AMD Mendocino SoC AMD Mendocino (zdroj: AMD, via: ComputerBase)

Modely a nové značení: nejdůležitější je předposlední číslice

V noteboocích se Mendocino bude prodávat jako Ryzen řady 7020 a Athlon 7020 (respektive je možná lepší psát 7x20). Jde o nový systém značení, ve kterém budou tyto levné a architektonicky starší procesory bohužel smíchané s novými Zeny 4 (a dokonce i Zeny 3). To, že procesor patří do série 7000, už nebude znamenat nic jiného než to, že jde o produkt pro rok 2023. Ve značení bude patrné, jakou architekturu procesor má, ale musíte se dívat ne na první, ale na třetí číslici. Série „7020“ proto znamená, že jde o procesor s architekturou Zen 2. Mobilní procesory s architekturou Zen 4 budou Ryzen 7040.

V praxi druhá a případně čtvrtá číslice bude vyplněné různými vyššími či nižšími čísly podle toho, kam daný model Ryzenu nebo Athlonu zapadá v nabídce. Zde můžete tento systém značení vidět vysvětlený:

Nový systém značení mobilních procesorů AMD platný od roku 2023 2 Nový systém značení mobilních procesorů AMD platný od roku 2023 (zdroj: AMD)

Modely: Mendocino se vmísí i mezi Ryzeny 5

AMD bude celkově výrobcům notebooků nabízet čtyři modely, dva označené jako Athlon a dva jako Ryzen 3 a Ryzen 5 (ano, tento lowendový čip bude nominálně zasahovat až do třídy procesorů Ryzen 5, což bude pro kupující určitě matoucí).

Modely se neliší integrovanou grafikou ani konektivitou, ale zřejmě jen výkonem CPU části, všechny také mají zmíněné 15W TDP (s možností snížení na 8 W). Nejvýkonnější podobou Mendocina je Ryzen 5 7520U, jenž má čtyři jádra a osm vláken, se základním taktem 2,8 GHz. Jeho maximální boost je 4,3 GHz, což by teoreticky mohlo dávat jednojádrový výkon blížící se Ryzenu 5 3500X, jenž měl stejné maximum (a na 4,3 GHz boostoval také Ryzen 3 3300X). Jenže Mendocino má jen malou 4MB L3 cache, která asi může alespoň v některých úlohách výkon srážet.

Levnější alternativou bude Ryzen 3 7320U, který má pořád čtyři jádra a osm vláken, ale o kapku nižší takty – 2,4 GHz v základu a jeho maximální boost bude 4,1 GHz. Jednovláknový výkon by tedy mohl teoreticky být až nad Ryzenem 3 3100, ale opět je tu jen 4MB L3 cache.

Modely procesorů AMD Mendocino Modely procesorů AMD Mendocino (zdroj: AMD, via: ComputerBase)

Modely Athlon budou ořezány na jen dvě jádra. Athlon Gold 7220U má dvě jádra s SMT, takže čtyři vlákna, a frekvenci 2,4 GHz v základu a 3,7 GHz v maximálním boostu, se zachovanou plnou 4MB L3 cache.

Nejlevnější model Athlon Silver 7120U má takty 2,4–3,5 GHz, ale navíc mu byla ještě vypnuta SMT, takže už má se dvěma jádry pouhá dvě vlákna, a také zmenšena L3 cache na jen 2 MB.

AMD paradoxně teď bude používat značení používané Intelem poté, co ho ten zase po pár letech opustil. Ono rozlišení Silver / Gold odkoukané od Intelu totiž zřejmě zmizí s tím, jak zmizí procesory Pentium. Použití dříve prémiové značky Athlon pro levné procesory na straně AMD je obdobou toho, co Intel posledních 15 let dělal s Pentiem, uvidíme tedy, zda se AMD neinspiruje a taky značku Athlon neopustí. (Čistě emocionálně bych preferoval, kdyby ne.)

Více: Značky Pentium a Celeron končí? Levné procesory Intel se teď budou jmenovat… Intel Processor

Minimální potřebná konektivita

Všechny modely budou v noteboocích používat paměti LPDDR5-5500, přičemž šířka řadiče je 64 bitů, tedy poloviční proti desktopovým procesorům. Není ani zmíněna podpora desktopového typu pamětí DDR5, proto je nejisté, zda bude možné vyrobit verzi těchto CPU pro socket AM5. Mendocino také (alespoň v mobilní verzi) poskytuje jen čtyři linky PCIe 3.0. Obvykle asi bude v notebooku SSD s rozhraním PCIe 3.0 ×2 a jednu linku nebo dvě vezme bezdrátový adaptér.

Mendocino je SoC, který se v noteboocích bude používat bez čipsetu, všechna konektivita je tedy přímo ve 100mm² křemíku. Podporované jsou až čtyři obrazové výstupy DisplayPort 1.4a (volitelně přes USB-C) nebo HDMI 2.1. Maximální rozlišení ale nevíme. Je možný bezdrátový přenos obrazu přes Miracast.

SoC umožňuje vyvést z notebooku maximálně pět portů USB – jedno USB 3.2 Gen 2 (10 Gb/s), jedno USB 3.2 Gen 1 (5 Gb/s) a tři USB 2.0. Ovšem některá z těchto rozhraní v praxi mohou být sežrána bezdrátovým adaptérem Bluetooth, čtečkou karet a podobnými perifériemi. V čipu je zkráceně řečeno jen minimální konektivita potřebná pro notebooky a prakticky nic navíc (čtyři obrazové výstupy, které do toho úplně nezapadají, jsou nejspíš pro použití v embedded zařízeních).

Chystané notebooky s procesory AMD Mendocino Chystané notebooky s procesory AMD Mendocino (zdroj: AMD, via: ComputerBase)

Cílem procesorů Mendocino (Ryzen / Athlon 7020) budou chromebooky a levné notebooky. AMD uvádí cenové rozpětí 399 až 699 dolarů, ale postupem času se nejspíš budou prodávat i za nižší částky. Má jít například o modely řady Lenovo Ideapad 1, Acer Aspire 3, HP ale bude tyto procesory montovat i do zatím nespecifikovaného levnějšího notebooku s úhlopříčkou displeje 17 palců (pro ty, kdo chtějí velký displej na stolní práci, ale úsporné levné vnitřnosti). Časem se asi objeví i další zařízení – levné notebooky, které již byly prodávány s procesory AMD založenými ještě na architektuře Zen či Zen+ (Ryzeny 3 generace 3000, Athlony Gold/Silver), obvykle asi v dalších generacích přejdou na Mendocino.

Cyber25

Tyto notebooky by měly přicházet na trh během čtvrtého kvartálu letošního roku, Mendocina budou tedy opravdu napřed před výkonnějšími mobilními Ryzeny generace 7000. Ty budou mít označení 7040 v případě novinek s jádry Zen 4 (výkonné modely Dragon Range s až 16 jádry budou Ryzen 7045) a zřejmě také 7030, což budou modely vzniklé refreshem architektury Zen 3 z Ryzenů 6000 (Rembrandt) a 5000 (Barcelo, což je samo refresh Cezanne).

rhallock 1 1662482462284 Výkonnostní segmenty procesorů AMD pro notebooky (zdroj: AMD)

Zdroje: AMD (1, 2, 3, 4, 5, 6), ComputerBase

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