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

François Beaufort
François Beaufort

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

getDisplayMedia() kullanan birçok web uygulaması, yakalanan yüzeyin video önizlemesini kullanıcıya gösterir. Örneğin, video konferans uygulamaları bu videoyu genellikle uzak kullanıcılara aktarırken aynı zamanda yerel bir HTMLVideoElement olarak oluşturur. Böylece yerel kullanıcı sürekli olarak paylaştıklarının önizlemesini 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ının yanı sıra yakalanan bir sekmenin yakınlaştırma düzeyini okumasına ve yazmasına da olanak tanır.

Bir kullanıcı, yakalanan sekmeyi (demo) kaydırıp yakınlaştırır.

Yakalanan Yüzey Kontrolü'nü neden kullanmalısınız?

Tüm video konferans uygulamalarının aynı dezavantajı vardır: Kullanıcı, yakalanan bir sekme veya pencereyle etkileşimde bulunmak isterse bu yüzeye geçerek onu video konferans uygulamasından uzaklaştırmalıdır. Bu durum bazı zorluklara yol açıyor:

  • Kullanıcı, video konferans sekmesi ve paylaşılan sekme için Pencere İçinde Pencere veya ayrı yan yana pencereler kullanmadığı sürece, yakalanan uygulamayı ve uzak kullanıcıların videolarını aynı anda göremez. Daha küçük ekranlarda bu işlem zor olabilir.
  • Video konferans uygulaması ile yakalanan yüzey arasında geçiş yapmak, kullanıcıyı zorluyor.
  • Kullanıcı uygulama dışındayken video konferans uygulamasının gösterdiği denetimlere erişimini kaybeder; Örneğin, yerleştirilmiş sohbet uygulaması, emoji tepkiler, görüşmeye katılmak isteyen kullanıcılarla ilgili bildirimler, multimedya ve düzen denetimleri ve diğer faydalı video konferans özellikleri.
  • Sunucu, kontrol yetkisini uzaktaki katılımcılara veremez. Bu durum, uzaktan kullanıcıların sunucunun slaytını değiştirmesini, biraz yukarı aşağı kaydırmasını veya yakınlaştırma seviyesini ayarlamasını istediği çok tanıdık bir senaryoya yol açar.

Captured Surface Control API bu sorunları ele alır.

Yakalanmış Yüzey Kontrolü'nü nasıl kullanabilirim?

Yakalanan Yüzey Denetimi'nin başarıyla kullanılması için birkaç adım gerekir. Örneğin, bir tarayıcı sekmesinin açıkça yakalanması ve yakalanan sekmeyi kaydırıp yakınlaştırabilmek için kullanıcıdan izin alınması gerekir.

Tarayıcı sekmesini kaydet

İlk olarak kullanıcıdan getDisplayMedia() ile paylaşacak bir yüzey seçmesini isteyin ve bu süreçte yakalama oturumuyla bir CaptureController nesnesini ilişkilendirin. En kısa zamanda, yakalanan yüzeyi kontrol etmek için o nesneyi kullanacağız.

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

Daha sonra, yakalanan yüzeyin yerel önizlemesini <video> öğesi biçiminde oluşturun:

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

Kullanıcı bir pencere veya ekran paylaşmayı seçerse bu durum şimdilik kapsam dışındadır ancak kullanıcı 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 nesnesindeki sendWheel() veya setZoomLevel() ilk çağrısı, bir izin istemi oluşturuyor. Kullanıcı izin verirse söz konusu CaptureController nesnesinde bu yöntemlerin diğer çağrılarına izin verilir. Kullanıcı izin reddederse verilen taahhüt 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 gezinmeden sonra kalamayacağını unutmayın. Ancak yakalama oturumları, yakalanan sayfadaki gezinmede geçerliliğini korur.

Kullanıcıya izin istemi göstermek için kullanıcı hareketi gereklidir. Yalnızca sendWheel() ve setZoomLevel() çağrıları için ve yalnızca istemin gösterilmesi gerekiyorsa kullanıcı hareketi gereklidir. Kullanıcı web uygulamasında bir yakınlaştırma veya uzaklaştırma düğmesini tıklarsa bu kullanıcı hareketi gerçekleştirilmiş olur; Ancak uygulama öncelikle kaydırma kontrolünü sunmak isterse geliştiriciler kaydırmanın bir kullanıcı hareketi olmadığını unutmamalıdır. Bir olasılık, kullanıcıya ilk olarak "kaydırma işlemini başlatma" olanağı sunmaktır. düğmesi kullanın:

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ırma

Yakalama uygulaması, sendWheel() kullanarak bir sekmenin görüntü alanında kendi seçtiği büyüklükteki tekerlek etkinliklerini kendi seçtiği koordinatlar üzerinden yayınlayabilir. Etkinlik, yakalanan uygulama ile doğrudan kullanıcı etkileşimlerinden ayırt edilemez.

Yakalama uygulamasının "previewTile" adında bir <video> öğesi kullandığı varsayıldığında, aşağıdaki kodda, gönderme tekerlek etkinliklerinin yakalanan sekmeye nasıl geçeceği 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 explained further 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: Tekerlek etkinliğinin iletileceği koordinatlar.
  • wheelDeltaX ve wheelDeltaY: sırasıyla yatay ve dikey kaydırmalar için kaydırmaların piksel cinsinden büyüklüğü. Bu değerlerin, orijinal tekerlek etkinliğine kıyasla ters gittiğini unutmayın.

Olası bir 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)];
}

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

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

<video> öğesinin boyutu, tamamen yakalama uygulamasının alanı içindedir ve tarayıcı tarafından bilinmiyor. Sekmenin boyutu tamamen tarayıcının alan adı içindedir 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() yöntemini kullanır. Tarayıcı da aynı şekilde, yakalanan karelerin boyutu ile sekmenin boyutu arasında çeviri yapar ve kaydırma etkinliğini, web uygulamasının beklentisine uygun bir ofsette yayınlar.

sendWheel() tarafından verilen vaat aşağıdaki durumlarda reddedilebilir:

  • Yakalama oturumu henüz başlamadıysa veya zaten durduysa (sendWheel() işlemi tarayıcı tarafından işlenirken eşzamansız olarak durdurma dahil)
  • Kullanıcı, sendWheel() uygulamasına izin vermediyse.
  • Yakalama uygulaması [trackSettings.width, trackSettings.height] alanının dışındaki koordinatlarda 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ı etmek iyi bir fikirdir. (0, 0 değerinin normalde sınırların dışında olmayacağını unutmayın. Bu nedenle, kullanıcıdan izin istemek için bunları güvenle kullanabilirsiniz.)

Tarih aralığını

Yakalanan sekmenin yakınlaştırma düzeyiyle etkileşim, aşağıdaki CaptureController yüzeyleri üzerinden gerçekleştirilir:

  • getSupportedZoomLevels(), tarayıcı tarafından desteklenen ve %100 olarak tanımlanan "varsayılan yakınlaştırma düzeyinin" yüzdeleri olarak gösterilen yakınlaştırma düzeylerinin listesini döndürür. Bu liste tek yönlü olarak artmaktadır ve 100 değerini içeriyor.
  • getZoomLevel(), sekmenin geçerli yakınlaştırma düzeyini döndürür.
  • setZoomLevel(), sekmenin yakınlaştırma düzeyini getSupportedZoomLevels() ürününde bulunan herhangi bir tam sayı değerine ayarlar ve sekme başarılı olduğunda bir taahhüt döndürür. Yakalama oturumunun sonunda yakınlaştırma düzeyinin sıfırlanmadığına dikkat edin.
  • Kullanıcılar, yakalama uygulaması aracılığıyla veya yakalanan sekmeyle doğrudan etkileşim yoluyla yakınlaştırma düzeyini değiştirebileceğinden, oncapturedzoomlevelchange, yakalanan bir sekmenin yakınlaştırma seviyesi değişikliklerini dinlemenizi sağlar.

setZoomLevel() için yapılan aramalar izinle denetlenir; diğer salt okunur yakınlaştırma yöntemlerine yapılan çağrılar da etkinlikleri dinlerken olduğu gibi "ücretsiz"dir.

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 seviyesi değişikliklerine tepki vermeniz gösterilmektedir:

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

Özellik algılama

Çark etkinlikleri göndermenin 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 şunu kullanın:

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

Yakalanan Yüzey Kontrolü'nü etkinleştir

Captured Surface Control API, masaüstündeki Chrome'da Captured Surface Control (Yakalanan Yüzey Kontrolü) işaretinin arkasında kullanılabilir ve chrome://flags/#captured-surface-control adresinden etkinleştirilebilir.

Bu özellik ayrıca, masaüstünde Chrome 122'den itibaren bir kaynak denemesinde yer alıyor. Bu sayede, geliştiricilerin, sitelerini ziyaret eden kullanıcıların gerçek kullanıcılardan veri toplamasına olanak tanıyan bu özelliği etkinleştirebilecek. Kaynak denemeleri ve bunların işleyiş şekli 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'lerin Yakalanan Yüzey Kontrolü'ne nasıl erişeceğini yönetmenizi sağlar. Güvenlikle ilgili dengeleri anlamak için Yakalanan Yüzey Kontrolü 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 demo çalıştırarak Yakalanmış Yüzey Kontrolü'nü oynayabilirsiniz. Kaynak kodu kontrol ettiğinizden emin olun.

Chrome'un önceki sürümlerindeki değişiklikler

Yakalanan Yüzey Kontrolü ile ilgili bilmeniz gereken bazı önemli davranış farklılıkları aşağıda verilmiştir:

  • Chrome 124 ve önceki sürümlerde:
    • İzin verildiyse, yakalama kaynağının değil, söz konusu CaptureController ile ilişkili yakalama oturumuna göre belirlenir.
  • Chrome 122'de:
    • getZoomLevel(), sekmenin mevcut yakınlaştırma seviyesiyle bir taahhüt döndürür.
    • Kullanıcı, uygulamaya kullanım izni vermediyse sendWheel(), "No permission." hata mesajıyla reddedilen bir 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 ile ilgili deneyimleriniz hakkında bilgi almak ister.

Bize tasarım hakkında bilgi verin

Yakalanmış Yüzey Yakalama özelliği ile ilgili olarak beklediğiniz gibi çalışmayan bir şey mi var? Yoksa fikrinizi uygulamak için ihtiyacınız olan eksik yöntemler veya özellikler mi var? Güvenlik modeliyle ilgili bir sorunuz veya yorumunuz mu var? GitHub deposunda bir spesifikasyon sorunu bildirin veya mevcut bir soruna düşüncelerinizi ekleyin.

Uygulamayla ilgili bir sorun mu var?

Chrome'un uygulanmasıyla ilgili bir hata buldunuz mu? Yoksa uygulama, spesifikasyondan farklı mı? https://new.crbug.com adresinden hata bildiriminde bulunun. Olabildiğince çok ayrıntıyı ve videoyu çoğaltma talimatlarını eklemeyi unutmayın. Glitch, yeniden oluşturulabilir hataları paylaşmak için mükemmel bir seçenektir.