[AKTUALIZOVÁNO] Levná grafika nové generace od AMD je tady: Radeon RX 9060 XT oficiálně, už víme i ceny

Sdílet

Radeon RX 9060 XT Autor: AMD
Referenční návrh Radeonu RX 9060 XT. Běžně asi tento design nebude v prodeji
Grafika s čipem Navi 44 je pomyslnou polovinou Navi 48 z Radeonu RX 9070 XT. Jestli bude mít také polovinu jeho výkonu (a polovinu ceny), to teprve uvidíme. Karta ale překvapila rozhraním PCI Express…

Před necelými třemi měsíci AMD odhalilo grafiky Radeon RX 9070 a RX 9070 XT s novou architekturou RDNA 4. Asi se dá říct, že zatímco nová generace Nvidie možná přinesla o trochu menší zlepšení, než se čekalo, architektura RDNA 4 možná spíš byla podceněná a pak překvapila. Teprve teď se však uvidí, co přinese do segmentu levnějších grafik s čipem Navi 44 nyní vycházejícím v nové kartě Radeon RX 9060 XT.

Radeon RX 9060 XT je jedna z novinek, kterou AMD odhalilo na Computexu 2025. Firma tuto kartu avizovala už po odhalení Radeonu RX 9070 a 9070 XT v únoru a o existenci druhého GPU generace RDNA 4 se už vědělo předem z neoficiálních úniků, podle nichž mělo jít takřka přesnou polovinu čipu Navi 48 (které v plné konfiguraci reprezentuje Radeon RX 9070 XT). Teď máme konečně specifikace, které to víceméně potvrzují – ale jsou tu i překvapení.

Navi 44 obsahuje 29,7 miliardy tranzistorů v ploše údajně 199 mm² proti 53,9 miliardám (na 356,5 mm²) v Navi 48.

Navi 44

Radeon RX 9060 XT obsahuje GPU Navi 44 v plné výbavě, což znamená 32 jednotek CU architektury RDNA 4 – 2048 shaderů, 32 Ray Acceleratorů a 64 AI Acceleratorů. GPU má stanovenou boostovou frekvenci 3,13 GHz, což platí pro referenční parametry (aktualizováno: tzv. game clock je uváděná 2,53 GHz). Nereferenční „OC“ karty (tedy s rovnou z továrny aplikovaným přetaktováním) budou mít taky vyšší. GPU obsahuje dle očekávání 32 MB Infinity Cache.

GPU Navi 44, ilustrace

GPU Navi 44, ilustrace

Autor: AMD

Při uvedeném taktu boostu má grafika dosahovat výkonu 821 TOPS při akceleraci AI, což je mimochodem víc než u RTX 5060 Ti (759 TOPS) a RTX 5060 (614 TOPS), nicméně u architektury Nvidia Blackwell je to při výpočtech s datovým typem FP4 a u AMD RDNA 4 je to pro výpočty s jednodušším celočíselným formátem INT4. A přímo srovnávat hodnoty TOPS a TFLOPS mezi různými architekturami úplně nejde.

Křemík Radeonů RX 9000: Detaily a novinky architektury AMD RDNA 4 Přečtěte si také:

Křemík Radeonů RX 9000: Detaily a novinky architektury AMD RDNA 4

GPU Navi 44 má 128bitovou sběrnici a na ní může být osazeno buď 8 GB, nebo 16 GB paměti GDDR6 (propustnost by zřejmě měla být 320 GB/s při efektivním taktu 20,0 GHz). V prodeji budou obě verze kapacity, kdy kompromisní 8GB budou mít logicky nižší cenu, zatímco ty 16GB pak budou lépe připravené na nejnáročnější dnešní a budoucí hry. Možné problémy, které dnes už s 8GB pamětí mohou být, ukázaly nedávno testy konkurenční GeForce RTX 5060 Ti 8GB.

Specifikace grafiky Radeon RX 9060 XT

Specifikace grafiky Radeon RX 9060 XT

Autor: AMD

PCI Express s 16 linkami

Až na možnost 16GB paměti je tedy tato grafika opravdu skoro přesnou polovinou Radeonu RX 9070 XT (a Navi 44 polovinou čipu Navi 48). Neplatí to ale v jedné věci: Dříve se mělo za to, že GPU bude mít zúžené rozhraní PCI Express 5.0 s jen osmi linkami, což by odpovídalo předchozím generacím (Radeon RX 6600 a 6600 XT, RX 7600 a RX 7600 XT). Toto se překvapivě nepotvrdilo – dle specifikací GPU poskytuje plné rozhraní PCI Express 5.0 ×16.

Bude to mít tu výhodu, že se zřejmě zabrání potenciální ztrátě výkonu v počítačích, které mají podporu jen PCI Expressu 4.0, jehož linky poskytují poloviční rychlost. Týká se to i velkého množství B650 (a B840) desek na platformě AM5. S osmi linkami 4.0 už by možná GPU nefungovalo ideálně, ale takto na podobných deskách GPU poběží s PCIe 4.0 ×16 a problémy by to mělo zažehnat.

Grafická karta Radeon RX 9060 XT

Grafická karta Radeon RX 9060 XT

Autor: AMD

AMD uvádí celkovou spotřebu karty či TDP (firma ale používá zkratku TBP – Total Board Power) netypicky ne jako jedno číslo, ale jako rozsah: 150–182 W. Zatím úplně nevíme, co se tím míní. Mohlo by jít o rozsah spotřeb různých karet, kdy 150 W by bylo základní výchozí TDP a nereferenční „OC“ karty by se pak pohybovaly od této hodnoty až po oněch 182 W u nějakého nejvýše taktovaného modelu. Karta každopádně má u referenčního návrhu napájení jen jedním jediným osmipinovým konektorem. Nicméně některé nereferenční modely mohou asi nést dva (například pro potřeby dalšího přetaktování), to teprve uvidíme.

(Aktualizováno: 16GB karty budou spotřebou začínat o deset wattů výš, na 160 W pro referenční karty a víc pro nereferenční.)

Oficiální specifikace potvrdily, že čip Navi 44 podporuje obrazové výstupy HDMI 2.1b i DisplayPort 2.1a, také by tedy zřejmě mělo umět maximálně až 8K obrazovky jako Radeony RX 9070 a 9070 XT. Zvláštnost čipu Navi 44 je, že podporuje jen tři výstupy (což bude pro úsporu místa na čipu) místo obvyklejších čtyř.

Radeon RX 9060 XT od Aceru. Na záslepce je vidět trojice obrazových výstupů

Radeon RX 9060 XT od Aceru

Autor: Acer, via: Momomo_us

Informace o chybějících enkodérech se nepotvrzují?

Ze začátku chyběla informace, zdali GPU má integrované multimediální enginy pro dekódování a enkódování videa. Jelikož menší GPU bývají navržená s ohledem na notebooky, v kterých multimediální funkce zajišťuje integrované GPU v procesoru, panovaly obavy, že by mohly by být z Navi 44 odebrané kvůli zmenšení čipu a snížení ceny. Aktualizováno: Web AMD zdá se potvrzuje, že Radeon RX 9060 XT multimediální enginy obsahuje. Podle specifikací podporuje enkódování i dekódování obvyklých formátů: H.264, H.265 alias HEVC i AV1.  (Není zmíněno VP9, ale to ani u Radeonů RX 9070 XT nebo starších karet, AMD tento formát ve specifikacích neuvádí.)

Aktualizováno: Ceny jdou proti 8GB kartám Nvidie, datum vydání

Po úvodní prezentaci AMD už jsou jasné i ceny karty a to, jak je namířená. Radeon RX 9060 XT 16GB má oficiální doporučenou cenu 349 $, což u nás vychází s DPH na asi 9300 Kč či 380 €. Tato karta tedy bude namířená proti GeForce RTX 5060 Ti 8GB (379 $).

Podle AMD ji má v průměru porážet asi o +6 %, což jsou ale oficiální benchmarky, které mohou být ovlivněné například příznivou volbou her a nastavení (jde například o testování v rozlišení 1440p). Nicméně v situacích, kde RTX 5060 Ti 8GB kvůli malé paměti narazí na problémy, logicky 16GB Radeon vyhraje.

Toto srovnání je zdá se pro 180W Radeon RX 9060 XT (stejné TDP jako má RTX 5060 Ti), tedy s o něco vyšší než onou výchozí 160W spotřebou. Je možné, že u těchto karet firma zkouší podobný model jako v noteboocích, kdy nejsou striktně jen jedny referenční parametry a vedle nich je všechno ostatní OC (přetaktování), ale rozsah spotřeb a od nich se odvíjejících výkonů, které výrobci karet mohou zvolit.

Oficiální benchmarky Radeonu RX 9060 XT dle AMD

Oficiální benchmarky Radeonu RX 9060 XT dle AMD

Autor: AMD, via: VideoCardz

AMD s tímto modelem poskytuje víc kapacity paměti a 16linkové rozhraní (což nemusí být moc důležité, ale uvidíme) za nižší cenu, což zní dobře. Přitom čip Navi 44 je podstatně větší při použití stejného výrobního procesu, takže AMD stojí výroba víc než 181mm² křemík GB206 používaný Nvidií. Nvidia používá (nejspíš) dražší paměti, ale když je za stejnou, respektive dokonce nižší cenu u AMD osazeno 16 GB GDDR6 proti 8 GB GDDR7, opět jsou asi výrobní náklady nižší u Nvidie.

Z tohoto srovnání s 8GB kartou se dá dovodit, že v průměru bude Radeon RX 9060 XT s 16GB pomalejší než GeForce RTX 5060 Ti 16GB (429 $). To se však čekalo vzhledem k parametrům čipu Navi 44.

Radeon RX 9060 XT 8GB má oficiálně doporučenou cenu 299 $. U nás asi 8000 Kč / 326 €. V tomto případě tedy grafika míří na levnější model GeForce RTX 5060 (také 8GB) s úplně stejnou cenou. Soudě podle předchozího srovnání by v tomto případě mohl Radeon mít mít znatelně navrch v hrubém výkonu (při o 15W vyšší spotřebě) a situace s pamětí už je stejná u obou karet.

prace_s_linuxem_tip

Za těchto podmínek by už teoreticky mohlo 16 linek u Radeonu přidávat jistou výhodu proti RTX 5060 (jak RTX 5060 Ti, tak RTX 5060 mají rozhraní PCIe 5.0 ×8), protože v situace nedostatku paměti se do karty musí nahrávat data z operační paměti počítače právě přes PCI Express. S rozhraním PCIe 5.0 ×16 by zde zpomalení tím způsobené mohlo být menší a tím by se i výkon mohl propadat méně. Ale zda to opravdu (o trošku) pomůže, to budou muset ukázat až testy. U GeForce RTX 5060 Ti 8GB bylo nicméně zaznamenáno, že PCIe 4.0 ×8 už jejímu výkonu ubližuje, takže na deskách podporujících jen PCIe 4.0 a nikoliv PCIe 5.0 by Radeon asi mohl výhodu mít.

V obchodech za dva týdny

Dnešní odhalení ještě není reálným startem prodeje této karty. Ten zřejmě nastane až po opadnutí Computexového ruchu – v obchodech se karty objeví 5. 6. Recenze snad také vyjdou krátce předtím.Zdroje: AMD, VideoCardz, Momomo_us

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