Yakalanan bir sekmeyi kaydırın ve yakınlaştırın

François Beaufort
François Beaufort

Sekmeleri, pencereleri ve ekranları web platformunda Screen Capture API ile paylaşmak zaten mümkündür. Bir web uygulaması getDisplayMedia() çağrısı yaptığında Chrome, kullanıcıdan web uygulamasıyla bir sekme, pencere veya ekranı MediaStreamTrack videosu olarak paylaşmasını ister.

getDisplayMedia() kullanan birçok web uygulaması, kullanıcıya yakalanan yüzeyin video önizlemesini gösterir. Örneğin, video konferans uygulamaları genellikle bu videoyu uzaktaki kullanıcılara yayınlarken aynı zamanda yerel bir HTMLVideoElement'da da oluşturur. Böylece yerel kullanıcı, paylaştığı içeriğin önizlemesini sürekli olarak görür.

Bu dokümanda, Chrome'daki yeni Captured Surface Control API tanıtılmaktadır. Bu API, web uygulamanızın yakalanan bir sekmeyi kaydırmasına, yakalanan bir sekmenin yakınlaştırma düzeyini okumasına ve yazmasına olanak tanır.

Kullanıcı, yakalanan bir sekmeyi kaydırır ve yakınlaştırır (demo).

Yakalanan Yüzey Denetimi neden kullanılmalıdır?

Tüm video konferans uygulamalarında aynı sorun söz konusudur: Kullanıcı, yakalanan bir sekme veya pencereyle etkileşimde bulunmak isterse bu yüzeye geçerek video konferans uygulamasından uzaklaştırmalıdır. Bu da bazı zorlukları beraberinde getirir:

  • Pencere İçinde Pencere modu veya video konferans sekmesi ve paylaşılan sekme için yan yana ayrı pencereler kullanılmadığı sürece kullanıcı, yakalanan uygulamayı ve uzaktaki kullanıcıların videolarını aynı anda göremez. Daha küçük bir ekranda bu zor olabilir.
  • Video konferans uygulaması ile yakalanan yüzey arasında geçiş yapma ihtiyacı, kullanıcıya yüklenmekte.
  • Kullanıcı, video konferans uygulamasından uzaktayken gösterilen denetimlere (ör. yerleşik sohbet uygulaması, emoji tepkileri, görüşmeye katılmak isteyen kullanıcılarla ilgili bildirimler, multimedya ve düzen kontrolleri ve diğer yararlı video konferans özellikleri) erişimini kaybeder.
  • Sunucu, uzaktan katılımcılara kontrol yetkisi veremez. Bu, uzak kullanıcıların sunucudan slaydı değiştirmesini, biraz yukarı aşağı kaydırmasını veya yakınlaştırma düzeyini ayarlamasını istediği, çok tanıdık bir senaryoya neden oluyor.

Yakalanan Yüzey Denetimi API'sı bu sorunları ele alır.

Yakalanan Yüzey Denetimi'ni nasıl kullanabilirim?

Yakalanan Yüzey Denetimi'nin başarıyla kullanılması için, bir tarayıcı sekmesinin açıkça yakalanması ve yakalanan sekmeyi kaydırmadan ve yakınlaştırmadan önce kullanıcıdan izin almak gibi birkaç adım gerekir.

Tarayıcı sekmesi yakala

Kullanıcıdan getDisplayMedia() kullanarak paylaşılacak bir yüzey seçmesini isteyerek başlayın ve bu sırada yakalama oturumuyla bir CaptureController nesnesi ilişkilendirin. Çok yakında, yakalanan yüzeyi kontrol etmek için bu nesneyi kullanacağız.

const controller = new CaptureController();
const stream = await navigator.mediaDevices.getDisplayMedia({ controller });

Ardından, yakalanan yüzeyin bir <video> öğesi biçiminde yerel önizlemesini oluşturun:

const previewTile = document.querySelector('video');
previewTile.srcObject = stream;

Kullanıcı bir pencere veya ekran paylaşmayı seçerse bu şimdilik kapsam dışındadır, ancak bir sekmeyi paylaşmayı seçerse işleme devam edebiliriz.

const [track] = stream.getVideoTracks();

if (track.getSettings().displaySurface !== 'browser') {
  // Bail out early if the user didn't pick a tab.
  return;
}

İzin istemi

Belirli bir CaptureController nesnesinde sendWheel() veya setZoomLevel() işlevi için yapılan ilk çağrı, izin istemi üretir. Kullanıcı izin verirse söz konusu CaptureController nesnesinde bu yöntemlerin başka çağrılarına izin verilir. Kullanıcı izin vermezse döndürülen söz de reddedilir.

CaptureController nesnelerinin belirli bir capture-session ile benzersiz bir şekilde ilişkilendirilmiş olduğunu, başka bir yakalama oturumuyla ilişkilendirilemeyeceğini ve tanımlandıkları sayfada gezinme durumunda kalmayacaklarını unutmayın. Ancak yakalama oturumları, yakalanan sayfada gezinmeden sonra kalır.

Kullanıcıya izin isteminin gösterilmesi için kullanıcı hareketi gereklidir. Yalnızca sendWheel() ve setZoomLevel() çağrılarında kullanıcı hareketi gerekir ve istemin gösterilmesi gerekir. Kullanıcı, web uygulamasında yakınlaştırma veya uzaklaştırma düğmesini tıklarsa bu kullanıcı hareketi verilir, ancak uygulama önce kaydırma kontrolü sunmak istiyorsa geliştiricilerin kaydırmanın bir kullanıcı hareketi olmadığını unutmaması gerekir. Olasılıklardan biri, aşağıdaki örneğe göre önce kullanıcıya bir "kaydırmaya başla" düğmesi sunmaktır:

const startScrollingButton = document.querySelector('button');

startScrollingButton.addEventListener('click', async () => {
  try {
    const noOpWheelAction = {};

    await controller.sendWheel(noOpWheelAction);
    // The user approved the permission prompt.
    // You can now scroll and zoom the captured tab as shown later in the article.
  } catch (error) {
    return; // Permission denied. Bail.
  }
});

Kaydır

Bir yakalama uygulaması, sendWheel() özelliğini kullanarak bir sekmenin görüntü alanında kendi seçtiği koordinatlar üzerinden kendi seçtiği büyüklükteki çember etkinlikleri yayınlayabilir. Etkinlik, yakalanan uygulama ile doğrudan kullanıcı etkileşimi arasında ayırt edilemiyor.

Yakalama uygulamasının "previewTile" adlı bir <video> öğesi kullandığı varsayıldığında, aşağıdaki kodda gönderme tekerleği etkinliklerinin yakalanan sekmeye nasıl aktarılacağı gösterilmektedir:

const previewTile = document.querySelector('video');

previewTile.addEventListener('wheel', async (event) => {
  // Translate the offsets into coordinates which sendWheel() can understand.
  // The implementation of this translation is further explained below.
  const [x, y] = translateCoordinates(event.offsetX, event.offsetY);
  const [wheelDeltaX, wheelDeltaY] = [-event.deltaX, -event.deltaY];

  try {
    // Relay the user's action to the captured tab.
    await controller.sendWheel({ x, y, wheelDeltaX, wheelDeltaY });
  } catch (error) {
    // Inspect the error.
    // ...
  }
});

sendWheel() yöntemi iki değer grubu içeren bir sözlük alır:

  • x ve y: Çark etkinliğinin sağlanacağı koordinatlar.
  • wheelDeltaX ve wheelDeltaY: Sırasıyla yatay ve dikey kaydırmalarda kaydırmaların piksel cinsinden büyüklüğü. Bu değerlerin, orijinal tekerlek etkinliğine kıyasla ters çevrilmiş olduğunu unutmayın.

Olası translateCoordinates() uygulaması:

function translateCoordinates(offsetX, offsetY) {
  const previewDimensions = previewTile.getBoundingClientRect();
  const trackSettings = previewTile.srcObject.getVideoTracks()[0].getSettings();

  const x = trackSettings.width * offsetX / previewDimensions.width;
  const y = trackSettings.height * offsetY / previewDimensions.height;

  return [Math.floor(x), Math.floor(y)];
}

Daha önceki kodda üç farklı boyut olduğunu unutmayın:

  • <video> öğesinin boyutu.
  • Yakalanan karelerin boyutu (burada trackSettings.width ve trackSettings.height olarak gösterilmiştir).
  • Sekmenin boyutu.

<video> öğesinin boyutu, yakalama uygulamasının alanı dahilindedir ve tarayıcı tarafından bilinmiyor. Sekmenin boyutu tamamen tarayıcının alan adı dahilindedir ve web uygulaması tarafından bilinmiyor.

Web uygulaması, <video> öğesine göre ofsetleri video kanalının kendi koordinat alanı içindeki koordinatlara çevirmek için translateCoordinates() özelliğini kullanır. Tarayıcı, yakalanan karelerin boyutu ile sekmenin boyutu arasında aynı şekilde çeviri yapar ve kaydırma etkinliğini, web uygulaması beklentisine karşılık gelen bir ofsette sunar.

sendWheel() tarafından verilen söz aşağıdaki durumlarda reddedilebilir:

  • Yakalama oturumu henüz başlamadıysa veya durduysa sendWheel() işlemi tarayıcı tarafından işlenirken eşzamansız olarak durdurulması da buna dahildir.
  • Kullanıcı, uygulamaya sendWheel() kullanımı için izin vermediyse.
  • Yakalama uygulaması, [trackSettings.width, trackSettings.height] dışındaki koordinatlarda bir kaydırma etkinliği göndermeye çalışırsa. Bu değerlerin eşzamansız olarak değişebileceğini unutmayın. Bu nedenle, hatayı yakalayıp göz ardı etmeniz iyi bir fikirdir. (0, 0 normal şartlarda sınırların dışında değildir; bu nedenle, kullanıcıdan izin istemek için bunları kullanmak güvenlidir.)

Tarih aralığını

Yakalanan sekmenin yakınlaştırma düzeyiyle etkileşim, aşağıdaki CaptureController yüzeyleri üzerinden yapılır:

  • getSupportedZoomLevels(), tarayıcı tarafından desteklenen yakınlaştırma düzeylerinin listesini döndürür. Bu liste, %100 olarak tanımlanan "varsayılan yakınlaştırma düzeyi"nin yüzdeleriyle belirtilir. Bu liste tekdüze şekilde artmaktadır ve 100 değerini içermektedir.
  • getZoomLevel(), sekmenin geçerli yakınlaştırma düzeyini döndürür.
  • setZoomLevel(), sekmenin yakınlaştırma düzeyini getSupportedZoomLevels() öğesinde bulunan herhangi bir tam sayı değerine ayarlar ve başarılı olduğunda bir söz döndürür. Yakalama oturumunun sonunda yakınlaştırma düzeyinin sıfırlanmadığını unutmayın.
  • oncapturedzoomlevelchange, yakalanan bir sekmenin yakınlaştırma düzeyini, yakalama uygulaması veya yakalanan sekmeyle doğrudan etkileşimde bulunarak değiştirebildiği için, yakalanmış bir sekmenin yakınlaştırma düzeyini dinlemenizi sağlar.

setZoomLevel() için yapılan aramalar izin alınarak kontrol altına alınır; diğer salt okunur yakınlaştırma yöntemlerine yapılan aramalar ve etkinlikleri dinlemek "ücretsizdir".

Aşağıdaki örnekte, mevcut bir yakalama oturumunda yakalanan bir sekmenin yakınlaştırma düzeyini artırmanız gösterilmektedir:

const zoomIncreaseButton = document.getElementById('zoomInButton');

zoomIncreaseButton.addEventListener('click', async (event) => {
  const levels = CaptureController.getSupportedZoomLevels();
  const index = levels.indexOf(controller.getZoomLevel());
  const newZoomLevel = levels[Math.min(index + 1, levels.length - 1)];

  try {
    await controller.setZoomLevel(newZoomLevel);
  } catch (error) {
    // Inspect the error.
    // ...
  }
});

Aşağıdaki örnekte, yakalanan bir sekmenin yakınlaştırma düzeyi değişikliklerine nasıl tepki vereceğiniz gösterilmektedir:

controller.addEventListener('capturedzoomlevelchange', (event) => {
  const zoomLevel = controller.getZoomLevel();
  document.querySelector('#zoomLevelLabel').textContent = `${zoomLevel}%`;
});

Özellik algılama

Tekerlek etkinliklerinin gönderilmesinin desteklenip desteklenmediğini kontrol etmek için şunu kullanın:

if (!!window.CaptureController?.prototype.sendWheel) {
  // CaptureController sendWheel() is supported.
}

Yakınlaştırma kontrolünün desteklenip desteklenmediğini kontrol etmek için şunları kullanın:

if (!!window.CaptureController?.prototype.setZoomLevel) {
  // CaptureController setZoomLevel() is supported.
}

Yakalanan Yüzey Denetimini Etkinleştir

Captured Surface Control API, Chrome'daki masaüstünde Captured Surface Control bayrağının arkasında kullanılabilir ve chrome://flags/#captured-surface-control adresinden etkinleştirilebilir.

Bu özellik ayrıca masaüstü için Chrome 122 ile başlayan bir kaynak denemesine giriyor. Bu sayede geliştiriciler, sitelerini ziyaret eden kullanıcıların gerçek kullanıcılardan veri toplamak üzere bu özelliği etkinleştirebilecek. Kaynak denemeleri ve işleyiş şekilleri hakkında daha fazla bilgi için Kaynak denemelerini kullanmaya başlama başlıklı makaleyi inceleyin.

Güvenlik ve gizlilik

"captured-surface-control" izin politikası, yakalama uygulamanızın ve yerleştirilmiş üçüncü taraf iframe'lerinizin Yakalanan Yüzey Kontrolü'ne nasıl erişebileceğini yönetmenize olanak tanır. Güvenlik dengelemelerini anlamak için Yakalanan Yüzey Denetimi açıklayıcısının Gizlilik ve Güvenlikle İlgili Dikkat Edilmesi Gerekenler bölümüne göz atın.

Demo

Glitch'te demoyu çalıştırarak Yakalanan Yüzey Denetimi ile oynayabilirsiniz. Kaynak koduna göz atmayı unutmayın.

Chrome'un önceki sürümlerine göre yapılan değişiklikler

Yakalanan Yüzey Denetimi ile ilgili bilmeniz gereken bazı önemli davranış farklılıkları şunlardır:

  • Chrome 124 ve önceki sürümlerde:
    • İzin verilirse izin, yakalama kaynağını değil, söz konusu CaptureController ile ilişkili yakalama oturumunu kapsar.
  • Chrome 122'de:
    • getZoomLevel(), sekmenin mevcut yakınlaştırma düzeyiyle ilgili bir söz döndürür.
    • Kullanıcı uygulamaya kullanım izni vermediyse sendWheel(), "No permission." hata mesajıyla reddedilen sözü döndürür. Chrome 123 ve sonraki sürümlerde hata türü "NotAllowedError" şeklindedir.
    • oncapturedzoomlevelchange kullanılamıyor. setInterval() kullanarak bu özelliğe çoklu dolgu yapabilirsiniz.

Geri bildirim

Chrome ekibi ve web standartları topluluğu, Yakalanan Yüzey Denetimi deneyimleriniz hakkında bilgi almak ister.

Bize tasarım hakkında bilgi verin

Yakalanan Yüzey Yakalama özelliğiyle ilgili olarak beklediğiniz gibi çalışmayan bir özellik var mı? Fikrinizi uygulamak için gereken eksik yöntemler veya özellikler mi var? Güvenlik modeliyle ilgili bir sorunuz veya yorumunuz mu var? GitHub deposunda spesifikasyon sorunu bildiriminde bulunun veya mevcut bir soruna düşüncelerinizi ekleyin.

Uygulamayla ilgili bir sorun mu var?

Chrome'un uygulamasında bir hata buldunuz mu? Yoksa uygulama, spesifikasyondan farklı mı? https://new.crbug.com adresinden hata bildiriminde bulunun. Hatayı yeniden oluşturma talimatlarını ve mümkün olduğunca çok ayrıntıyı eklediğinizden emin olun. Glitch, tekrarlanabilir hataları paylaşmak için idealdir.