ÐÑполÑзование инÑеÑÑейÑа Screen Capture API
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
Want more browser support for this feature? Tell us why.
Ð ÑÑой ÑÑаÑÑе изÑÑаеÑÑÑ Ð¸ÑполÑзование пÑогÑаммного инÑеÑÑейÑа Screen Capture и его меÑода getDisplayMedia() Ð´Ð»Ñ Ð·Ð°Ñ
ваÑа поÑока ÑкÑана (вÑего или его ÑаÑÑи), его запиÑи или пеÑедаÑи ÑеÑез ÑеÑÑÐ¸Ñ WebRTC .
ÐÑимеÑание:
Ðолезно оÑмеÑиÑÑ, ÑÑо поÑледние веÑÑии библиоÑеки WebRTC adapter.js вклÑÑаÑÑ ÑеализаÑÐ¸Ñ Ð¼ÐµÑода getDisplayMedia() Ð´Ð»Ñ Ð¾Ð±Ð¼ÐµÐ½Ð° изобÑажениÑми Ñ ÑкÑана на бÑаÑзеÑаÑ
, коÑоÑÑе его поддеÑживаÑÑ, но еÑÑ Ð½Ðµ ÑеализÑÑÑ ÑекÑÑий ÑÑандаÑÑнÑй инÑеÑÑейÑ, коÑоÑÑй Ñеализован в поÑледниÑ
веÑÑиÑÑ
Chrome, Edge, и Firefox.
ÐÐ°Ñ Ð²Ð°Ñ ÑодеÑжимого ÑкÑана
ÐаÑ
Ð²Ð°Ñ ÑодеÑжимого ÑкÑана, как живого поÑока MediaStream запÑÑкаеÑÑÑ Ð²Ñзовом меÑода navigator.mediaDevices.getDisplayMedia(), и возвÑаÑÐ°ÐµÑ ÑкземплÑÑ Ð¾Ð±ÑекÑа пÑомиÑа , коÑоÑÑй ÑазÑеÑаеÑÑÑ Ð¾Ð±ÑекÑом поÑока, ÑекÑÑиÑ
медиаданнÑÑ
Ñ ÑкÑана.
ÐапÑÑк заÑ
ваÑа Ñ ÑкÑана : в ÑÑиле async/await
async function startCapture(displayMediaOptions) {
let captureStream = null;
try {
captureStream =
await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
} catch (err) {
console.error("Error: " + err);
}
return captureStream;
}
Ðожно напиÑаÑÑ ÑÑÐ¾Ñ ÐºÐ¾Ð´, иÑполÑзÑÑ Ð°ÑинÑ
ÑоннÑÑ ÑÑнкÑÐ¸Ñ Ð¸ опеÑаÑÐ¾Ñ await , как показано вÑÑе, или иÑполÑзоваÑÑ Ñип Promise непоÑÑедÑÑвенно, пÑÐ¸Ð¼ÐµÑ Ð½Ð¸Ð¶Ðµ.
ÐапÑÑка заÑ
ваÑа Ñ ÑкÑана: в ÑÑиле Promise
function startCapture(displayMediaOptions) {
let captureStream = null;
return navigator.mediaDevices
.getDisplayMedia(displayMediaOptions)
.catch((err) => {
console.error("Error:" + err);
return null;
});
}
РлÑбом ÑлÑÑае user agent оÑвеÑиÑÑ Ð¾ÑобÑажением инÑеÑÑейÑа диалога, запÑаÑиваÑÑий Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ ÑÐ°Ð·Ð¼ÐµÑ Ð¾Ð±Ð»Ð°ÑÑи заÑ
ваÑа ÑкÑана. Ðбе ÑеализаÑии ÑÑнкÑии startCapture() возвÑаÑаÑÑ Ð¾Ð±ÑÐµÐºÑ Ñипа MediaStream , ÑодеÑжаÑий заÑ
ваÑенное Ñ ÑкÑана изобÑажение (ÑÑÑÐ¼ÐºÑ ?).
СмоÑÑим Options and constraints, ниже, подÑобнее о Ñом, как ÑказаÑÑ Ð¶ÐµÐ»Ð°ÐµÐ¼Ñй Ñип повеÑÑ Ð½Ð¾ÑÑи, а Ñакже о дÑÑÐ³Ð¸Ñ ÑпоÑÐ¾Ð±Ð°Ñ Ð½Ð°ÑÑÑойки ÑезÑлÑÑиÑÑÑÑего поÑока.
ÐÑÐ¸Ð¼ÐµÑ Ð¾ÐºÐ½Ð°, позволÑÑÑего полÑзоваÑÐµÐ»Ñ Ð²ÑбÑаÑÑ Ð¿Ð¾Ð²ÐµÑÑ Ð½Ð¾ÑÑÑ Ð´Ð¸ÑÐ¿Ð»ÐµÑ Ð´Ð»Ñ Ð·Ð°Ñ Ð²Ð°Ñа
ÐаÑем можно иÑполÑзоваÑÑ Ð·Ð°Ñ
ваÑеннÑй поÑок captureStream, везде, где пÑинимаеÑÑÑ Ñип поÑока в каÑеÑÑве вÑ
однÑÑ
паÑамеÑÑов. ÐÑÐ¸Ð¼ÐµÑ examples ниже показÑÐ²Ð°ÐµÑ Ð½ÐµÑколÑко ÑпоÑобов иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð»ÑÑенного Ñипа поÑока
ÐидимÑе или логиÑеÑкие повеÑÑ Ð½Ð¾ÑÑи оÑобÑажениÑ
ÐÐ»Ñ Ñелей инÑеÑÑейÑа Screen Capture API, повеÑÑ Ð½Ð¾ÑÑÑ Ð¾ÑобÑÐ°Ð¶ÐµÐ½Ð¸Ñ - ÑÑо лÑбой обÑÐµÐºÑ ÐºÐ¾Ð½ÑенÑа, коÑоÑÑй Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð²ÑбÑан API Ð´Ð»Ñ Ñелей ÑовмеÑÑного (обÑего) иÑполÑзованиÑ.ÐовеÑÑ Ð½Ð¾ÑÑи обÑего доÑÑÑпа вклÑÑаÑÑ Ð² ÑÐµÐ±Ñ ÑодеÑжимое вкладки бÑаÑзеÑа, полное окно, вÑе пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¾ÐºÐ½Ð°, обÑединÑннÑе в Ð¾Ð´Ð½Ñ Ð¿Ð¾Ð²ÐµÑÑ Ð½Ð¾ÑÑÑ, и мониÑÐ¾Ñ (или гÑÑÐ¿Ð¿Ñ Ð¼Ð¾Ð½Ð¸ÑоÑов, обÑединÑннÑÑ Ð² Ð¾Ð´Ð½Ñ Ð¿Ð¾Ð²ÐµÑÑ Ð½Ð¾ÑÑÑ).
ÐÑÑÑ Ð´Ð²Ð° Ñипа повеÑÑ Ð½Ð¾ÑÑи диÑплеÑ. ÐÐ¸Ð´Ð¸Ð¼Ð°Ñ Ð¿Ð¾Ð²ÐµÑÑ Ð½Ð¾ÑÑÑ Ð¾ÑобÑÐ°Ð¶ÐµÐ½Ð¸Ñ - ÑÑо повеÑÑ Ð½Ð¾ÑÑÑ, коÑоÑÐ°Ñ Ð¿Ð¾Ð»Ð½Ð¾ÑÑÑÑ Ð²Ð¸Ð´Ð½Ð° на ÑкÑане, напÑимеÑ, пеÑеднее окно или вкладка или веÑÑ ÑкÑан.
ÐогиÑеÑÐºÐ°Ñ Ð¿Ð¾Ð²ÐµÑÑ Ð½Ð¾ÑÑÑ Ð¾ÑобÑÐ°Ð¶ÐµÐ½Ð¸Ñ - ÑÑо повеÑÑ Ð½Ð¾ÑÑÑ, коÑоÑÐ°Ñ ÑаÑÑиÑно или полноÑÑÑÑ ÑкÑÑÑа, либо в некоÑоÑой ÑÑепени пеÑекÑÑваеÑÑÑ Ð´ÑÑгим обÑекÑом, либо полноÑÑÑÑ ÑкÑÑÑÐ°Ñ Ð¸Ð»Ð¸ Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑÑ Ð²Ð½Ðµ ÑкÑана. ÐÑи повеÑÑ Ð½Ð¾ÑÑи обÑабаÑÑваÑÑÑÑ Ð¿Ð¾ дÑÑгомÑ. Ðак пÑавило, бÑаÑÐ·ÐµÑ Ð¿ÑедоÑÑавлÑÐµÑ Ð¸Ð·Ð¾Ð±Ñажение, коÑоÑое каким-Ñо обÑазом ÑкÑÑÐ²Ð°ÐµÑ ÑкÑÑÑÑÑ ÑаÑÑÑ Ð¿Ð¾Ð²ÐµÑÑ Ð½Ð¾ÑÑи логиÑеÑкого диÑплеÑ, напÑÐ¸Ð¼ÐµÑ ÑазмÑÑие или замена ÑвеÑом или ÑиÑÑнком. ÐÑо Ñделано из ÑообÑажений безопаÑноÑÑи, поÑколÑÐºÑ ÐºÐ¾Ð½ÑенÑ, коÑоÑÑй не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿ÑоÑмоÑÑен полÑзоваÑелем, Ð¼Ð¾Ð¶ÐµÑ ÑодеÑжаÑÑ Ð´Ð°Ð½Ð½Ñе, коÑоÑÑми они не Ñ Ð¾ÑÑÑ Ð´ÐµÐ»Ð¸ÑÑÑÑ.
ÐÑаÑÐ·ÐµÑ Ð¼Ð¾Ð¶ÐµÑ ÑазÑеÑиÑÑ Ð·Ð°Ñ Ð²Ð°Ñ Ð²Ñего ÑодеÑжимого ÑкÑÑÑого окна поÑле полÑÑÐµÐ½Ð¸Ñ ÑазÑеÑÐµÐ½Ð¸Ñ Ð¾Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð½Ð° ÑÑо. Ð ÑÑом ÑлÑÑае бÑаÑÐ·ÐµÑ Ð¼Ð¾Ð¶ÐµÑ ÑодеÑжаÑÑ Ð·Ð°ÑÑÑÑваннÑй конÑенÑ, либо пÑÑÑм полÑÑÐµÐ½Ð¸Ñ ÑекÑÑего ÑодеÑжимого ÑкÑÑÑой ÑаÑÑи окна, либо пÑÑÑм пÑедоÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ñамого поÑледнего видимого ÑодеÑжимого, еÑли ÑекÑÑее ÑодеÑжимое недоÑÑÑпно.
СвойÑÑва и огÑаниÑениÑ
ÐбÑÐµÐºÑ Ð¾Ð³ÑаниÑений, пеÑедаÑÑийÑÑ Ð² меÑод getDisplayMedia() ÑвлÑеÑÑÑ Ð¾Ð±ÑекÑом Ñипа DisplayMediaStreamConstraints , коÑоÑÑй иÑполÑзÑеÑÑÑ Ð´Ð»Ñ ÐºÐ¾Ð½ÑигÑÑаÑии полÑÑаемого обÑекÑа поÑока.
ÐÑимеÑание: РоÑлиÑие Ð¾Ñ Ð±Ð¾Ð»ÑÑинÑÑва пÑименений огÑаниÑений в медиа-API, здеÑÑ Ð¾Ð½ иÑполÑзÑеÑÑÑ Ð¸ÑклÑÑиÑелÑно Ð´Ð»Ñ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ ÐºÐ¾Ð½ÑигÑÑаÑии поÑока, а не Ð´Ð»Ñ ÑилÑÑÑаÑии доÑÑÑпнÑÑ Ð²Ð°ÑианÑов.
СÑÑеÑÑвÑÑÑ ÑÑи новÑÑ
огÑаниÑениÑ, добавленнÑе в обÑÐµÐºÑ Ñипа MediaTrackConstraints (а Ñак же в MediaTrackSupportedConstraints и MediaTrackSettings) Ð´Ð»Ñ ÐºÐ¾Ð½ÑигÑÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ñока заÑ
ваÑа ÑкÑана:
cursor-
УказÑваеÑ, ÑледÑÐµÑ Ð»Ð¸ Ð·Ð°Ñ Ð²Ð°ÑÑваÑÑ ÐºÑÑÑÐ¾Ñ Ð¼ÑÑи и, еÑли да, делаÑÑ ÑÑо поÑÑоÑнно или ÑолÑко во вÑÐµÐ¼Ñ Ð´Ð²Ð¸Ð¶ÐµÐ½Ð¸Ñ Ð¼ÑÑи. ÐозможнÑе знаÑениÑ:
always-
(вÑегда) ÐÑÑÑÐ¾Ñ Ð¼ÑÑи вÑегда Ð·Ð°Ñ Ð²Ð°ÑÑваеÑÑÑ Ð² ÑезÑлÑÑиÑÑÑÑий поÑок.
motion-
(в движении) ÐÑÑÑÐ¾Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ бÑÑÑ Ð²Ð¸Ð´Ð¸Ð¼Ñм пÑи его движении, и (на ÑÑмоÑÑение user agent ) на коÑоÑкое вÑÐµÐ¼Ñ Ð´Ð¾ и поÑле движениÑ. Рпокое кÑÑÑÐ¾Ñ ÑдалÑеÑÑÑ Ð¸Ð· поÑока.
never-
(никогда) ÐÑÑÑÐ¾Ñ Ð½Ðµ поÑвлÑеÑÑÑ Ð² ÑезÑлÑÑиÑÑÑÑем поÑоке..
logicalSurface-
Тип
Boolean, пÑи иÑÑинном знаÑении опÑеделÑеÑ, ÑÑо Ð·Ð°Ñ Ð²Ð°Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ вклÑÑаÑÑ Ð¾Ð±Ð»Ð°ÑÑÑ Ð·Ð° пÑеделами ÑкÑана, еÑли имееÑÑÑ.
Ðи одно из огÑаниÑений никак не пÑименÑеÑÑÑ Ð´Ð¾ ÑÐµÑ Ð¿Ð¾Ñ, пока не бÑÐ´ÐµÑ Ð²ÑбÑан конÑÐµÐ½Ñ Ð´Ð»Ñ Ð·Ð°Ñ Ð²Ð°Ñа. ÐгÑаниÑÐµÐ½Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÑÑÑ Ñо, ÑÑо Ð²Ñ Ð²Ð¸Ð´Ð¸Ñе в полÑÑенном поÑоке
РпÑимеÑÑ, еÑли опÑеделиÑÑ Ð¾Ð³ÑаниÑение width Ð´Ð»Ñ Ð²Ð¸Ð´ÐµÐ¾, оно пÑимениÑÑÑ ÐºÐ°Ðº маÑÑÑабиÑование видео, поÑле Ñого, как полÑзоваÑÐµÐ»Ñ Ð²ÑбеÑÐµÑ Ð¾Ð±Ð»Ð°ÑÑÑ, и не ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð¾Ð³ÑаниÑение на ÑÐ°Ð·Ð¼ÐµÑ Ñамого иÑÑоÑника.
ÐÑимеÑание: ÐгÑаниÑÐµÐ½Ð¸Ñ Ð½Ð¸ÐºÐ¾Ð³Ð´Ð° не вÑзÑваÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ в ÑпиÑке иÑÑоÑников, доÑÑÑпнÑÑ Ð´Ð»Ñ Ð·Ð°Ñ Ð²Ð°Ñа API Sharing Screen. ÐÑо гаÑанÑиÑÑеÑ, ÑÑо веб-пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð½Ðµ могÑÑ Ð·Ð°ÑÑавиÑÑ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð´ÐµÐ»Ð¸ÑÑÑÑ Ð¾Ð¿ÑеделÑннÑм конÑенÑом, огÑаниÑÐ¸Ð²Ð°Ñ Ð¸ÑÑ Ð¾Ð´Ð½Ñй ÑпиÑок, пока не оÑÑанеÑÑÑ ÑолÑко один ÑлеменÑ.
РпÑоÑеÑÑе Ð·Ð°Ñ Ð²Ð°Ñа ÑкÑана маÑина, коÑоÑÐ°Ñ Ð¾Ð±Ð¼ÐµÐ½Ð¸Ð²Ð°ÐµÑÑÑ ÑодеÑжимÑм ÑкÑана, бÑÐ´ÐµÑ Ð¾ÑобÑажаÑÑ ÐºÐ°ÐºÑÑ-Ñо ÑоÑÐ¼Ñ Ð¸Ð½Ð´Ð¸ÐºÐ°ÑоÑа, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð·Ð½Ð°Ð», ÑÑо обмен Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑÑ Ð² пÑоÑеÑÑе.
ÐÑимеÑание:
Ðз ÑообÑажений конÑиденÑиалÑноÑÑи и безопаÑноÑÑи иÑÑоÑники ÑовмеÑÑного иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑкÑана не пеÑеÑиÑлÑÑÑÑÑ Ñ Ð¸ÑполÑзованием меÑода enumerateDevices(). Ðо Ñой-же пÑиÑине, ÑобÑÑие devicechange никогда не вÑзÑваеÑÑÑ, когда еÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² доÑÑÑпнÑÑ
иÑÑоÑникаÑ
пÑи вÑполнении getDisplayMedia().
ÐÐ°Ñ Ð²Ð°Ñ Ð¿ÐµÑедаваемого аÑдио
ÐеÑод getDisplayMedia() в оÑновном иÑполÑзÑеÑÑÑ Ð´Ð»Ñ Ð·Ð°Ñ
ваÑа видео полÑзоваÑелÑÑкого ÑкÑана или его ÑаÑÑи. Ðднако user agents Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð·Ð²Ð¾Ð»Ð¸ÑÑ Ð·Ð°Ñ
ваÑиÑÑ Ð°Ñдио вмеÑÑе Ñ Ð²Ð¸Ð´ÐµÐ¾ конÑенÑом. ÐÑÑоÑником аÑдио Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð²ÑбÑанное окно, вÑÑ Ð°Ñдио ÑиÑÑема компÑÑÑеÑа, или полÑзоваÑелÑÑкий микÑоÑон (или иÑ
комбинаÑиÑ) .
Ðо запÑÑка ÑкÑипÑа, коÑоÑÑй бÑÐ´ÐµÑ Ð·Ð°Ð¿ÑаÑиваÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ Ð¾Ð±Ð¼ÐµÐ½Ð° аÑдио, пÑовеÑÑÑе ÑеализаÑÐ¸Ñ Browser compatibility, Ð´Ð»Ñ Ð¿Ð¾Ð½Ð¸Ð¼Ð°Ð½Ð¸Ñ Ð±ÑаÑзеÑной ÑовмеÑÑимоÑÑи Ñ ÑÑнкÑионалÑноÑÑÑÑ Ð·Ð°Ñ Ð²Ð°Ñа аÑдио в поÑок Ð·Ð°Ñ Ð²Ð°Ñа ÑкÑана.
ЧÑÐ¾Ð±Ñ Ð·Ð°Ð¿ÑоÑиÑÑ Ð´Ð¾ÑÑÑп к ÑкÑÐ°Ð½Ñ Ñ Ð²ÐºÐ»ÑÑÑннÑм звÑком, паÑамеÑÑÑ Ð½Ð¸Ð¶Ðµ пеÑедаÑÑÑÑ Ð² меÑод getDisplayMedia():
const gdmOptions = {
video: true,
audio: true,
};
ÐÑо даÑÑ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð¿Ð¾Ð»Ð½ÑÑ ÑÐ²Ð¾Ð±Ð¾Ð´Ñ Ð²ÑбоÑа Ñого, ÑÑо он Ñ
оÑеÑ, в пÑеделаÑ
Ñого, ÑÑо поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¿Ð¾Ð»ÑзоваÑелÑÑкий агенÑ. ÐÑо можно ÑÑоÑниÑÑ, Ñказав дополниÑелÑнÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ ÑвойÑÑва audio и video:
const gdmOptions = {
video: {
cursor: "always",
},
audio: {
echoCancellation: true,
noiseSuppression: true,
sampleRate: 44100,
},
};
Ð ÑÑом пÑимеÑе кÑÑÑÐ¾Ñ Ð²Ñегда бÑÐ´ÐµÑ Ð²Ð¸Ð´ÐµÐ½ пÑи Ð·Ð°Ñ Ð²Ð°Ñе, и на звÑковой доÑожке в идеале Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð²ÐºÐ»ÑÑÐµÐ½Ñ ÑÑнкÑии Ð¿Ð¾Ð´Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÑÑма и ÑÑ Ð¾Ð¿Ð¾Ð´Ð°Ð²Ð»ÐµÐ½Ð¸Ñ, а Ñакже идеалÑÐ½Ð°Ñ ÑаÑÑоÑа диÑкÑеÑизаÑии звÑка 44,1 кÐÑ
ÐаÑ
Ð²Ð°Ñ Ð°Ñдио вÑегда необÑзаÑелен, и даже когда веб-конÑÐµÐ½Ñ Ð·Ð°Ð¿ÑаÑÐ¸Ð²Ð°ÐµÑ Ð¿Ð¾Ñок Ñ Ð°Ñдио и видео, возвÑаÑаемÑй MediaStream Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾-пÑÐµÐ¶Ð½ÐµÐ¼Ñ Ð¸Ð¼ÐµÑÑ ÑолÑко Ð¾Ð´Ð½Ñ Ð²Ð¸Ð´ÐµÐ¾Ð´Ð¾ÑÐ¾Ð¶ÐºÑ Ð±ÐµÐ· звÑка.
ÐÑимеÑание:
ÐекоÑоÑÑе ÑвойÑÑва не ÑÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ñ ÑиÑоко и могÑÑ Ð½Ðµ иÑполÑзоваÑÑÑÑ Ð´Ð²Ð¸Ð¶ÐºÐ¾Ð¼. РпÑимеÑÑ, cursor Ð¸Ð¼ÐµÐµÑ Ð¾Ð³ÑаниÑеннÑÑ Ð¿Ð¾Ð´Ð´ÐµÑжкÑ.
Using the captured stream
The Promise returned by getDisplayMedia() resolves to a MediaStream that contains at least one video stream that contains the screen or screen area, and which is adjusted or filtered based upon the constraints specifed when getDisplayMedia() was called.
Potential risks
Privacy and security issues surrounding screen sharing are usually not overly serious, but they do exist. The largest potential issue is users inadvertently sharing content they did not wish to share.
For example, privacy and/or security violations can easily occur if the user is sharing their screen and a visible background window happens to contain personal information, or if their password manager is visible in the shared stream. This effect can be amplified when capturing logical display surfaces, which may contain content that the user doesn't know about at all, let alone see.
User agents which take privacy seriously should obfuscate content that is not actually visible onscreen, unless authorization has been given to share that content specifically.
Authorizing capture of display contents
Before streaming of captured screen contents can begin, the user agent will ask the user to confirm the sharing request, and to select the content to share.
Examples
>Simple screen capture
In this example, the contents of the captured screen area are simply streamed into a <video> element on the same page.
JavaScript
There isn't all that much code needed in order to make this work, and if you're familiar with using getUserMedia() to capture video from a camera, you'll find getDisplayMedia() to be very familiar.
Setup
First, some constants are set up to reference the elements on the page to which we'll need access: the <video> into which the captured screen contents will be streamed, a box into which logged output will be drawn, and the start and stop buttons that will turn on and off capture of screen imagery.
The object displayMediaOptions contains the MediaStreamConstraints to pass into getDisplayMedia(); here, the cursor property is set to always, indicating that the mouse cursor should always be included in the captured media.
ÐÑимеÑание:
Some properties are not widely implemented and might not be used by the engine. cursor, for example, has limited support.
Finally, event listeners are established to detect user clicks on the start and stop buttons.
const videoElem = document.getElementById("video");
const logElem = document.getElementById("log");
const startElem = document.getElementById("start");
const stopElem = document.getElementById("stop");
// Options for getDisplayMedia()
var displayMediaOptions = {
video: {
cursor: "always",
},
audio: false,
};
// Set event listeners for the start and stop buttons
startElem.addEventListener(
"click",
function (evt) {
startCapture();
},
false,
);
stopElem.addEventListener(
"click",
function (evt) {
stopCapture();
},
false,
);
Logging content
To make logging of errors and other issues easy, this example overrides certain Console methods to output their messages to the <pre> block whose ID is log.
console.log = (msg) => (logElem.innerHTML += `${msg}<br>`);
console.error = (msg) =>
(logElem.innerHTML += `<span class="error">${msg}</span><br>`);
console.warn = (msg) =>
(logElem.innerHTML += `<span class="warn">${msg}<span><br>`);
console.info = (msg) =>
(logElem.innerHTML += `<span class="info">${msg}</span><br>`);
This allows us to use the familiar console.log(), console.error(), and so on to log information to the log box in the document.
Starting display capture
The startCapture() method, below, starts the capture of a MediaStream whose contents are taken from a user-selected area of the screen. startCapture() is called when the "Start Capture" button is clicked.
async function startCapture() {
logElem.innerHTML = "";
try {
videoElem.srcObject =
await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
dumpOptionsInfo();
} catch (err) {
console.error("Error: " + err);
}
}
After clearing the contents of the log in order to get rid of any leftover text from the previous attempt to connect, startCapture() calls getDisplayMedia(), passing into it the constraints object defined by displayMediaOptions. Using await, the following line of code does not get executed until after the Promise returned by getDisplayMedia() resolves. Upon resolution, the promise returns a MediaStream, which will stream the contents of the screen, window, or other region selected by the user.
The stream is connected to the <video> element by storing the returned MediaStream into the element's srcObject.
The dumpOptionsInfo() functionâwhich we will look at in a momentâdumps information about the stream to the log box for educational purposes.
If any of that fails, the catch() clause outputs an error message to the log box.
Stopping display capture
The stopCapture() method is called when the "Stop Capture" button is clicked. It stops the stream by getting its track list using MediaStream.getTracks(), then calling each track's {domxref("MediaStreamTrack.stop, "stop()")}} method. Once that's done, srcObject is set to null to make sure it's understood by anyone interested that there's no stream connected.
function stopCapture(evt) {
let tracks = videoElem.srcObject.getTracks();
tracks.forEach((track) => track.stop());
videoElem.srcObject = null;
}
Dumping configuration information
For informational purposes, the startCapture() method shown above calls a method named dumpOptions(), which outputs the current track settings as well as the consrtaints that were placed upon the stream when it was created.
function dumpOptionsInfo() {
const videoTrack = videoElem.srcObject.getVideoTracks()[0];
console.info("Track settings:");
console.info(JSON.stringify(videoTrack.getSettings(), null, 2));
console.info("Track constraints:");
console.info(JSON.stringify(videoTrack.getConstraints(), null, 2));
}
The track list is obtained by calling getVideoTracks() on the capture'd screen's MediaStream. The settings currentoly in effect are obtained using getSettings() and the established constraints are gotten with getConstraints()
HTML
The HTML starts with a simple introductory paragraph, then gets into the meat of things.
<p>
This example shows you the contents of the selected part of your display.
Click the Start Capture button to begin.
</p>
<p>
<button id="start">Start Capture</button> <button id="stop">
Stop Capture
</button>
</p>
<video id="video" autoplay></video>
<br />
<strong>Log:</strong>
<br />
<pre id="log"></pre>
The key parts of the HTML are:
- A
<button>labeled "Start Capture" which, when clicked, calls thestartCapture()function to request access to, and begin capturing, screen contents. - A second button, "Stop Capture", which upon being clicked calls
stopCapture()to terminate capture of screen contents. - A
<video>into which the captured screen contents are streamed. - A
<pre>block into which logged text is placed by the interceptedConsolemethod.
CSS
The CSS is entirely cosmetic in this example. The video is given a border, and its width is set to occupy nearly the entire available horizontal space (width: 98%). max-width is set to 860px to set an absolute upper limit on the video's size,
The error, warn, and info classes are used to style the corresponding console output types.
#video {
border: 1px solid #999;
width: 98%;
max-width: 860px;
}
.error {
color: red;
}
.warn {
color: orange;
}
.info {
color: darkgreen;
}
Result
The final product looks like this. If your browser supports Screen Capture API, clicking "Start Capture" will present the user agent's interface for selecting a screen, window, or tab to share.
Security
In order to function when Feature Policy is enabled, you will need the display-capture permission. This can be done using the Feature-Policy HTTP header orâif you're using the Screen Capture API in an <iframe>, the <iframe> element's allow attribute.
For example, this line in the HTTP headers will enable Screen Capture API for the document and any embedded <iframe> elements that are loaded from the same origin:
Feature-Policy: display-capture 'self'
If you're performing screen capture within an <iframe>, you can request permission just for that frame, which is clearly more secure than requesting a more general permission:
<iframe src="https://mycode.example.net/etc" allow="display-capture"> </iframe>
СмоÑÑиÑе Ñакже
- Screen Capture API
- Media Capture and Streams API
- Taking still photos with WebRTC
HTMLCanvasElement.captureStream()to obtain aMediaStreamwith the live contents of a<canvas>
