音视频学习(二十八):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.rhkb.cn/news/497183.html

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

相关文章

力扣矩阵-算法模版总结

lc-73.矩阵置零-(时隔14天)-12.27 思路&#xff1a;(23min22s) 1.直接遍历遇0将行列设0肯定不行&#xff0c;会影响后续判断&#xff0c;题目又要求原地算法&#xff0c;那么进一步考虑是否可以将元素为0&#xff0c;其行列需要设为0的位置给存储下来&#xff0c;最后再遍历根据…

Markov test笔记

补充知识 来源于数学之美第五章&#xff1a; 到了 19 世纪&#xff0c;概率论的发展从相对静止的随机变量的研究发展到随机变量的时间序列 ( s 1 , s 2 , s 3 , … ) (s_1, s_2, s_3, \dots) (s1​,s2​,s3​,…)&#xff0c;即随机过程&#xff08;动态的&#xff09;。这在…

DeepSpeed 使用 LoRA 训练后文件结构详解

DeepSpeed 使用 LoRA 训练后文件结构详解 在大语言模型&#xff08;LLM&#xff09;的训练过程中&#xff0c;DeepSpeed 提供了强大的分布式训练能力&#xff0c;而 LoRA&#xff08;Low-Rank Adaptation&#xff09;通过参数高效微调技术显著减少了资源占用。完成训练后&…

GitHub 桌面版配置 |可视化界面进行上传到远程仓库 | gitLab 配置【把密码存在本地服务器】

&#x1f947; 版权: 本文由【墨理学AI】原创首发、各位读者大大、敬请查阅、感谢三连 &#x1f389; 声明: 作为全网 AI 领域 干货最多的博主之一&#xff0c;❤️ 不负光阴不负卿 ❤️ 文章目录 桌面版安装包下载clone 仓库操作如下GitLab 配置不再重复输入账户和密码的两个方…

docker-开源nocodb,使用已有数据库

使用已有数据库 创建本地数据库 数据库&#xff1a;nocodb 用户&#xff1a;nocodb 密码&#xff1a;xxxxxx修改docker-compose.yml 默认网关的 IP 地址是 172.17.0.1&#xff08;适用于 bridge 网络模式&#xff09;version: "2.1" services:nocodb:environment:…

uniapp 前端解决精度丢失的问题 (后端返回分布式id)

原因&#xff1a; 后端使用分布式id, id为19位数&#xff0c;导致精度丢失 &#xff0c;前端解决方法 这个是通过浏览器请求回来的数据&#xff0c;这个时候id 数据已经丢失了&#xff0c;在数据库查询不到&#xff0c;在调获详情接口的时候会有问题 实际的&#xff1a; 解决…

SQL-leetcode-180. 连续出现的数字

180. 连续出现的数字 表&#xff1a;Logs -------------------- | Column Name | Type | -------------------- | id | int | | num | varchar | -------------------- 在 SQL 中&#xff0c;id 是该表的主键。 id 是一个自增列。 找出所有至少连续出现三次的数字。 返回的…

【教程】通过Docker运行AnythingLLM

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 官方教程&#xff1a;Local Docker Installation ~ AnythingLLM 1、先创建一个目录用于保存anythingllm的持久化文件&#xff1a; sudo mkdir /app su…

soular使用教程

用 soular 配置你的组织&#xff0c;工作更高效&#xff01;以下是快速上手的简单步骤&#xff1a; &#xfeff; 1. 账号管理 可以对账号信息进行多方面管理&#xff0c;包括分配不同的部门、用户组等&#xff0c;从而确保账号权限和职责的清晰分配。 &#xfeff; 1.1 用…

Github - 如何提交一个带有“verified”标识的commit

Github - 如何提交一个带有“verified”标识的commit 前言(Why) 今天在Github上浏览某项目的commit记录的时候发现&#xff0c;有的commit记录带有verified绿色标识&#xff0c;有的带有橘色的Unverified标识&#xff0c;还有的什么都不显示。 既然我是根正苗红的作者(bushi)…

基于Bregman的交替方向乘子法

目录标题 ADMM方法简介Bregman散度Bregman ADMM的原理主要优势代码示例&#xff1a;各个符号的解释&#xff1a;**梯度的几何含义**&#xff1a;具体数学公式&#xff1a;**应用示例**&#xff1a;**ADMM的标准形式&#xff1a;****ADMM中的变量角色&#xff1a;****ADMM中的更…

【操作系统】课程 3进程同步与通信 同步测练 章节测验

3.1知识点导图 无 3.2进程同步与互斥 【本章学习目标】 &#xff08;1&#xff09;了解进程通信的机制和通信方式。 &#xff08;2&#xff09;理解多道程序环境下进程间通信的机制&#xff1b;消息传递系统的实现。 &#xff08;3&#xff09;掌握临界资源和临界区的概念…

React中最优雅的异步请求

给大家分享在React19中使用useSuspense处理异步请求为什么是被认为最优雅的解决方案 一. 传统方案 解决异步请求的方案中&#xff0c;我们要处理至少两个最基本的逻辑 正常的数据显示数据加载的UI状态 例如&#xff1a; export default function Index(){const [content, …

《机器视觉:开启智能新时代》

《机器视觉&#xff1a;开启智能新时代》 一、机器视觉&#xff1a;工业之眼的崛起二、核心组件&#xff1a;构建精准视觉系统&#xff08;一&#xff09;光源&#xff1a;照亮视界的画笔&#xff08;二&#xff09;镜头&#xff1a;聚焦精准的慧眼&#xff08;三&#xff09;相…

STM32F103RCT6学习之四:定时器

1.基础 定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断 16位计数器、预分频器、自动重装寄存器的时基单元&#xff0c;在72MHz计数时钟下可以实现最大59.65s的定时 不仅具备基本的定时中断功能&#xff0c;而且还包含内外时钟源选择、输入捕获、…

3DMAX镂空星花球建模插件FloralStarBall使用方法

3DMAX镂空星花球建模插件FloralStarBall使用教程 就是那个3DMAX镂空星花球建模&#xff0c;再也不用手动做了&#xff0c;使用3DMAX镂空星花球建模FloralStarBall插件可以一键生成&#xff01; 3DMAX镂空星花球建模插件FloralStarBall&#xff0c;经典星形球体的美丽变体。星形…

Nginx区分PC端和移动端访问

在使用Nginx时&#xff0c;可以通过$http_user_agent变量来判断用户访问的客户端类型&#xff0c;从而提供不同的内容或服务。下面是一个基于$http_user_agent变量来判断是否为PC访问的Nginx配置示例。 1. 理解$http_user_agent变量的含义及其在Nginx中的用途 $http_user_agen…

Jmeter快速入门

目录 1.安装Jmeter 1.1.下载 1.2.解压 1.3.运行 2.快速入门 2.1.设置中文语言 2.2.基本用法 1.安装Jmeter Jmeter依赖于JDK&#xff0c;所以必须确保当前计算机上已经安装了JDK&#xff0c;并且配置了环境变量。 1.1.下载 可以Apache Jmeter官网下载&#xff0c;地址…

Ftrans数据摆渡系统 搭建安全便捷跨网文件传输通道

一、专业数据摆渡系统对企业的意义 专业的数据摆渡系统对企业具有重要意义&#xff0c;主要体现在以下几个方面‌&#xff1a; 1、‌数据安全性‌&#xff1a;数据摆渡系统通过加密传输、访问控制和审计日志等功能&#xff0c;确保数据在传输和存储过程中的安全性。 2、‌高…

Jupyter在运行上出现错误:ModuleNotFoundError: No module named ‘wordcloud‘

问题分析&#xff1a;显示Jupyter未安装这个模板 解决办法&#xff1a;在单元格内输入&#xff1a;!pip install wordcloud