Подробное объяснение сервера rtmp протокол_rtmp
Подробное объяснение сервера rtmp протокол_rtmp

Предисловие

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

В этой статье протокол rtmp будет объяснен в следующих четырех частях.

  • 1. Новости
  • 2. Блокировать
  • 3. тип сообщения rtmp
  • 4. Пример анализа процесса передачи rtmp

1. Новости

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

Формат сообщения

RTMPзаголовок сообщенияинагрузкадве части。

заголовок сообщения

ценить

длина

значение

message type

1byte

Указывает тип сообщения

payload length

3byte

Количество байтов, представляющих нагрузку,формат с прямым порядком байтов

timestamp

4byte

Представляет временную метку сообщения в формате с обратным порядком байтов.

stream id

3byte

Указывает идентификатор потока сообщений, формат с обратным порядком байтов.

  • Тип сообщения:

Идентификаторы сообщений 1–7 используются для сообщений управления протоколом.

Сообщения 8 и 9 используются для передачи аудио- и видеоданных соответственно.

Сообщения 15-20 используются для отправки команд в кодировке AMF, отвечающих за взаимодействие пользователя и сервера, таких как воспроизведение, пауза.

нагрузка

Реальные данные, содержащиеся в сообщениях в нагрузке. Например, это могут быть аудиосэмплы или сжатые видеоданные.

2. Блокировать

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

формат блока

Блоки состоят из головок инагрузка

блочная структура

ценить

длина

значение

basic header

1 байт или 2 байта или 3 байта

блокировать базовый заголовок

chunk msg header

11 байт или 2 байта или 3 байта

кусокзаголовок сообщения

extended timestamp

4byte

расширенная временная метка

а. Базовый заголовок блока (базовый заголовок)
  • Структура первого байта основного заголовка:

ценить

длина

значение

fmt

2bit

формат блока

cs id

6bit

Идентификатор блокировки потока

  • fmtиззначение

ценить

значение

0

выражатькусокзаголовок сообщенияда Тип 0

1

выражатькусокзаголовок сообщенияда Тип 1

2

выражатькусокзаголовок сообщенияда Тип 2

3

выражатькусокзаголовок сообщенияда Тип 3

  • cs idиззначение

ценить

значение

0

блокировать базовый заголовок 2 байта, Идентификатор метода расчета блокировки потока (2-й байт + 64),Диапазон(64-319)

1

блокировать базовый заголовок 3 байта, Идентификатор метода расчета блокировки потока (3-й байт*255+2-й байт+64),Диапазон(3-65599)

2

блокировать базовый заголовок1 байт, 2 представляет сообщение протокола низкого уровня

3-64

блокировать базовый заголовок1 байт, это число представляет собой Идентификатор блокировки поток,диапазон(3-64)

Этот протокол поддерживает 65597 потоков с идентификаторами от 3 до 65599. Идентификаторы 0, 1 и 2 зарезервированы.

b、кусокзаголовок сообщения (заголовок фрагмента сообщения)
  • Тип 0

Тип 0 имеет общую длину 11 байт и имеет следующий формат:

ценить

длина

значение

timestamp

3byte

Временная метка

message length

3byte

нагрузкаиздлина

message type id

1byte

идентификатор типа сообщения

message stream id

4byte

идентификатор потока сообщений

  • Тип 1

Тип 1 имеет общую длину 7 байт и имеет следующий формат:

ценить

длина

значение

timestamp

3byte

Временная метка

message length

3byte

нагрузкаиздлина

message type id

1byte

идентификатор типа сообщения

  • Тип 2

Тип 1 имеет общую длину 3 байта и имеет следующий формат:

ценить

длина

значение

timestamp

3byte

Временная метка

  • Тип 3

Тип Блок из 3 не имеет заголовка. Идентификатор потока, длина сообщения, Ни Временная, ни метка не появились. Этот тип блока использует те же данные, что и предыдущий блок. Когда сообщение разделено на несколько частей,Кроме первой части,Все блоки должны использовать этот тип.

c. Расширенная временная метка.

расширенная временная метка всего 4 байта, только если заголовок блока сообщения中из普通Временная Это поле передается только в том случае, если для метки установлено значение 0x00ffffff. Если обычный Временная Цена метки меньше 0x00ffffff, тогда это поле не должно появляться.

Формат данных rtmp был подробно объяснен выше. Давайте объясним конкретное содержание протокола rtmp.

нагрузка

Нагрузка блока — это нагрузка на содержимое сообщения.

Подводя итог: сообщение является базовой единицей данных rtmp, а блок используется для повторной инкапсуляции сообщения для передачи по сети.

3. тип сообщения rtmp

Типы сообщений RTMP можно разделить на три категории: сообщения управления протоколом, сообщения управления пользователем и командные сообщения RTMP.

1. Сообщение управления протоколом
1.1. Сообщение о размере блока (Тип сообщения=1)

Устанавливает размер блока, используемый для уведомления узла о новом максимальном размере блока. Максимальный размер блока по умолчанию составляет 128 байт. Клиенты и серверы могут использовать это сообщение для изменения размера блока по умолчанию. Например, предположим, что клиент хочет отправить аудиоданные размером 131 байт, а размер фрагмента — 128 байт. В этом случае клиент может сообщить серверу, что размер нового фрагмента составляет 131 байт, а затем полные аудиоданные можно отправить одним фрагментом.

Максимальный размер блока рекомендуется составлять не менее 128 байт, но должен быть не менее 1 байта. Каждое направление связи (например, от клиента к серверу) имеет независимые настройки размера блока. Максимальный размер блока поддерживается взаимодействующими сторонами (сервером или клиентом).

Сообщение об установке размера блока занимает всего 4 байта, Формат следующего:

ценить

длина

значение

0

1bit

Первый бит должен быть 0

chunk size

31bit

Новый максимальный размер блокаценить

1.2 Сообщение о завершении (Тип сообщения=2)

Завершить сообщение,Используется для уведомления узла,Если вы ожидаете частичную часть сообщения (часть сообщения уже получена),那么可以丢弃之前已经接收到изкусок。对端将接收到из Идентификатор блокировки поток в качестве полезной нагрузки текущего управляющего сообщения протокола. Приложение может отправить это сообщение во время завершения работы, чтобы указать, что дальнейшая обработка сообщения не требуется.

Завершить сообщениенагрузка имеет общий размер 4 байта,Формат следующий:

ценить

длина

значение

chunk stream id

4byte

Идентификатор потока блокировки, сообщения этого потока блокировки не будут потеряны полностью

1.3. Подтверждающее сообщение (Тип сообщения=3).

Клиент или сервер ДОЛЖНЫ отправить сообщение подтверждения партнеру после получения байтов, равных размеру окна. Размер окна относится к максимальному количеству байтов, которое отправитель может отправить до получения сообщения подтверждения от получателя. Это сообщение определяет порядковый номер, который представляет собой количество полученных на данный момент байтов.

Подтверждающее сообщение имеет общий размер 4 байта. Формат следующего:

ценить

длина

значение

sequence number

4byte

Количество полученных на данный момент байтов

1.4. Сообщение подтверждения размера окна (Тип сообщения=5)

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

Размер окна подтверждения составляет всего 4 байта, Формат следующего:

ценить

длина

значение

acknowledge window size

4byte

Подтвердите размер окна

1.5. Установите сообщение о пропускной способности однорангового узла (тип сообщения = 6).

Клиент или сервер отправляет это сообщение для обновления выходной пропускной способности узла. Цена выходной полосы пропускания такая же, как и размер окна. Если цена, полученная узлом в этом сообщении, не совпадает с размером окна, обратно отправляется сообщение о размере окна подтверждения (подтверждения).

ценить

длина

значение

acknowledge window size

4byte

Подтвердите размер окна

limit type

1byte

Поле типа лимита

  • limit type:

Отправитель может типа лимитаотметить сообщение как сложное(0),мягкий(1),Или динамический (2). Если существует жесткое ограничение, партнер должен отправлять данные в соответствии с предоставленной полосой пропускания. Если это мягкий предел,Пиры могут гибко выбирать пропускную способность,Отправитель может ограничить пропускную способность. Если это динамический предел,Пропускная способность может быть жесткой или мягкой.

2. Пользовательское управляющее сообщение (Тип сообщения=4)

RTMP использует идентификатор типа сообщения 4 обозначает сообщение управления пользователем. Эти сообщения содержат информацию, используемую уровнем потоковой передачи RTMP. Идентификатор, используемый сообщением управления протоколом: 1、2、3、5 и 6 (Уже представлено ранее). Сообщения управления пользователями должны использовать идентификатор потока сообщений. 0 (который считается потоком управления) и Идентификатор при отправке в виде потока фрагментов RTMP. блокировки поток равен 2. Прием сообщения управления протоколом вступает в силу немедленно при разборе, Временная; Поле метка игнорируется.

Клиент или сервер отправляет это сообщение, чтобы уведомить одноранговый узел о некоторых событиях пользовательского управления.

Эта новость несет в себетип событияиданные о событии,Формат следующий:

ценить

длина

значение

event type

2byte

тип события

event data

?

данные о событии

  • event type

событие

описывать

Stream Begin (=0)

Сервер отправляет это событие, чтобы уведомить клиента о том, что поток готов и может использоваться для связи. По умолчанию,Это событие отправляется с идентификатором = 0 после успешного получения команды подключения клиента. данные о событии - 4 байта,Представляет идентификатор готового потока.

Stream EOF (=1)

Сервер отправляет это событие, чтобы уведомить клиента о том, что воспроизведение данных для запрошенного потока закончилось. Перед отправкой дополнительных команд данные больше не отправляются. Клиент будет отбрасывать сообщения, полученные для этого потока. данные о событии имеет размер 4 байта и представляет поток, который воспроизводит завершившийся поток. ID。

StreamDry (=2)

Сервер отправляет это событие, чтобы уведомить клиента об отсутствии данных в текущем потоке. Если сервер не обнаруживает никаких сообщений в течение определенного периода времени, он может уведомить соответствующий клиент о том, что в текущем потоке закончились данные. Эти данные о событии — это 4 байта, представляющие поток, в котором нет данных. ID。

SetBuffer Length (=3)

Клиент отправляет это событие, чтобы уведомить сервер о размере буфера. (в миллисекундах) этот буфер используется для кэширования любых данных, поступающих из потока. Это событие отправляется до того, как сервер начнет обработку потока. данные о Первые 4 байта событии представляют собой идентификатор потока, а следующие 4 байта представляют длину буфера в миллисекундах.

Streams Recorded (=4)

Сервер отправляет это событие, чтобы уведомить клиента о том, что текущий поток является потоком записи. данные о событии - 4 байта, представляющие собой поток потока записи ID。

PingRequest (=6)

Сервер отправляет это событие, чтобы проверить, доступен ли клиент. данные о событии — это 4-байтовая Временная метка представляет собой местное время сервера, когда сервер отправляет эту команду. После получения этого сообщения клиент немедленно отправит PingResponse отвечать.

PingResponse(=7)

Клиент отправляет это событие в ответ на PingRequest сервера. данные о событии — это 4-байтовая Временная метка,Должен Временная метка — данные, полученные из PingRequest о Получено от события.

3. Командное сообщение RTMP
3.1. Сообщение данных (тип сообщения = 18 или 15).

Клиент или сервер отправляет метаданные и пользовательские данные другой стороне через это сообщение. Метаданные включают дату создания данных.、продолжительность、Тема и другие детали。Тип сообщения18из用AMF0кодирование,Тип сообщения 15 кодируется с помощью AMF3.

3.2. Сообщение об общем объекте (тип сообщения = 19 или 16).

Общие объекты распределены по нескольким клиентам,Синхронизированный экземпляр объекта FLASH (набор пар имен). Тип сообщения kMsgContainer=19 закодирован с помощью AMF0.,kMsgContainerEx=16, закодированный с помощью AMF3,Эти два сообщения предназначены для событий общих объектов. Каждое сообщение может содержать несколько событий.

Формат следующий:

событие

описывать

Use (=1)

Клиент отправляет это событие, чтобы уведомить сервер о создании именованного общего объекта.

Release (=2)

Когда клиент удаляет общий объект,Отправьте это уведомление о событии на сервер.

Requeset change (=3)

Когда делается запрос на изменение связанной цены именованного параметра общего объекта.,Клиент отправляет это сообщение.

Change (=4)

При изменении ассоциации именованного параметра,Сервер отправляет это событие всем клиентам.

Success (=5)

После принятия запроса на изменение события,Сервер отвечает этим сообщением запрашивающему клиенту.

SendMessage (=6)

Клиент отправляет широковещательное сообщение об этом событии на сервер. После получения этого события сервер рассылает сообщение всем клиентам, включая того, который отправил это событие.

Status (=7)

для состояния ошибки,Сервер отправляет это событие клиенту.

Clear (=8)

Сервер отправляет это событие клиенту,Очистить общий объект. Это событие также используется в качестве ответа, когда клиент отправляет usesoeventh при подключении.

Remove (=9 )

Сервер отправляет это событие, чтобы клиент удалил слот.

Request Remove (=10)

Клиент отправляет это событие на сервер при удалении слота.

Use Success(=11)

Когда соединение успешно Сервер отправляет это событие клиенту.

3.3.Аудиосообщение (Тип сообщения=8)

Клиент и сервер используют это сообщение для отправки аудиоданных партнеру.

3.4. Видеосообщение (Тип сообщения=9)

Клиент и сервер используют это сообщение для отправки видеоданных партнеру.

3.5. Совокупные сообщения (Тип сообщения=22).

Совокупное сообщение — это отдельное сообщение, содержащее ряд подсообщений.

Формат следующий:

Идентификатор потока сообщений совокупного сообщения переопределит идентификатор потока дочерних сообщений в агрегате сообщений. Совокупное сообщение и первое подсообщение Временная Разница в метке — это смещение, которое используется для добавления Временной к подсообщению. метка Перенормировка на график потока. Смещение добавляется к Временной каждому подсообщению. метка для достижения нормированного времени истечения. Временная для первого подсообщения метка должна сочетаться с Временной метка та же самая, поэтому смещение должно быть ноль. Возвращенный указатель содержит размер предыдущего сообщения, включая его заголовок. сообщения。 Включатьзаголовок сообщения должны соответствовать формату FLV-файла и для обратного поиска.

3.6. Командное сообщение (тип сообщения = 20 или 17).

Командные сообщения передают команды в кодировке AMF между клиентом и сервером. Тип сообщения 20 кодируется AMF0, а тип сообщения 17 кодируется AMF3.

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

Команды, связанные с a.NetConnection
  • connect
  • call
  • close
  • createStream
b.Команды, связанные с NetStream
  • play
  • play2
  • deleteStream
  • closeStream
  • receiveAudio
  • receiveVideo
  • publish
  • seek
  • pause
  • Сервер использует команду onStatus для отправки статуса NetStream клиенту:

4. Пример анализа процесса передачи rtmp

В этой части будет представлен процесс передачи rtmp и использование Wireshark для захвата пакетов и анализа примеров.

  • рукопожатие
  • Установить сетевое соединение
  • Создайте поток
  • играть
1, рукопожатие

(1) Подтверждение начинается с отправки клиентом блоков C0, C1.

(2) Сервер отправляет блоки S0 и S1 после получения C0.

(3) После того, как клиент получает блоки S0 и S1, он отправляет блок C2, а сервер отправляет блок S2 после получения блоков C0 и C1.

(4) Когда клиент получает S2, а сервер получает C2, рукопожатие считается успешным после проверки соответственно.

Принципиальная схема выглядит следующим образом:

C0 и S0 имеют только 1 байт, Формат следующего:

ценить

длина

значение

version

1byte

номер версии

C1, S1 содержит 1526 байт, формат следующий:

ценить

длина

значение

time

4byte

Временная метка

zero

4byte

ноль

random bytes

1528byte

Это поле используется для проверки

C2иS2из Формат сообщения

Детали сообщения C2 и S2 такие же, как у C1 и S2.,C2 является копией S1,S2 является копией C1.

Получив C2, сервер сравнит его с S1.

Получив S2, клиент сравнит его с C1.

rtmp использует этот метод, чтобы определить успешность рукопожатия.

Пример анализа:

(1) Рукопожатие начинается с отправки клиентом блоков C0, C1:

Язык кода:javascript
копировать
03: Этот байт — C0, что означает номер. версии。

Следующие 1536 байт — это C1.
ff fd fe b4:Временная метка
00 00 00 00: Четыре ноль

Следующие 1528 байт — это случайные числа.

(2) Сервер отправляет блоки S0 и S1 после получения C0:

Язык кода:javascript
копировать
03: Этот байт — S0, что означает номер. версии。

Следующие 1536 байт — это S1.
ff fd fe b4:Временная метка
00 00 00 00: Четыре ноль

Следующие 1528 байт — это случайные числа.

(3) После того, как клиент получает блоки S0 и S1, он отправляет блок C2, а сервер отправляет блок S2 после получения блоков C0 и C1.

На рисунке ниже показан S2, отправленный сервером:

Как видно, данные те же, что и C1.

На рисунке ниже показан C2, отправленный клиентом:

Как видно, данные такие же, как S1.

Рукопожатие завершено.

2. Установите сетевое соединение.

(1) Клиент отправляет «сообщение о подключении» для запроса соединения.

(2) После получения запроса на подключение служба отправляет «сообщение подтверждения размера окна».

(3) Сервер отправляет клиенту «сообщение об установке пропускной способности».

(4) После того, как клиент обрабатывает «Сообщение об установке пропускной способности», он отправляет на сервер «Сообщение о подтверждении размера окна» (это сообщение будет отправлено только в том случае, если цена сообщения об установке пропускной способности отличается от размера окна).

(5) Сервер отправляет клиенту сообщение «Начало потока» в сообщении пользовательского управления.

(6) Сервер отправляет «результат» (_result) в «командном сообщении», чтобы уведомить клиента о состоянии соединения.

Принципиальная схема выглядит следующим образом:

Пример анализа:

«Команда подключения», при которой клиент отправляет командное сообщение на сервер:

Язык кода:javascript
копировать
03: бит[7:8] означает, что fmt равен 0, бит[0:6] означает идентификатор блокировки поток равен 3 (если он равен 0, это означает, что существует один байт расширения; если он равен 1, это означает, что есть два байта расширения, если он равен 2, это означает базовое сообщение управления протоколом и команду)
Поскольку fmt равен 0, заголовок следующего блока сообщение имеет 11 байт
00 00 00:timestamp
00 00 5f:message length
14:message тип, десятичное число равно 20, что указывает на то, что тип данных сообщения использует кодировку AMF0.
00 00 00 00:msg stream id
Далее идут данные блока

02:amf тип (представляющий строку)
00 07:string длина (представляющая длину строки)
63 6f 6e 6e 65 63 74:string("connect")

00 :amf тип (представляющий двойной тип)
3f f0 00 00 00 00 00 00:val

03:amf тип (представляющий тип объекта)

key:
00 03:string длина (представляющая длину строки)
61 70 70:string("app")
value:
02:amf тип (представляющий строку)
00 04:string длина (представляющая длину строки)
74 79 70 65:string("live")
key:
00 04:string длина (представляющая длину строки)
74 79 70 65:string("type")
val:
02:amf тип (представляющий строку)
00 0a:string длина (представляющая длину строки)
6e 6f 6e 70 72 69 76 61 74 65:string("nonprivate")
key:
00 05:string длина (представляющая длину строки)
74 63 55 72 6c:string("tcUrl")
val:
02:amf тип (представляющий строку)
00 1f:string длина (представляющая длину строки)
72 74 6d 70 3a 2f 2f 31 39 32 2e 31 36 38 2e 31 36 38 2e 31 36 2e 31 32 38 3a 38 30 30 31 2d 6c 69 76 65:string("rtmp://192.168.16.128:8001/live")

00 00 09: Обозначает конец

Сервер отправляет клиенту окно подтверждения:

Язык кода:javascript
копировать
02: бит[7:8] означает, что fmt равен 0, бит[0:6] означает идентификатор блокировки поток равен 2 (2 представляет базовое сообщение управления протоколом и команду)
Поскольку fmt равен 0, заголовок следующего блока сообщение имеет 11 байт
00 00 00:timestamp
00 00 54:message length
05:message тип (5 указывает на определение размера окна события)
00 00 00 00:msg stream id
00 4c 4b 40:window size

После этого сервер отправил клиенту еще три сообщения.,В документации здесь говорится немного другое.,я тоже не совсем понимаю,Надеюсь, кто-нибудь сможет это объяснить:

Этот поток блоков содержит несколько сообщений

  • Первое сообщение предназначено для установки сообщения о пропускной способности однорангового узла.
Язык кода:javascript
копировать
02: бит[7:8] означает, что fmt равен 0, бит[0:6] означает идентификатор блокировки поток равен 2 (2 представляет базовое сообщение управления протоколом и команду)
Поскольку fmt равен 0, заголовок следующего блока сообщение имеет 11 байт
00 00 00:timestamp
00 00 05:message length
06:message тип (6 означает настройку сообщения о пропускной способности однорангового узла)
00 00 00 00:msg stream id
00 4c 4b 40:window размер (пропускная способность 5M)
02 :limit type
     0 - Жесткий: партнер должен ограничить свою выходную полосу пропускания не более чем указанным размером окна.
    1 - Мягкий: партнер должен ограничить свою выходную полосу пропускания не более чем указанным размером окна или, если ограничение уже существует, выбрать меньшую цену между двумя размерами окна.
    2 - Динамический: если предыдущий тип лимита был Hard,Тогда это сообщение также считается жестким сообщением.,В противном случае игнорируйте это сообщение.
  • Второе сообщение — это сообщение об установленном размере блока.
Язык кода:javascript
копировать
02: бит[7:8] означает, что fmt равен 0, бит[0:6] означает идентификатор блокировки поток равен 2 (2 представляет базовое сообщение управления протоколом и команду)
Поскольку fmt равен 0, заголовок следующего блока сообщение имеет 11 байт
00 00 00:timestamp
00 00 04:message length
01:message тип (1 означает сообщение об установке размера блока)
00 00 00 00:msg stream id
00 00 10 00
  • Третье сообщение — это ответное сообщение о подключении.
Язык кода:javascript
копировать
03: бит[6:7] означает, что fmt равен 0, бит[0:5] означает идентификатор блокировки потокадля1(3выражать Идентификатор блокировки потока)
Поскольку fmt равен 0, заголовок следующего блока сообщение имеет 11 байт
00 00 00:timestamp
00 00 be:message length
14:message тип (20 в десятичном формате, что указывает на то, что данные сообщения закодированы в формате AMF0)
00 00 00 00:msg stream id

02:amf тип (представляющий строку)
00 07:string длина (представляющая длину строки)
5f 71 65 73 75 6c 74:string("_resulte")
00:amf тип (имеется в виду двойной)
3f f0 00 00 00 00 00 00: вал (двойной тип)

03:amf тип (представляющий тип объекта)
key:
00 06:string длина (представляющая длину строки)
66 6d 73 56 65 72:string("fmsVer")
val:
02:amf тип (представляющий строку)
00 0d:string длина (представляющая длину строки)
46 4d 53 2f 33 2c 30 2c 30 2c 31 2c 31 32 33:string("FMS/2,0,1,123")
...
00 00 09:end
3. Установите поток

(1) Клиент отправляет на сервер «Команду создания потока (createStream)» в «Командном сообщении».

(2) После получения сообщения сервер отправляет «результат (_result)» в «командном сообщении».

Принципиальная схема выглядит следующим образом:

Пример анализа:

(1) Клиент отправляет «команду createStream» в «командном сообщении» на сервер:

(2) Сервер отправляет «результат (_result)» в «командном сообщении» клиенту:

4. Публикация аудио и видео данных

(1) Клиент отправляет «команду публикации» в «командном сообщении».

(2) После получения сообщения сервер отправляет «streambegin» в сообщении управления пользователем.

(3) Клиент начинает отправлять аудио- и видеоданные.

Принципиальная схема выглядит следующим образом:

Пример анализа:

Клиент отправляет «команду публикации» в «командном сообщении»:

Ответ сервера:

Клиент отправляет мультимедийную информацию:

Клиент отправляет мультимедийные данные:

Заявление об авторских правах: Содержание этой статьи добровольно предоставлено пользователями Интернета, а мнения, выраженные в этой статье, представляют собой только точку зрения автора. Данный сайт лишь предоставляет услуги по хранению информации, не имеет никаких прав собственности и не несет соответствующей юридической ответственности. Если вы обнаружите на этом сайте какое-либо подозрительное нарушение авторских прав/незаконный контент, отправьте электронное письмо, чтобы сообщить. После проверки этот сайт будет немедленно удален.

Издатель: Лидер стека программистов полного стека, укажите источник для перепечатки: https://javaforall.cn/200812.html Исходная ссылка: https://javaforall.cn

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose