From 55ddd4454665a3c66e3d5b186bc79048468d36e7 Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Mon, 15 Mar 2021 14:29:50 +0300 Subject: Auto fixes --- files/ru/web/api/webrtc_api/adapter.js/index.html | 4 ++-- files/ru/web/api/webrtc_api/index.html | 10 +++++----- files/ru/web/api/webrtc_api/session_lifetime/index.html | 8 ++++---- .../webrtc_api/signaling_and_video_calling/index.html | 4 ++-- .../webrtc_api/simple_rtcdatachannel_sample/index.html | 4 ++-- .../ru/web/api/webrtc_api/taking_still_photos/index.html | 16 ++++++++-------- .../ru/web/api/webrtc_api/using_data_channels/index.html | 6 +++--- 7 files changed, 26 insertions(+), 26 deletions(-) (limited to 'files/ru/web/api/webrtc_api') diff --git a/files/ru/web/api/webrtc_api/adapter.js/index.html b/files/ru/web/api/webrtc_api/adapter.js/index.html index 97e09d25e2..efe5581fc2 100644 --- a/files/ru/web/api/webrtc_api/adapter.js/index.html +++ b/files/ru/web/api/webrtc_api/adapter.js/index.html @@ -7,7 +7,7 @@ translation_of: Web/API/WebRTC_API/adapter.js ---

{{WebRTCSidebar}}

-

Несмотря на то, что WebRTC спецификация относительно стабильна, не все еще браузеры полностью реализуют её функциональность. Некоторые реализации в браузерах все еще содержат префексы производителей в некоторых, или даже всех WebRTC интерфейсах, и разработчик может самостоятельно, в ручную, учесть вопросы несовместимости в своем коде. Но есть более простой выход. Организация WebRTC предлагает библиотеку adapter.js для обработки вопросов несовместимостей в различных браузерных реализациях WebRTC. Эта библиотека является JavaScript клином, позволяющим писать код в соответствии со спецификацией, чтобы он работал во всех браузерах с различным уровнем поддержки WebRTC. С ней нет необходимости условно использовать префиксные интерфейсы или реализовывать обходные пути

+

Несмотря на то, что WebRTC спецификация относительно стабильна, не все еще браузеры полностью реализуют её функциональность. Некоторые реализации в браузерах все еще содержат префиксы производителей в некоторых, или даже всех WebRTC интерфейсах, и разработчик может самостоятельно, в ручную, учесть вопросы несовместимости в своем коде. Но есть более простой выход. Организация WebRTC предлагает библиотеку adapter.js для обработки вопросов несовместимостей в различных браузерных реализациях WebRTC. Эта библиотека является JavaScript клином, позволяющим писать код в соответствии со спецификацией, чтобы он работал во всех браузерах с различным уровнем поддержки WebRTC. С ней нет необходимости условно использовать префиксные интерфейсы или реализовывать обходные пути

Примечание : Поскольку функциональность и названия API-терминов в WebRTC и поддерживаемых браузерах постоянно изменяются, обычно рекомендуется использовать этот адаптер.

@@ -17,7 +17,7 @@ translation_of: Web/API/WebRTC_API/adapter.js

Как работает adapter.js

-

Для каждой версии  браузера, поддерживающего WebRTC, adapter.js реализует необходимые полизаполнители, устанавливает имена API без префиксов и применяет любые другие изменения, необходимые для того, чтобы браузер выполнял код, в сообтветствии со спецификацией WebRTC.

+

Для каждой версии  браузера, поддерживающего WebRTC, adapter.js реализует необходимые полизаполнители, устанавливает имена API без префиксов и применяет любые другие изменения, необходимые для того, чтобы браузер выполнял код, в соответствии со спецификацией WebRTC.

Например, в версиях Firefox старше 38 адаптер добавляет свойство {{domxref ("RTCPeerConnection.urls")}}; Firefox изначально не поддерживает это свойство до Firefox 38, а в Chrome адаптер добавляет поддержку API {{jsxref ("Promise")}}, если он отсутствует. Это всего лишь пара примеров. Вот в кратце, какие корректировки производит библиотека.

diff --git a/files/ru/web/api/webrtc_api/index.html b/files/ru/web/api/webrtc_api/index.html index 78971cd1df..1c3d082d99 100644 --- a/files/ru/web/api/webrtc_api/index.html +++ b/files/ru/web/api/webrtc_api/index.html @@ -49,7 +49,7 @@ translation_of: Web/API/WebRTC_API
{{domxref("RTCPeerConnectionIceEvent")}}
Представляет события, которые происходят в отношении кандидатов ICE, обычно {{domxref ("RTCPeerConnection")}}. Один тип передается данному объекту события: {{event ("icecandidate")}}.
{{domxref("RTCRtpSender")}}
-
Управляет кродированием и передачей данных через объект типа  {{domxref("MediaStreamTrack")}} для объекта типа {{domxref("RTCPeerConnection")}}.
+
Управляет кодированием и передачей данных через объект типа  {{domxref("MediaStreamTrack")}} для объекта типа {{domxref("RTCPeerConnection")}}.
{{domxref("RTCRtpReceiver")}}
Управляет получением и декодированием данных через объект типа {{domxref("MediaStreamTrack")}} для объекта типа {{domxref("RTCPeerConnection")}}.
{{domxref("RTCTrackEvent")}}
@@ -57,19 +57,19 @@ translation_of: Web/API/WebRTC_API
{{domxref("RTCCertificate")}}
Представляет сертификат, который использует объект {{domxref("RTCPeerConnection")}}.
{{domxref("RTCDataChannel")}}
-
Представляет двунапрвленный канал данных между двумя узлами соединения.
+
Представляет двунаправленный канал данных между двумя узлами соединения.
{{domxref("RTCDataChannelEvent")}}
Представляет события, которые возникают при присоединении объекта типа  {{domxref("RTCDataChannel")}} к объекту типа {{domxref("RTCPeerConnection")}}. Один тип передается этому событию {{event("datachannel")}}.
{{domxref("RTCDTMFSender")}}
-
Управляет кодированием и передачей  двутональной мультичастотной  (DTMF) сигнализацией для объекта типа {{domxref("RTCPeerConnection")}}.
+
Управляет кодированием и передачей  двухтональной мультичастотной  (DTMF) сигнализацией для объекта типа {{domxref("RTCPeerConnection")}}.
{{domxref("RTCDTMFToneChangeEvent")}}
Указывает на входящее событие изменение тона двутоновой мультичастотной сигнализации  (DTMF). Это событие не всплывает (если не указано иначе) и не является отменяемым (если не указано иначе).
{{domxref("RTCStatsReport")}}
-
Ассинхронно сообщает статус для переданного объекта типа  {{domxref("MediaStreamTrack")}} .
+
Асинхронно сообщает статус для переданного объекта типа  {{domxref("MediaStreamTrack")}} .
{{domxref("RTCIdentityProviderRegistrar")}}
Регистрирует провайдер идентификации (idP).
{{domxref("RTCIdentityProvider")}}
-
Активирует возможность браузеру запросить создание или проверку обяъвления идентификации.
+
Активирует возможность браузеру запросить создание или проверку объявления идентификации.
{{domxref("RTCIdentityAssertion")}}
Представляет идентификатор удаленного узла текущего соединения. Если узел еще не установлен и подтвержден, ссылка на интерфейс вернет null. После установки не изменяется.
{{domxref("RTCIdentityEvent")}}
diff --git a/files/ru/web/api/webrtc_api/session_lifetime/index.html b/files/ru/web/api/webrtc_api/session_lifetime/index.html index 958fd99136..0b052b5475 100644 --- a/files/ru/web/api/webrtc_api/session_lifetime/index.html +++ b/files/ru/web/api/webrtc_api/session_lifetime/index.html @@ -11,7 +11,7 @@ translation_of: Web/API/WebRTC_API/Session_lifetime
-

Эта статья не вдается в детали фактически использованных API в установке и обработке WebRTC-соединения. Это просто обзор процесса вцелом с некоторой информацией о том, для чего нужен каждый шаг. Смотрите статью Signaling and video calling, чтобы получить пример с пошаговым объяснением того, что делает код.

+

Эта статья не вдается в детали фактически использованных API в установке и обработке WebRTC-соединения. Это просто обзор процесса в целом с некоторой информацией о том, для чего нужен каждый шаг. Смотрите статью Signaling and video calling, чтобы получить пример с пошаговым объяснением того, что делает код.

Эта страница находится в стадии разработки, и некоторое из содержания будут перемещаться на другие страницы, как направляющий материал. 

@@ -23,7 +23,7 @@ translation_of: Web/API/WebRTC_API/Session_lifetime

Интернет большой. Реально большой. Умные люди, несколько лет назад, заметив то, насколько он велик, каким большим он может стать и то как быстро растёт, а также ограничения 32-битной системы адресации протокола IP, и поняли, что нужно начать что-то делать, чтобы создать новую 64-битную систему адресации. Но в какой-то момент они так же пришли к выводу, что переход на новую систему займёт больше времени, чем продержатся 32-разрядные адреса. Затем другие умные люди придумали способ, позволяющий нескольким компьютерам использовать один и тот же 32-итный IP-адрес. Network Address Translation ({{Glossary("NAT")}}) - это стандарт, который поддерживает разделение адреса путем маршрутизации входящих и исходящих пакетов данных в и из локальной сети (LAN), которые разделяют единственный WAN (глобальный) адрес.

-

Проблемой для пользователя является то, что каждый отдельный компьютер в сети Интернет не обязан иметь уникальный IP-адрес, и посути, IP-адрес устройства может измениться не только тогда, когда оно перемещяется из одной сети в другую, но и если их сетевой адрес был изменён {{Glossary("NAT")}} и/или {{interwiki("wikipedia", "DHCP")}}. Для разработчиков, пытающихся строить одноранговые сети, эта ситуация является хорошей головоломкой: без уникального идентификатора для каждого устройства, нет возможности моментально автоматически выяснить то, как подключиться к конкретному устройству в Интернет.  Если вызнаете, с кем вы хотите поговорить, вам не обязательно знать, какой адрес у вашего собеседника.

+

Проблемой для пользователя является то, что каждый отдельный компьютер в сети Интернет не обязан иметь уникальный IP-адрес, и по сути, IP-адрес устройства может измениться не только тогда, когда оно перемещается из одной сети в другую, но и если их сетевой адрес был изменён {{Glossary("NAT")}} и/или {{interwiki("wikipedia", "DHCP")}}. Для разработчиков, пытающихся строить одноранговые сети, эта ситуация является хорошей головоломкой: без уникального идентификатора для каждого устройства, нет возможности моментально автоматически выяснить то, как подключиться к конкретному устройству в Интернет.  Если вызнаете, с кем вы хотите поговорить, вам не обязательно знать, какой адрес у вашего собеседника.

Это похоже на попытку отправить письмо подруге Мишель, написав только на конверте слово "Мишель" и опустить в почтовый ящик. Вам необходимо выяснить её адрес и указать его на конверте, иначе она сильно удивится, почему вы забыли про её день рождения.

@@ -31,7 +31,7 @@ translation_of: Web/API/WebRTC_API/Session_lifetime

Процесс Сигнализации

-

Сигнализация - это процесс передачи управляющей информации между двумя устройствами для опредения протоколов связи, каналов, кодирования и формата медиа-данных,  методов передачи данных, а также информации, необходимой для маршрутизации. Наиболее важная вещь, о которой нужно знать о процессе сигнализации для WebRTC - этот процесс не определен в спецификации.

+

Сигнализация - это процесс передачи управляющей информации между двумя устройствами для определения протоколов связи, каналов, кодирования и формата медиа-данных,  методов передачи данных, а также информации, необходимой для маршрутизации. Наиболее важная вещь, о которой нужно знать о процессе сигнализации для WebRTC - этот процесс не определен в спецификации.

Вы можете задаться вопросом, почему нечто основоположное для процесса установки WebRTC-соединения вынесено из спецификации? Ответ прост: потому как два устройства не могут контактировать друг с другом, и спецификация не может предусмотреть все возможные способы использования WebRTC, также это приобретает ещё больший смысл с точки зрения предоставления разработчику возможности выбора наиболее подходящей сетевой технологии и протоколов передачи сообщений.

@@ -46,7 +46,7 @@ translation_of: Web/API/WebRTC_API/Session_lifetime

Только после успешного завершения процесса сигнализации, может быть возможен процесс открытия WebRTC-соединения между узлами.

diff --git a/files/ru/web/api/webrtc_api/signaling_and_video_calling/index.html b/files/ru/web/api/webrtc_api/signaling_and_video_calling/index.html index 4c4f7ea418..844c8e0d19 100644 --- a/files/ru/web/api/webrtc_api/signaling_and_video_calling/index.html +++ b/files/ru/web/api/webrtc_api/signaling_and_video_calling/index.html @@ -1,5 +1,5 @@ --- -title: Сигнализирование и видео вызов +title: Сигнализированные и видео вызов slug: Web/API/WebRTC_API/Signaling_and_video_calling translation_of: Web/API/WebRTC_API/Signaling_and_video_calling --- @@ -23,7 +23,7 @@ translation_of: Web/API/WebRTC_API/Signaling_and_video_calling

Важно, что серверу не нужно понимать или интерпретировать сигнальные данные. Хотя они в формате {{Glossary("SDP")}}, это не имеет особого значения: содержание сообщений, проходящих через сигнальный сервер - по сути, черный ящик. Значение имеет лишь то, что когда подсистема {{Glossary("ICE")}} дает команду передать данные другому пиру, вы просто это делаете, а уже пир знает, как получить эту информацию и доставить ее на свою подсистему ICE. Все что нужно - передавать сообщения туда и обратно. Содержание совершенно не важно для сигнального сервера.

-

Подготовка сервера чата к сигнализиции

+

Подготовка сервера чата к сигнализации

Наш сервер чата использует WebSocket API для отправки информации как {{Glossary("JSON")}}  между каждым клиентом и сервером. Сервер поддерживает несколько типов сообщений для нескольких задач : регистрация нового пользователя, установки имен пользователей, отправка сообщений чата.

diff --git a/files/ru/web/api/webrtc_api/simple_rtcdatachannel_sample/index.html b/files/ru/web/api/webrtc_api/simple_rtcdatachannel_sample/index.html index 5d818e7829..4d02e4d5d4 100644 --- a/files/ru/web/api/webrtc_api/simple_rtcdatachannel_sample/index.html +++ b/files/ru/web/api/webrtc_api/simple_rtcdatachannel_sample/index.html @@ -5,7 +5,7 @@ translation_of: Web/API/WebRTC_API/Simple_RTCDataChannel_sample ---

{{WebRTCSidebar}}

-

Интерфейс {{domxref("RTCDataChannel")}} является функциональностью  WebRTC API , который позволяет открыть канал между узлами соединения, по которому можно отправлять и получать произвольные данные. Эти  API намеренно сходны с  WebSocket API, для использования единой програмной модели.

+

Интерфейс {{domxref("RTCDataChannel")}} является функциональностью  WebRTC API , который позволяет открыть канал между узлами соединения, по которому можно отправлять и получать произвольные данные. Эти  API намеренно сходны с  WebSocket API, для использования единой программной модели.

В этом примере мы откроем соединение {{domxref ("RTCDataChannel")}}, связывающее два элемента на одной странице. Хотя это явно надуманный сценарий, он полезен для демонстрации последовательности соединения двух узлов. Мы расскажем о механизме выполнения соединения, передачи и получения данных, но оставим немного информации о поиске и подключении к удаленному компьютеру для другого примера.

@@ -20,7 +20,7 @@ translation_of: Web/API/WebRTC_API/Simple_RTCDataChannel_sample   Disconnect </button> -

Затем, определяем блок, который содержит элемент управления ввода текста, в который пользователь печатает текст свого сообщения, предназначенного для отправки, по нажатию кнопки. Элемент {{HTMLElement("div")}} будет представлять первый узлел в канале передачи (сторона отправителя).

+

Затем, определяем блок, который содержит элемент управления ввода текста, в который пользователь печатает текст своего сообщения, предназначенного для отправки, по нажатию кнопки. Элемент {{HTMLElement("div")}} будет представлять первый узел в канале передачи (сторона отправителя).

  <div class="messagebox">
     <label for="message">Enter a message:
diff --git a/files/ru/web/api/webrtc_api/taking_still_photos/index.html b/files/ru/web/api/webrtc_api/taking_still_photos/index.html
index 84c6884cec..cdd65b56e9 100644
--- a/files/ru/web/api/webrtc_api/taking_still_photos/index.html
+++ b/files/ru/web/api/webrtc_api/taking_still_photos/index.html
@@ -7,17 +7,17 @@ translation_of: Web/API/WebRTC_API/Taking_still_photos
 ---
 

{{WebRTCSidebar}}

-

В этой статье объясняется как использовать WebRTC для получения доступа к камере компьютера или мобильного устройства, и захвата кадров с их помощью. Ознакомтесь с примером, а затем узнайте как это работает.

+

В этой статье объясняется как использовать WebRTC для получения доступа к камере компьютера или мобильного устройства, и захвата кадров с их помощью. Ознакомьтесь с примером, а затем узнайте как это работает.

Uz WebRTC balstīta attēla uztveršanas lietotne - kreisajā pusē un bez tīmekļa kameras uzņemšanas video straumē un poga

-

Перейдите непостредственно к коду на Github , при желании.

+

Перейдите непосредственно к коду на Github , при желании.

Разметка HTML

Наш HTML интерфейс состоит из двух секций : панель отображения видео потока, из которого будет производиться захват и панель отображения результата захвата. Каждая панель имеет свой элемент {{HTMLElement ("div")}}, для облегчения стилизации и управления.

-

Первая панель слева содержит два компонента : элемент {{HTMLElement ("video")}} , который будет получать поток, отводимый с камеры, и элемент  {{HTMLElement("button")}}, каторый будет использоваться пользователем для активации захвата видео кадра.

+

Первая панель слева содержит два компонента : элемент {{HTMLElement ("video")}} , который будет получать поток, отводимый с камеры, и элемент  {{HTMLElement("button")}}, который будет использоваться пользователем для активации захвата видео кадра.

  <div class="camera">
     <video id="video">Video stream not available.</video>
@@ -73,7 +73,7 @@ translation_of: Web/API/WebRTC_API/Taking_still_photos
  
photo
Содержит ссылку на элемент  {{HTMLElement("img")}} после загрузки страницы.
startbutton
-
Содержит ссылку на элемент  {{HTMLElement("button")}} после загрузки страницы, используюется для старта захвата.
+
Содержит ссылку на элемент  {{HTMLElement("button")}} после загрузки страницы, используется для старта захвата.

Функция  startup()

@@ -104,9 +104,9 @@ translation_of: Web/API/WebRTC_API/Taking_still_photos });
-

Здесь мы вазываем метод  {{domxref("MediaDevices.getUserMedia()")}} , запрашивая медиапоток без аудиопотока (audio : false). Он возвращает промис, на котором мы определяем методы успешного и не успешного выполнений.

+

Здесь мы называем метод  {{domxref("MediaDevices.getUserMedia()")}} , запрашивая медиапоток без аудиопотока (audio : false). Он возвращает промис, на котором мы определяем методы успешного и не успешного выполнений.

-

Успешное выполнение промиса передает объект потока( stream ) в качестве параметра функции метода then()., который присваевается свойству srcObject элемента {{HTMLElement("video")}}, направляя поток в него.

+

Успешное выполнение промиса передает объект потока( stream ) в качестве параметра функции метода then()., который присваивается свойству srcObject элемента {{HTMLElement("video")}}, направляя поток в него.

Как только поток связан с элементом <video> ,  запускаем его воспроизведение, вызовом метода HTMLMediaElement.play().

@@ -167,7 +167,7 @@ translation_of: Web/API/WebRTC_API/Taking_still_photos photo.setAttribute('src', data); }
-

Начнем с получения ссылки на скрытый элемент {{HTMLElement ("canvas")}}, который мы используем для рендеринга за пределами экрана. Затем мы устанавливаем свойсто fillStyle в  #AAA ( светло-серый) и заполняем весь холст этим цветом, вызывая метод {{domxref("CanvasRenderingContext2D.fillRect()","fillRect()")}}.

+

Начнем с получения ссылки на скрытый элемент {{HTMLElement ("canvas")}}, который мы используем для рендеринга за пределами экрана. Затем мы устанавливаем свойство fillStyle в  #AAA ( светло-серый) и заполняем весь холст этим цветом, вызывая метод {{domxref("CanvasRenderingContext2D.fillRect()","fillRect()")}}.

Наконец, в этой функции мы конвертируем canvas в изображение PNG и вызываем метод {{domxref("Element.setAttribute", "photo.setAttribute()")}} отображая захваченный цветовой фон в элементе изображения (бокса для фотографии).

@@ -197,7 +197,7 @@ translation_of: Web/API/WebRTC_API/Taking_still_photos

Примечание : Используется факт того, что интерфейс {{domxref("HTMLVideoElement")}} похож на интерфейс {{domxref("HTMLImageElement")}} для любых API , которые принимают HTMLImageElement в качестве параметра, с текущим кадром видео, представленным как содержимое изображения.

-

Как тоько  canvas будет содержать захваченное видео, конвертируем его в  PNG формат, вызывая метод {{domxref("HTMLCanvasElement.toDataURL()")}} на нем; наконец вызываем метод {{domxref("Element.setAttribute", "photo.setAttribute()")}} отображая захваченное изображение в элементе изображения (бокса фотографии).

+

Как только  canvas будет содержать захваченное видео, конвертируем его в  PNG формат, вызывая метод {{domxref("HTMLCanvasElement.toDataURL()")}} на нем; наконец вызываем метод {{domxref("Element.setAttribute", "photo.setAttribute()")}} отображая захваченное изображение в элементе изображения (бокса фотографии).

Если подходящее изображение не доступно (то есть, width и height равны  0), отчищаем содержимое элемента изображения, вызывая метод clearphoto().

diff --git a/files/ru/web/api/webrtc_api/using_data_channels/index.html b/files/ru/web/api/webrtc_api/using_data_channels/index.html index f8074830d4..cbb64c54bb 100644 --- a/files/ru/web/api/webrtc_api/using_data_channels/index.html +++ b/files/ru/web/api/webrtc_api/using_data_channels/index.html @@ -37,9 +37,9 @@ dataChannel.addEventListener("open", (event) => {

Ручной режим согласования

-

Для ручного согласования соединения, сначала необходимо создать новый объект типа {{domxref("RTCDataChannel")}}, используя метод  {{domxref("RTCPeerConnection.createDataChannel", "createDataChannel()")}} объекта {{domxref("RTCPeerConnection")}}, определяя свойство  {{domxref("RTCDataChannelInit.negotiated", "negotiated")}} в значение true. Это сигнализирует объекту соединения не пытыться согласовать соединение автоматически.

+

Для ручного согласования соединения, сначала необходимо создать новый объект типа {{domxref("RTCDataChannel")}}, используя метод  {{domxref("RTCPeerConnection.createDataChannel", "createDataChannel()")}} объекта {{domxref("RTCPeerConnection")}}, определяя свойство  {{domxref("RTCDataChannelInit.negotiated", "negotiated")}} в значение true. Это сигнализирует объекту соединения не пытаться согласовать соединение автоматически.

-

Затем нужно согласовать соединение, используя веб сервер или иные средства коммуникации. Этот процесс должен сигнализировать удаленному узлу, что нужно создать собственный объект типа RTCDataChannel со свойством  negotiated, установленным в значение  true, используя тот же идентификатор канала {{domxref("RTCDataChannel.id", "id")}}. Это свяжет два объекта типа  RTCDataChannel через объет типа RTCPeerConnection.

+

Затем нужно согласовать соединение, используя веб сервер или иные средства коммуникации. Этот процесс должен сигнализировать удаленному узлу, что нужно создать собственный объект типа RTCDataChannel со свойством  negotiated, установленным в значение  true, используя тот же идентификатор канала {{domxref("RTCDataChannel.id", "id")}}. Это свяжет два объекта типа  RTCDataChannel через объект типа RTCPeerConnection.

let dataChannel = pc.createDataChannel("MyApp Channel", {
   negotiated: true
@@ -51,7 +51,7 @@ dataChannel.addEventListener("open", (event) => {
 
 requestRemoteChannel(dataChannel.id);
-

В данном примере канал создается установкой значения свойства negotiated в true, затем вызывается функция  requestRemoteChannel() , запуская согласование соединения для создания удаленного канала с тем же идентификатором как у локального канала. Таким образом создание каналов данных позволяет использовать различные свойства, создавая их декларативно, использьзуя одно и тоже значение идентификатора канала  id.

+

В данном примере канал создается установкой значения свойства negotiated в true, затем вызывается функция  requestRemoteChannel() , запуская согласование соединения для создания удаленного канала с тем же идентификатором как у локального канала. Таким образом создание каналов данных позволяет использовать различные свойства, создавая их декларативно, используя одно и тоже значение идентификатора канала  id.

Буферизация

-- cgit v1.2.3-54-g00ecf