音视频学习(二十八):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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言程序设计:程序设计和C语言

文章目录 C语言程序设计&#xff1a;程序设计和C语言一、计算机程序和语言计算机语言C语言的发展及其特点C语言的发展历程C语言的特点 二、编译器安装三、最简单的C 语言程序简单的C语言程序介绍程序执行流程&#xff1a;输出&#xff1a; 求两个整数之和运行结果&#xff1a; …

I2C(一):存储器模式:stm32作为主机对AT24C02写读数据

存储器模式&#xff1a;在HAL库中&#xff0c;I2C有专门对存储器外设设置的库函数 I2C&#xff08;一&#xff09;&#xff1a;存储器模式的使用 1、I2C轮询式写读AT24C02一页数据2、I2C轮询式写读AT24C02多页数据3、I2C中断式写读AT24C02一页数据4、I2C使用DMA式写读AT24C02一…

发表文章去哪里投稿?软文推广常见的几种渠道类型

在互联网高度繁荣的当下&#xff0c;人们获取信息的门槛愈发降低&#xff0c;投放信息渠道的类型也五花八门。但想要获得理想的推广效果&#xff0c;信息投放渠道在其中发挥着不小的作用。发表文章去哪里投稿&#xff1f;下面就让我们来了解一下软文推广常见的几种渠道类型。 一…

QComboBox中使用树形控件进行选择

事情是这样的&#xff0c;要在一个ComboBox中通过树形结构进行内容的选择。 默认的QComboBox展开是下拉的列表。因此需要定制一下。 效果就是这样的 实现上面效果的核心代码就是下面这样的 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { treenew…

Unity 读Excel,读取xlsx文件解决方案

Unity读取表格数据 效果&#xff1a; 思路&#xff1a; Unity可以解析Json&#xff0c;但是读取Excel需要插件的帮助&#xff0c;那就把这个功能分离开&#xff0c;读表插件就只管读表转Json&#xff0c;Unity就只管Json解析&#xff0c;中间需要一个存储空间&#xff0c;使用…

Linux之ARM(MX6U)裸机篇----7.蜂鸣器实验

一&#xff0c;蜂鸣器模块 封装步骤&#xff1a; ①初始化SNVS_TAMPER这IO复用为GPIO ②设置SNVS_TAMPPER这个IO的电气属性 ③初始化GPIO ④控制GPIO输出高低电平 bsp_beep.c: #include "bsp_beep.h" #include "cc.h"/* BEEP初始化 */ void beep_init…

前端学习DAY29(1688侧边栏)

完整代码、 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>1688导航条</title><style>…

NLP模型工程化部署

文章目录 一、理论-微服务、测试与GPU1&#xff09;微服务架构2&#xff09;代码测试3&#xff09;GPU使用 二、实践-封装微服务&#xff0c;编写测试用例和脚本&#xff0c;并观察GPU1&#xff09;微服务封装(RestFul和RPC)2&#xff09;测试编写(unit_test\api_test\load_tes…

重生之我在异世界学编程之数据结构与算法:深入队列篇

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 目录 一、概述二、链表节点结构三、队列结构四、基…

在线机考|2024华为实习秋招春招编程题(最新)——第2题_订单取餐顺序_300分(五)

题目内容 肯德基店销售炸鸡、薯条、可乐三种实物,准备三种食物的速度一样,且三种食物同时制作;三种食物同时制作,按订单顺序进行分发食物。现在有N个订单,每个订单用连续三位数组元素表示,数组的元素是对应食物的份数。N最大为100万,每个订单里每份食物最多100万份。请计…

SAP SD信贷管理后台配置(上)

后台系统功能配置 1、定义信贷控制范围 说明&#xff1a; 信贷控制区域是一个控制单元&#xff0c;用于指定和检查合作伙伴的信用额度&#xff1b;信用控制区域可以包含一个或多个公司&#xff0c;但一个公司无法分配给多个信贷控制区域&#xff1b;在信用控制区域内&#x…

​虚幻引擎UE5渲染不够快的解决办法

​虚幻引擎是由Epic Games公司开发的一款功能强大、全球最开放且先进的实时 3D 创作工具&#xff0c;广泛应用于游戏、影视、建筑可视化、虚拟现实等多个领域&#xff01;虚幻引擎UE5如何实现在网上极速渲染呢&#xff1f;本文提供云渲染和云电脑两套方案用于渲染提速&#xff…

算力股开盘大涨,电光科技7连板

12 月 30 日&#xff0c;尽管北证 50 指数半日跌超 3% 再创调整新低&#xff0c;全市场超 4200 股飘绿&#xff0c;但算力概念股却逆势活跃&#xff0c;电光科技实现 7 连板。以下是对这一现象的具体分析&#xff1a; 原因分析 政策利好&#xff1a;上海近日印发《关于人工智能…

kanzi做3d时钟屏保

用kanzi做一个3d屏保 1. blender制作3d数字模型 下载一些好看的字体文件&#xff0c;用blender建模字体模型&#xff0c;导出fbx格式 2. 新建kanzi工程 导入fbx模型&#xff0c;创建节点&#xff0c;时分秒节点&#xff0c;最上面放一个按钮&#xff0c;用来点击 根据喜好…

logback之自定义pattern使用的转换器

目录 &#xff08;1&#xff09;场景介绍 &#xff08;2&#xff09;定义转换器BizCallerConverter &#xff08;3&#xff09;logback配置conversionRule &#xff08;4&#xff09;测试效果 前文《logback之pattern详解以及源码分析》已经介绍了pattern&#xff0c;以及…

QTDemo:串口调试工具

项目简介 本项目通过QT框架设计一款可以在Windows、Linux等平台的跨平台串口助手&#xff0c;串口功能能够满足基本的调试需求。 本项目采用的版本为&#xff1a;QT5.14 visual studio 2022 进行开发。 项目源码&#xff1a;https://github.com/say-Hai/MyCOMDemo 项目页面&am…

Selenium+Java(21):Jenkins发送邮件报错Not sent to the following valid addresses解决方案

问题现象 小月妹妹近期在做RobotFrameWork自动化测试,并且使用Jenkins发送测试邮件的时候,发现报错Not sent to the following valid addresses,明明各个配置项看起来都没有问题,但是一到邮件发送环节,就是发送不出去,而且还不提示太多有用的信息,急的妹妹脸都红了,于…

AI 智能助手对话系统

一个基于 React 和 Tailwind CSS 构建的现代化 AI 对话系统&#xff0c;提供流畅的用户体验和丰富的交互功能。 项目链接&#xff1a;即将开放… 功能特点 &#x1f916; 智能对话&#xff1a;支持与 AI 助手实时对话&#xff0c;流式输出回答&#x1f4c1; 文件处理&#xff…

Design Compiler:两种工作模式(线负载模式和拓扑模式)

相关阅读 Design Compilerhttps://blog.csdn.net/weixin_45791458/category_12738116.html?spm1001.2014.3001.5482 Design Compiler可以以线负载模式或拓扑模式启动&#xff0c;必须选择其中一个模式。在拓扑模式下还可使用多模式和UPF模式&#xff1a;多模式允许在多种工作…

应急响应练习

文章目录 web1web2 web1 题目要求&#xff1a; 前景需要&#xff1a; 小李在值守的过程中&#xff0c;发现有CPU占用飙升&#xff0c;出于胆子小&#xff0c;就立刻将服务器关机&#xff0c;这是他的服务器系统&#xff0c;请你找出以下内容&#xff0c;并作为通关条件&#…