Cloudové hraní může představovat drastickou ekologickou zátěž

4. 9. 2020

Sdílet

Autor: © Paolese - Fotolia.com
Hraní videoher v cloudu může vést do deseti let k až o 30% vyšší uhlíkové stopě, ukazují výsledky nové studie.

Hraní videoher přes streamovací služby je na pozvolném vzestupu. Microsoft se chystá spustit konkurenci pro googlovskou Stadii a učiní tak další krok pro možnost hraní špičkových titulů bez nutnosti vlastnit drahý hardware či stahovat obsáhlé aktualizace. Může však mít takové hraní na dálku i svá negativa? Vědci z univerzity v britském Lancasteru tvrdí, že ano. A závažná. Odhadují, že pokud by se hráči během následující dekády přeorientovali na cloudové hraní, míra uhlíkových emisí by se mohla zvýšit až o 30%.

Jejich argumentace je jednoduchá. Uživatel se sice nemusí trápit s pořizováním neustále výkonnějšího hardwaru, když si vystačí jen s vysokorychlostním internetovým připojením, to by si však žádalo rozsáhlou aktualizaci infrastruktury, včetně obřích datových center. Výzkumníci se zaměřili na tři možné scénáře vývoje.

Od toho, kdy by cloudové hraní zůstalo okrajovou záležitostí, až po ten, kdy by se na něj během příštích deseti let přeorientovalo 90% hráčů. V tom extrémním by v roce 2030 stoupla roční emise skleníkových plynů až o 30%, přičemž ve svých výpočtech vědci zohlednili i úspory plynoucí z omezené výroby nových herních konzolí. Také upozorňují, že počítají se streamingem v rozlišení 720p a 1080p. Pokud by se rozšířil streaming ve 4K, mohly by být emise ještě dramatičtější.

Se závěry lancasterských vědců souhlasí též Evan Mills, šéf projektu Zeleného hraní – Green Gaming, realizovaného v americké národní laboratoři Berkeley.

„Navzdory představě o neviditelnosti a čistotě, kterou evokuje slůvko cloud, realita je představována enormním množstvím energeticky náročného hardwaru,“ poznamenává Mills. Jeho tým spočítal například to, že herní konzole připojená ke cloudovému hraní spotřebovává o 156% energie víc, než když je používána jen lokálně. Podstatně náročnější na energii je cloudové hraní taky ve srovnání se sledováním filmů online.

Existují ale samozřejmě i argumenty na podporu cloudového hraní. Ať už je to nižší produkce samotných konzolí nebo disků s hrami, včetně tedy zátěže na životní prostředí, kterou představuje jejich distribuce. Vědci z univerzity v Lancasteru také připouští, že streamované hraní může být při nižších rozlišeních v některých případech šetrnější než dnes rozšířené digitální downloady her, jejichž velikost nezřídka přesahuje 100 GB.

prace_s_linuxem_tip

Microsoft, který pozvolna rozjíždí svůj projekt xCloud, tvrdí, že jeho herní servery jsou energeticky efektivnější než domácí konzole. A stejně tak Google vychvaluje svoji Stadii – datová centra, která využívá, jsou prý dvojnásobně šetrnější než běžná datová centra. Obě firmy navíc tvrdí, že jejich datová centra jsou uhlíkově neutrální, což však může znamenat klidně to, že svou uhlíkovou stopu firmy kompenzují investováním do „zelených“ projektů.

O dostatečnosti těchto kompenzací výzkumníci pochybují, byť připouštějí, že jejich odhady jsou jen hrubé. Změnit je může například vývoj nových technologií, které by byly energeticky šetrnější, byť ty zase mohou čelit větší intenzitě provozu. Příležitost tak představuje, jako v minulosti už mnohokrát, zároveň problém, který je třeba řešit.

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