音视频学习(二十八):websocket-flv

FLV视频流格式

FLV (Flash Video) 是一种轻量化的视频封装格式,适合实时流媒体传输,主要特点包括:

  • 轻量级封装:封装开销低,适合在网络上传输。
  • 流式播放:支持边下载边播放,特别适合直播场景。
  • 适配性强:虽然 Flash 逐渐被淘汰,但 FLV 数据仍可以通过现代播放器(如 flv.js)播放。

http-flv:https://blog.csdn.net/www_dong/article/details/144571432

flv协议:https://blog.csdn.net/www_dong/article/details/128166528

WebSocket 协议

特点

  • 全双工通信:客户端和服务器可以随时发送消息,无需等待请求。

  • 基于 TCP 的协议:通过 TCP 连接提供高效的数据传输。

  • 长连接:建立连接后,保持持久连接,无需多次握手。

  • 低延迟:相比于 HTTP 请求/响应,WebSocket 消除额外的 HTTP 报文开销。

  • 轻量级协议头:消息头非常小,减少了带宽消耗。

  • 事件驱动:通过事件监听机制处理消息和连接状态。

连接过程

WebSocket 连接建立需要经过一个 HTTP 升级握手(Upgrade Handshake),步骤如下:

客户端请求升级

客户端通过 HTTP 发送升级请求:

GET /chat HTTP/1.1
Host: example.com:8080
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

关键头部:

  • Upgrade: websocket:请求将 HTTP 升级为 WebSocket。
  • Connection: Upgrade:指定连接为升级类型。
  • Sec-WebSocket-Key:一个 Base64 编码的随机字符串,用于验证连接有效性。
  • Sec-WebSocket-Version:指定 WebSocket 协议的版本(常见为 13)。

服务器响应

服务器收到请求后验证头部信息,返回以下响应:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

关键头部:

  • Sec-WebSocket-Accept:基于客户端的 Sec-WebSocket-Key 和特定算法生成的值,用于确认握手。

握手完成

连接建立后,双方切换到 WebSocket 协议,开始通过 TCP 通道进行数据交换。

特点

优点

  1. 实时性强:支持低延迟双向通信。
  2. 节省带宽:帧头较小,减少了网络开销。
  3. 轻量化:在 TCP 层之上直接操作,避免了 HTTP 的冗余数据。

缺点

  1. 复杂性:实现握手和协议需要更多开发和调试。
  2. 网络环境要求:依赖于 TCP 长连接,在某些防火墙或代理下可能不支持。
  3. 安全性:需要特别注意对传输数据的加密和校验(如 WSS)。

数据帧格式

WebSocket 数据通过帧(Frame)进行传输。每个帧包含以下字段:

字段名称长度描述
FIN1 位表示消息是否结束(1 表示结束)。
RSV1, RSV2, RSV3各 1 位保留位,通常为 0。
Opcode4 位指定帧类型(如文本、二进制)。
Mask1 位指示是否对数据进行掩码。
Payload Length7 位或更多数据负载的长度。
Masking-Key4 字节(可选)掩码密钥,用于客户端到服务器的数据。
Payload Data可变长度实际传输的数据。

Opcode 的取值

  • 0x1:文本帧
  • 0x2:二进制帧
  • 0x8:连接关闭帧
  • 0x9:Ping 帧
  • 0xA:Pong 帧

示例

  • 客户端
// 创建 WebSocket 连接
const socket = new WebSocket("ws://example.com/socket");// 连接打开事件
socket.onopen = () => {console.log("WebSocket connection established.");socket.send("Hello, Server!");
};// 接收消息事件
socket.onmessage = (event) => {console.log("Message from server:", event.data);
};// 错误事件
socket.onerror = (error) => {console.error("WebSocket error:", error);
};// 关闭事件
socket.onclose = () => {console.log("WebSocket connection closed.");
};
  • 服务端
const WebSocket = require('ws');// 创建 WebSocket 服务器
const wss = new WebSocket.Server({ port: 8080 });wss.on('connection', (ws) => {console.log("Client connected.");// 接收客户端消息ws.on('message', (message) => {console.log("Received:", message);ws.send("Hello, Client!");});// 处理关闭事件ws.on('close', () => {console.log("Client disconnected.");});
});

技术对比

特性WebSocketHTTP/2SSE (Server-Sent Events)
双向通信
连接类型长连接多路复用的长连接长连接
协议复杂性中等
消息方向双向单向(服务器推送为主)单向(服务器推送)
适用场景实时聊天、游戏、股票推送HTTP 优化(如 REST API)实时通知、新闻推送

ws-flv

WebSocket-FLV 是指使用 WebSocket 协议传输 FLV 格式视频流的技术组合。它主要用于实时直播场景,结合了 WebSocket 的实时性和 FLV 的轻量特点。

工作流程

服务器端

  • 将音视频流编码为 FLV 格式(可使用 FFmpeg 或其他编码工具)。
  • 通过 WebSocket 推送 FLV 数据到客户端。

客户端

  • 使用 WebSocket 接收 FLV 数据流。
  • 利用播放工具(如 flv.js)解析并渲染 FLV 数据。

优点

  • 延迟极低,通常低于 1 秒。
  • 数据传输高效,FLV 格式进一步减小了数据量。
  • 实现较为简单,适合实时直播。

示例(c++)

  • 服务端
#include <uwebsockets/App.h>
#include <fstream>
#include <iostream>
#include <vector>
#include <thread>class WebSocketFLVServer {
public:WebSocketFLVServer(const std::string &flvFilePath, int port): flvFilePath(flvFilePath), port(port) {}void start() {// 加载 FLV 文件if (!loadFLVFile()) {std::cerr << "Failed to load FLV file: " << flvFilePath << std::endl;return;}// 创建 WebSocket 服务器uWS::App().ws<ConnectionData>("/*", {.open = [this](auto *ws) {std::cout << "Client connected!" << std::endl;ws->send(reinterpret_cast<char *>(flvData.data()), flvData.size(), uWS::BINARY);},.message = [](auto *ws, std::string_view message, uWS::OpCode opCode) {// 处理客户端消息(可选)std::cout << "Received message: " << message << std::endl;},.close = [](auto *ws, int code, std::string_view message) {std::cout << "Client disconnected!" << std::endl;}}).listen(port, [this](auto *token) {if (token) {std::cout << "WebSocket server listening on port " << port << std::endl;} else {std::cerr << "Failed to listen on port " << port << std::endl;}}).run();}private:struct ConnectionData {};std::string flvFilePath;int port;std::vector<uint8_t> flvData;bool loadFLVFile() {std::ifstream file(flvFilePath, std::ios::binary);if (!file.is_open()) {return false;}file.seekg(0, std::ios::end);size_t fileSize = file.tellg();file.seekg(0, std::ios::beg);flvData.resize(fileSize);file.read(reinterpret_cast<char *>(flvData.data()), fileSize);file.close();return true;}
};int main() {const std::string flvFilePath = "live.flv"; // 替换为实际的 FLV 文件路径const int port = 9001;WebSocketFLVServer server(flvFilePath, port);server.start();return 0;
}

wss-flv

WSS-FLV 是指通过 WebSocket Secure(WSS) 协议传输 FLV(Flash Video) 视频流的技术组合。WSS 是 WebSocket 协议的安全版本,类似于 HTTPS,相较于普通 WebSocket(WS),WSS 在传输层使用了 TLS/SSL 加密,保障了数据的安全性。

特点

  • 加密通信:通过 TLS/SSL 加密,防止数据被篡改或窃听。

  • 与 HTTPS 兼容:可以在 HTTPS 环境中无缝工作,特别适合前端页面通过 WebSocket 通信的场景。

  • 适用高安全场景:如支付视频流、医疗直播、敏感监控视频传输等。

应用

直播平台

  • 提供安全的低延迟直播传输,避免流媒体数据被拦截或劫持。

实时监控

  • 安全传输监控视频流,保障用户隐私。

教育和会议系统

  • 在线教育或实时会议中,确保音视频数据加密传输。

远程医疗

  • 保障医疗数据和视频流的传输安全性。

示例(c++)

#include <uwebsockets/App.h>
#include <fstream>
#include <iostream>
#include <vector>
#include <thread>class WSSFLVServer {
public:WSSFLVServer(const std::string &flvFilePath, int port, const std::string &certPath, const std::string &keyPath): flvFilePath(flvFilePath), port(port), certPath(certPath), keyPath(keyPath) {}void start() {// 加载 FLV 文件if (!loadFLVFile()) {std::cerr << "Failed to load FLV file: " << flvFilePath << std::endl;return;}// 启动 WSS 服务uWS::SSLApp({.key_file_name = keyPath.c_str(),.cert_file_name = certPath.c_str(),.passphrase = ""}).ws<ConnectionData>("/*", {.open = [this](auto *ws) {std::cout << "Client connected (secure)!" << std::endl;ws->send(reinterpret_cast<char *>(flvData.data()), flvData.size(), uWS::BINARY);},.message = [](auto *ws, std::string_view message, uWS::OpCode opCode) {// 可选的客户端消息处理std::cout << "Received message: " << message << std::endl;},.close = [](auto *ws, int code, std::string_view message) {std::cout << "Client disconnected!" << std::endl;}}).listen(port, [this](auto *token) {if (token) {std::cout << "WSS server listening on port " << port << std::endl;} else {std::cerr << "Failed to listen on port " << port << std::endl;}}).run();}private:struct ConnectionData {};std::string flvFilePath;int port;std::string certPath;std::string keyPath;std::vector<uint8_t> flvData;bool loadFLVFile() {std::ifstream file(flvFilePath, std::ios::binary);if (!file.is_open()) {return false;}file.seekg(0, std::ios::end);size_t fileSize = file.tellg();file.seekg(0, std::ios::beg);flvData.resize(fileSize);file.read(reinterpret_cast<char *>(flvData.data()), fileSize);file.close();return true;}
};int main() {const std::string flvFilePath = "live.flv"; // 替换为实际 FLV 文件路径const int port = 9001;const std::string certPath = "certificate.crt"; // SSL 证书文件路径const std::string keyPath = "private.key";      // SSL 私钥文件路径WSSFLVServer server(flvFilePath, port, certPath, keyPath);server.start();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/891051.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

京东供应链创新与实践:应用数据驱动的库存选品和调拨算法提升履约效率

2024 年度总结系列 2024 年 10 月&#xff0c;京东零售供应链技术团队凭借其在库存选品与调拨技术上的创新与实践&#xff0c;荣获运筹与管理学领域的国际顶级奖项 Daniel H. Wagner Prize。本文为您介绍获奖背后的供应链技术创新和落地应用。 00 摘要 在电商行业中&#x…

大数据技术-Hadoop(二)HDFS的介绍与使用

目录 1、HDFS简介 1.1 什么是HDFS 1.2 HDFS的优点 1.3、HDFS的架构 1.3.1、 NameNode 1.3.2、 NameNode的职责 1.3.3、DataNode 1.3.4、 DataNode的职责 1.3.5、Secondary NameNode 1.3.6、Secondary NameNode的职责 2、HDFS的工作原理 2.1、文件存储 2.2 、数据写…

在 C# 中优化 JPEG 压缩级别和文件大小

此示例可让您检查不同 JPEG 压缩级别的图像质量。使用文件菜单的打开命令加载图像文件。然后使用“JPEG 压缩指数 (CI)”组合框选择压缩级别。程序将图像保存到具有该压缩级别的临时文件中&#xff0c;并显示生成的图像和文件大小。 该程序的关键是以下SaveJpg方法&#xff0c;…

Pandas02

Pandas01: Pandas01 文章目录 内容回顾1 数据的读取和保存1.1 读写Excel文件1.2 读写CSV1.3 读写Mysql 2 DataFrame 数据查询2.1 筛选多列数据2.2 loc 和 iloc2.3 query查询方法和isin 方法 3 DataFrame增 删 改数据3.1 增加一列数据3.2 删除一行/一列数据3.3 数据去重3.4 数据…

Flink定时器

flink的定时器都是基于事件时间&#xff08;event time&#xff09;或事件处理时间&#xff08;processing time&#xff09;的变化来触发响应的。对一部分新手玩家来说&#xff0c;可能不清楚事件时间和事件处理时间的区别。我这里先说一下我的理解&#xff0c;防止下面懵逼。…

Docker中的分层(Layer)

docker中有分层的概念&#xff0c;如下图所示 上面是容器层&#xff08;Container layer&#xff09;&#xff0c;下面是镜像层&#xff08;Image layers&#xff09;。 镜像层的内容是静态的&#xff0c;读和写的操作&#xff0c;都是在容器层发生&#xff0c;专门为容器的读…

RoboMIND:多体现基准 机器人操纵的智能规范数据

我们介绍了 RoboMIND&#xff0c;这是机器人操纵的多体现智能规范数据的基准&#xff0c;包括 4 个实施例、279 个不同任务和 61 个不同对象类别的 55k 真实世界演示轨迹。 工业机器人企业 埃斯顿自动化 | 埃夫特机器人 | 节卡机器人 | 珞石机器人 | 法奥机器人 | 非夕科技 | C…

python报错ModuleNotFoundError: No module named ‘visdom‘

在用虚拟环境跑深度学习代码时&#xff0c;新建的环境一般会缺少一些库&#xff0c;而一般解决的方法就是直接conda install&#xff0c;但是我在conda install visdom之后&#xff0c;安装是没有任何报错的&#xff0c;conda list里面也有visdom的信息&#xff0c;但是再运行代…

C语言性能优化:从基础到高级的全面指南

引言 C 语言以其高效、灵活和功能强大而著称&#xff0c;被广泛应用于系统编程、嵌入式开发、游戏开发等领域。然而&#xff0c;要写出高性能的 C 语言代码&#xff0c;需要对 C 语言的特性和底层硬件有深入的了解。本文将详细介绍 C 语言性能优化的背后技术&#xff0c;并通过…

go多版本管理工具g win安装配置

go多版本管理工具g 基本介绍仓库安装配置配置环境配置系统变量配置path变量测试使用配置完环境变量之后&#xff0c;打开终端进行测试使用查看 g 的环境变量配置&#xff0c;g env 为环境变量配置&#xff0c;g -v为当前版本信息查看可下载列表下载安装指定版本go&#xff0c;并…

PlasmidFinder:质粒复制子的鉴定和分型

质粒&#xff08;Plasmid&#xff09;是一种细菌染色体外的线性或环状DNA分子&#xff0c;也是一种重要的遗传元素&#xff0c;它们具有自主复制能力&#xff0c;可以在细菌之间传播&#xff0c;并携带多种重要的基因(如耐药基因与毒力基因等)功能。根据质粒传播的特性&#xf…

细说STM32F407单片机通过IIC读写EEPROM 24C02

目录 一、操作说明 二、工程配置 1、时钟、DEBUG、GPIO、USART6、NVIC、Code Generator 2、 IIC2 &#xff08;1&#xff09;Master Features组&#xff0c;主设备参数 &#xff08;2&#xff09;Slave Features组&#xff0c;从设备参数 三、软件设计 1、KELED 2、E…

神经网络-Inception

Inception网络是由Google开发的一种深度卷积神经网络架构&#xff0c;旨在解决计算机视觉领域中的图像分类和物体识别任务。 Inception网络最初在2014年被提出&#xff0c;并在ImageNet图像分类挑战赛上取得了很好的结果。其设计灵感来自于模块化的思想&#xff0c;将不同尺度…

PyTorch Instance Normalization介绍

Instance Normalization(实例归一化) 是一种标准化技术,与 Batch Normalization 类似,但它对每个样本独立地对每个通道进行归一化,而不依赖于小批量数据的统计信息。这使得它非常适合小批量训练任务以及图像生成任务(如风格迁移)。 Instance Normalization 的原理 对每…

国内独立开发者案例及免费送独立开发蓝图书

独立开发者在国内越来越受到关注&#xff0c;他们追求的是一种自由且自给自足的工作状态。 送这个&#xff1a; 少楠light&#xff08;Flomo、小报童、如果相机&#xff09;&#xff1a;他们是独立开发者的典范&#xff0c;不仅开发了多款产品&#xff0c;还坚信“剩者为王”…

【小程序】自定义组件的data、methods、properties

目录 自定义组件 - 数据、方法和属性 1. data 数据 2. methods 方法 3. properties 属性 4. data 和 properties 的区别 5. 使用 setData 修改 properties 的值 自定义组件 - 数据、方法和属性 1. data 数据 在小程序组件中&#xff0c;用于组件模板渲染的私有数据&…

MATLAB用find函数结合all,any函数高效解决问题

如本节中最后提到的问题&#xff0c;我们输出后还需要判断&#xff0c;不是特别的一目了然&#xff0c;这时候我们可以再加上 f i n d find find函数直接标记序号并输出。首先我们先来了解 f i n d find find的用法&#xff0c; f i n d ( a ) find(a) find(a)表示将矩阵或向量…

2022博客之星年度总评选开始了

作者简介&#xff1a;陶然同学 专注于Java领域开发 熟练掌握Java、js等语言的“Hello World” CSDN原力计划作者、CSDN内容合伙人、Java领域优质作者、Java领域新星作者、51CTO专家、华为云专家、阿里云专家等 &#x1f3ac; 陶然同学&#x1f3a5; 由 陶然同学 原创&#…

vue2 升级为 vite 打包

VUE2 中使用 Webpack 打包、开发&#xff0c;每次打包时间太久&#xff0c;尤其是在开发的过程中&#xff0c;本文记录一下 VUE2 升级Vite 步骤。 安装 Vue2 Vite 依赖 dev 依赖 vitejs/plugin-vue2": "^2.3.3 vitejs/plugin-vue2-jsx": "^1.1.1 vite&…

20241227在ubuntu20.04.6系统中,如何用watch命令每秒钟调用nvidia-smi来监控GPU

watch -n 1 nvidia-smi 20241227在ubuntu20.04.6系统中&#xff0c;如何用watch命令每秒钟调用nvidia-smi来监控GPU 2024/12/27 17:04 缘起&#xff1a;在ubuntu20.04.6系统中&#xff0c;使用M6000显卡来跑whisper&#xff0c;显存拉满/占用巨大&#xff0c;但是CPU占用比低&…