یک برگه ضبط شده را اسکرول و بزرگنمایی کنید، یک برگه ضبط شده را اسکرول و بزرگنمایی کنید

فرانسوا بوفور
François Beaufort

اشتراک‌گذاری برگه‌ها، پنجره‌ها و صفحه‌ها در حال حاضر در پلتفرم وب با Screen Capture API امکان‌پذیر است. هنگامی که یک برنامه وب با getDisplayMedia() تماس می‌گیرد، Chrome از کاربر می‌خواهد یک برگه، پنجره یا صفحه را با برنامه وب به‌عنوان ویدیوی MediaStreamTrack به اشتراک بگذارد.

بسیاری از برنامه‌های وب که از getDisplayMedia() استفاده می‌کنند، پیش‌نمایش ویدیویی از سطح ضبط‌شده را به کاربر نشان می‌دهند. برای مثال، برنامه‌های کنفرانس ویدیویی اغلب این ویدیو را برای کاربران راه دور پخش می‌کنند و در عین حال آن را به یک HTMLVideoElement محلی نیز رندر می‌کنند تا کاربر محلی دائماً پیش‌نمایش چیزی را که به اشتراک می‌گذارد ببیند.

این مستندات API جدید Captured Surface Control در کروم را معرفی می‌کند که به برنامه وب شما اجازه می‌دهد تا یک برگه ضبط‌شده را پیمایش کند، و همچنین سطح بزرگ‌نمایی یک برگه ضبط‌شده را بخواند و بنویسد.

کاربر یک برگه ضبط شده ( دمو ) را پیمایش و بزرگنمایی می کند.

چرا از Captured Surface Control استفاده کنیم؟

همه برنامه‌های کنفرانس ویدیویی از همین اشکال رنج می‌برند: اگر کاربر بخواهد با یک برگه یا پنجره ضبط‌شده تعامل داشته باشد، کاربر باید به آن سطح تغییر مکان داده و آنها را از برنامه کنفرانس ویدیویی دور کند. این چند چالش را به همراه دارد:

  • کاربر نمی‌تواند همزمان برنامه ضبط‌شده و ویدیوهای کاربران راه دور را ببیند، مگر اینکه از تصویر در تصویر یا پنجره‌های کنار هم جداگانه برای تب کنفرانس ویدیویی و برگه اشتراک‌گذاری شده استفاده کند. در یک صفحه نمایش کوچکتر، این ممکن است دشوار باشد.
  • نیاز کاربر به پریدن بین برنامه کنفرانس ویدیویی و سطح ضبط شده سنگین است.
  • وقتی کاربر از برنامه کنفرانس ویدیویی دور است، دسترسی به کنترل‌هایی را که در معرض آن قرار می‌گیرد، از دست می‌دهد. به عنوان مثال، یک برنامه چت تعبیه شده، واکنش های ایموجی، اعلان هایی در مورد درخواست کاربران برای پیوستن به تماس، کنترل های چند رسانه ای و طرح بندی، و سایر ویژگی های ویدئو کنفرانس مفید.
  • ارائه دهنده نمی تواند کنترل را به شرکت کنندگان از راه دور واگذار کند. این منجر به سناریوی بسیار آشنا می شود که در آن کاربران از راه دور از ارائه کننده می خواهند اسلاید را تغییر دهد، کمی بالا و پایین حرکت کند یا سطح بزرگنمایی را تنظیم کند.

API Captured Surface Control این مشکلات را برطرف می کند.

چگونه از Captured Surface Control استفاده کنم؟

استفاده موفقیت آمیز از Captured Surface Control به چند مرحله نیاز دارد، مانند گرفتن صریح برگه مرورگر و گرفتن مجوز از کاربر قبل از اینکه بتوانید برگه ضبط شده را اسکرول و بزرگنمایی کنید.

یک برگه مرورگر را ضبط کنید

با درخواست از کاربر برای انتخاب سطحی برای اشتراک گذاری با استفاده از getDisplayMedia() شروع کنید و در این فرآیند، یک شی CaptureController را با جلسه ضبط مرتبط کنید. به زودی از آن شی برای کنترل سطح گرفته شده استفاده خواهیم کرد.

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

در مرحله بعد، یک پیش نمایش محلی از سطح گرفته شده به شکل عنصر <video> تولید کنید:

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

اگر کاربر اشتراک گذاری یک پنجره یا یک صفحه را انتخاب کند، فعلاً خارج از محدوده است - اما اگر انتخاب کرد که یک برگه را به اشتراک بگذارد، ممکن است ادامه دهیم.

const [track] = stream.getVideoTracks();

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

درخواست مجوز

اولین فراخوانی sendWheel() یا setZoomLevel() بر روی یک شی CaptureController یک درخواست مجوز تولید می کند. اگر کاربر اجازه دهد، فراخوانی بیشتر این روش ها در آن شی CaptureController مجاز است. اگر کاربر اجازه را رد کند، قول برگشتی رد می شود.

توجه داشته باشید که اشیاء CaptureController به طور منحصربه‌فردی با یک جلسه ضبط خاص مرتبط هستند، نمی‌توانند با جلسه ضبط دیگری مرتبط شوند و از پیمایش صفحه‌ای که در آن تعریف شده‌اند باقی نمی‌مانند. با این حال، جلسات ضبط از پیمایش صفحه گرفته شده جان سالم به در می برند.

یک اشاره کاربر برای نشان دادن یک درخواست مجوز به کاربر مورد نیاز است. فقط تماس‌های sendWheel() و setZoomLevel() نیاز به ژست کاربر دارند و فقط در صورتی که درخواست نمایش داده شود. اگر کاربر روی دکمه بزرگنمایی یا کوچک نمایی در برنامه وب کلیک کند، آن حرکت کاربر مشخص است. اما اگر برنامه می‌خواهد ابتدا کنترل اسکرول را ارائه دهد، توسعه‌دهندگان باید در نظر داشته باشند که پیمایش یک حرکت کاربر نیست . یک امکان این است که ابتدا دکمه "شروع پیمایش" را به کاربر پیشنهاد دهید، مطابق مثال زیر:

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.
  }
});

اسکرول کنید

با استفاده از sendWheel() ، یک برنامه تصویربرداری می تواند رویدادهای چرخ را با اندازه انتخابی خود بر روی مختصات انتخابی خود در نمای یک برگه ارائه دهد. این رویداد با برنامه ضبط شده از تعامل مستقیم کاربر قابل تشخیص نیست.

با فرض اینکه برنامه تصویربرداری از عنصر <video> به نام "previewTile" استفاده می کند، کد زیر نحوه ارسال رویدادهای چرخ را به برگه ضبط شده نشان می دهد:

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() یک دیکشنری با دو مجموعه مقدار می گیرد:

  • x و y : مختصاتی که قرار است رویداد چرخ تحویل داده شود.
  • wheelDeltaX و wheelDeltaY : بزرگی طومارها، به پیکسل، برای طومارهای افقی و عمودی، به ترتیب. توجه داشته باشید که این مقادیر در مقایسه با رویداد چرخ اصلی معکوس هستند.

یک پیاده سازی ممکن از translateCoordinates() به شرح زیر است:

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

توجه داشته باشید که سه اندازه مختلف در کد قبلی وجود دارد:

  • اندازه عنصر <video> .
  • اندازه فریم های گرفته شده (در اینجا به عنوان trackSettings.width و trackSettings.height نشان داده شده است).
  • اندازه زبانه.

اندازه عنصر <video> کاملاً در دامنه برنامه ضبط است و برای مرورگر ناشناخته است. اندازه برگه کاملاً در دامنه مرورگر است و برای برنامه وب ناشناخته است.

برنامه وب از translateCoordinates() برای ترجمه offset های مربوط به عنصر <video> به مختصات در فضای مختصات خود آهنگ ویدیو استفاده می کند. مرورگر نیز بین اندازه فریم‌های گرفته شده و اندازه برگه ترجمه می‌کند و رویداد اسکرول را با یک افست مطابق با انتظارات برنامه وب ارائه می‌کند.

وعده بازگردانده شده توسط sendWheel() را می توان در موارد زیر رد کرد:

  • اگر جلسه ضبط هنوز شروع نشده یا قبلاً متوقف شده است، از جمله توقف ناهمزمان در زمانی که عملکرد sendWheel() توسط مرورگر مدیریت می‌شود.
  • اگر کاربر به برنامه اجازه استفاده از sendWheel() نداد.
  • اگر برنامه تصویربرداری تلاش کند یک رویداد پیمایشی را در مختصاتی ارائه دهد که خارج از [trackSettings.width, trackSettings.height] هستند. توجه داشته باشید که این مقادیر ممکن است به صورت ناهمزمان تغییر کنند، بنابراین بهتر است خطا را بگیرید و آن را نادیده بگیرید. (توجه داشته باشید که 0, 0 معمولاً خارج از محدوده نیست، بنابراین استفاده از آنها برای درخواست مجوز از کاربر بی خطر است.)

بزرگنمایی ضربه بزنید؛

تعامل با سطح زوم برگه ضبط شده از طریق سطوح CaptureController زیر انجام می شود:

  • getSupportedZoomLevels() لیستی از سطوح بزرگنمایی پشتیبانی شده توسط مرورگر را برمی گرداند که به صورت درصدهایی از "سطح بزرگنمایی پیش فرض" که به عنوان 100% تعریف می شود، نمایش داده می شود. این لیست به طور یکنواخت در حال افزایش است و حاوی مقدار 100 است.
  • getZoomLevel() سطح زوم فعلی برگه را برمی گرداند.
  • setZoomLevel() سطح بزرگنمایی برگه را به هر مقدار صحیح موجود در getSupportedZoomLevels() تنظیم می کند و در صورت موفقیت یک وعده را برمی گرداند. توجه داشته باشید که سطح بزرگنمایی در پایان جلسه عکس برداری تنظیم مجدد نمی شود.
  • oncapturedzoomlevelchange به شما امکان می دهد به تغییرات سطح زوم یک برگه ضبط شده گوش دهید زیرا کاربران ممکن است سطح بزرگنمایی را از طریق برنامه عکسبرداری یا از طریق تعامل مستقیم با برگه ضبط شده تغییر دهند.

فراخوانی به setZoomLevel() با مجوز بسته می شود. تماس‌های دیگر، روش‌های بزرگ‌نمایی فقط خواندنی «رایگان» هستند، مانند گوش دادن به رویدادها.

مثال زیر به شما نشان می دهد که سطح بزرگنمایی یک برگه ضبط شده را در یک جلسه ضبط موجود افزایش دهید:

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.
    // ...
  }
});

مثال زیر به شما نشان می دهد که به تغییرات سطح زوم یک برگه ضبط شده واکنش نشان دهید:

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

تشخیص ویژگی

برای بررسی اینکه آیا ارسال رویدادهای چرخ پشتیبانی می شود، از موارد زیر استفاده کنید:

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

برای بررسی اینکه آیا کنترل زوم پشتیبانی می‌شود، از موارد زیر استفاده کنید:

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

کنترل سطح ضبط شده را فعال کنید

Captured Surface Control API در Chrome روی دسک‌تاپ پشت پرچم Captured Surface Control موجود است و می‌توان آن را در chrome://flags/#captured-surface-control فعال کرد.

این ویژگی همچنین در حال ورود به یک آزمایش اولیه است که با Chrome 122 در دسک‌تاپ شروع می‌شود ، که به توسعه‌دهندگان اجازه می‌دهد این ویژگی را برای بازدیدکنندگان سایت‌هایشان فعال کنند تا داده‌های کاربران واقعی را جمع‌آوری کنند. برای اطلاعات بیشتر در مورد آزمایش‌های مبدأ و نحوه عملکرد آنها ، به شروع کار با آزمایش‌های مبدأ مراجعه کنید.

امنیت و حریم خصوصی

خط‌مشی مجوز "captured-surface-control" به شما امکان می‌دهد نحوه دسترسی برنامه عکس‌برداری و iframe‌های شخص ثالث تعبیه‌شده به Captured Surface Control را مدیریت کنید. برای درک معاوضه‌های امنیتی، بخش ملاحظات حریم خصوصی و امنیتی توضیح‌دهنده کنترل سطح ضبط شده را بررسی کنید.

نسخه ی نمایشی

با اجرای دمو در Glitch می توانید با Captured Surface Control بازی کنید. حتماً کد منبع را بررسی کنید .

تغییرات نسبت به نسخه های قبلی کروم

در اینجا چند تفاوت رفتاری کلیدی در مورد کنترل سطح ضبط شده وجود دارد که باید از آنها آگاه باشید:

  • در کروم 124 و قبل از آن:
    • مجوز - در صورت اعطا - به جلسه ضبط مرتبط با آن CaptureController اختصاص دارد، نه به مبدا ضبط.
  • در کروم 122:
    • getZoomLevel() یک وعده با سطح زوم فعلی برگه برمی گرداند.
    • sendWheel() یک وعده رد شده را با پیام خطای "No permission." اگر کاربر به برنامه اجازه استفاده را نداده باشد. نوع خطا "NotAllowedError" در کروم 123 و جدیدتر است.
    • oncapturedzoomlevelchange در دسترس نیست. می توانید این ویژگی را با استفاده از setInterval() پر کنید.

بازخورد

تیم Chrome و انجمن استانداردهای وب می‌خواهند درباره تجربیات شما با Captured Surface Control بشنوند.

در مورد طراحی به ما بگویید

آیا چیزی در مورد Captured Surface Capture وجود دارد که آنطور که انتظار داشتید کار نمی کند؟ یا آیا روش ها یا ویژگی هایی وجود دارد که برای اجرای ایده خود به آنها نیاز دارید؟ سوال یا نظری در مورد مدل امنیتی دارید؟ یک مشکل مشخصات را در مخزن GitHub ثبت کنید یا افکار خود را به یک مشکل موجود اضافه کنید.

مشکل در اجرا؟

آیا اشکالی در پیاده سازی کروم پیدا کردید؟ یا اجرا با مشخصات متفاوت است؟ یک اشکال را در https://new.crbug.com ثبت کنید. حتماً تا جایی که می توانید جزئیات و همچنین دستورالعمل هایی را برای بازتولید درج کنید. Glitch برای به اشتراک گذاری باگ های قابل تکرار عالی عمل می کند.