前端

RTSP视频流播放原理与Web端实现技术指南

TRAE AI 编程助手

本文深入解析RTSP视频流播放的核心原理,详细阐述Web端实现的技术挑战与解决方案,为流媒体开发者提供完整的技术指南。

01|RTSP协议基础原理与工作机制

RTSP(Real Time Streaming Protocol,实时流传输协议)是TCP/IP协议体系中的应用层协议,专为娱乐和会议系统控制流媒体服务器而设计。作为流媒体传输的核心协议,RTSP提供了可扩展的框架,支持受控、按需交付实时数据。

协议架构与核心特性

RTSP采用客户端-服务器架构,默认使用554端口进行通信。协议设计借鉴了HTTP的语法和语义,但专门针对流媒体传输进行了优化:

RTSP客户端 ←→ RTSP服务器
    ↓              ↓
RTP/RTCP数据流 ←→ 媒体数据

关键特性解析:

  • 状态管理:维护会话状态,支持PLAY、PAUSE、TEARDOWN等操作
  • 传输独立性:不绑定特定传输协议,可配合TCP、UDP或组播使用
  • 可扩展性:支持通过头部字段扩展功能
  • 安全性:支持基本认证和摘要认证机制

请求-响应模型详解

RTSP的请求-响应机制与HTTP类似,但增加了对流媒体控制的特殊支持:

OPTIONS rtsp://example.com/media.mp4 RTSP/1.0\r\n
CSeq: 1\r\n
User-Agent: TRAE-RTSP-Client/1.0\r\n\r\n

服务器响应示例:

RTSP/1.0 200 OK\r\n
CSeq: 1\r\n
Public: OPTIONS, DESCRIBE, SETUP, PLAY, PAUSE, TEARDOWN\r\n\r\n

核心方法说明:

方法功能描述状态码
OPTIONS获取服务器支持的方法列表200
DESCRIBE获取媒体描述信息(SDP)200
SETUP建立媒体传输会话200
PLAY开始或继续播放媒体流200
PAUSE暂停媒体流传输200
TEARDOWN终止会话并释放资源200

会话建立流程

RTSP会话建立遵循严格的时序逻辑:

sequenceDiagram participant Client participant Server Client->>Server: OPTIONS Server->>Client: 200 OK (支持方法列表) Client->>Server: DESCRIBE Server->>Client: 200 OK (SDP描述) Client->>Server: SETUP (Transport头) Server->>Client: 200 OK (Session ID) Client->>Server: PLAY (Range头) Server->>Client: 200 OK (开始传输) Note over Client,Server: RTP/RTCP数据流传输 Client->>Server: TEARDOWN Server->>Client: 200 OK (会话结束)

TRAE IDE优势提示:在TRAE IDE中,您可以使用内置的网络调试工具实时监控RTSP通信过程,通过智能代码补全快速构建协议处理逻辑,大幅提升流媒体应用开发效率。

02|RTSP与RTP/RTCP的协作机制

RTSP、RTP(Real-time Transport Protocol)和RTCP(RTP Control Protocol)构成了完整的流媒体传输体系。理解三者间的协作关系是实现高质量视频流播放的关键。

协议层次与职责分工

应用层:RTSP(控制信令)
传输层:RTP(媒体数据) + RTCP(质量控制)
网络层:UDP/TCP(传输载体)

RTP协议核心功能:

  • 媒体数据封装与传输
  • 时间戳同步机制
  • 序列号保证数据包顺序
  • 负载类型标识编码格式

RTCP协议监控职责:

  • 传输质量统计与反馈
  • 参与者信息维护
  • 媒体同步信息传递
  • 拥塞控制支持

数据流协作流程

当RTSP建立会话后,RTP/RTCP数据流开始工作:

graph TD A[RTSP PLAY命令] --> B[服务器开始RTP传输] B --> C[RTP数据包发送] C --> D[客户端接收与缓存] E[RTCP周期报告] --> F[质量统计] F --> G[自适应调整] G --> H[码率/分辨率调节] style A fill:#e1f5fe style H fill:#f3e5f5

RTP数据包结构解析

RTP数据包头部包含关键控制信息:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X|  CC   |M|     PT      |       sequence number         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           timestamp                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           synchronization source (SSRC) identifier            |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|            contributing source (CSRC) identifiers             |
|                             ....                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

关键字段说明:

  • Version (V):RTP版本号,固定为2
  • Padding (P):填充标志位
  • Extension (X):扩展头标志位
  • CSRC Count (CC):CSRC标识符数量
  • Marker (M):标记位,标识重要事件
  • Payload Type (PT):负载类型,定义编码格式
  • Sequence Number:序列号,用于丢包检测
  • Timestamp:时间戳,用于媒体同步

RTCP反馈机制

RTCP通过定期发送控制包来维持传输质量:

// RTCP接收报告解析示例
function parseReceiverReport(packet) {
    const report = {
        ssrc: packet.readUInt32BE(0),
        fractionLost: packet.readUInt8(4),
        cumulativeLost: packet.readUInt24BE(5),
        highestSeq: packet.readUInt32BE(8),
        jitter: packet.readUInt32BE(12),
        lsr: packet.readUInt32BE(16),
        dlsr: packet.readUInt32BE(20)
    };
    
    // 计算网络质量指标
    const quality = {
        packetLossRate: report.fractionLost / 256,
        jitterMs: report.jitter / 90, // 假设90kHz时钟
        roundTripTime: calculateRTT(report.lsr, report.dlsr)
    };
    
    return { report, quality };
}

03|Web端播放RTSP流的技术挑战

将RTSP流直接播放在Web浏览器中面临多重技术障碍,需要深入理解浏览器安全模型和流媒体技术限制。

浏览器原生支持限制

现代浏览器出于安全考虑,原生不支持RTSP协议。这一限制源于以下因素:

安全沙箱机制:

  • 浏览器禁止直接访问非HTTP协议
  • 防止恶意网站访问本地网络资源
  • 限制对原始网络套接字的访问

媒体格式兼容性:

浏览器支持格式:MP4 (H.264/AAC)、WebM (VP8/VP9/Opus)
RTSP常见格式:H.264、H.265、MPEG-4、MJPEG

实时性要求挑战

Web应用对延迟极其敏感,传统HTTP渐进式下载无法满足需求:

应用场景可接受延迟技术挑战
视频监控< 500ms低延迟传输
视频会议< 150ms唇音同步
直播互动< 3s大规模并发
云游戏< 50ms高码率传输

网络环境复杂性

Web应用必须适应多样化的网络条件:

// 网络自适应算法示例
class NetworkAdaptation {
    constructor() {
        this.metrics = {
            bandwidth: 0,
            packetLoss: 0,
            rtt: 0,
            jitter: 0
        };
        this.qualityLevels = [
            { bitrate: 500000, resolution: '640x480' },
            { bitrate: 1000000, resolution: '1280x720' },
            { bitrate: 2500000, resolution: '1920x1080' }
        ];
    }
    
    adaptQuality() {
        const { bandwidth, packetLoss } = this.metrics;
        
        if (packetLoss > 0.05) {
            // 高丢包率,降低码率
            return this.getLowerQuality();
        } else if (bandwidth > 2000000) {
            // 带宽充足,提升质量
            return this.getHigherQuality();
        }
        
        return this.currentQuality;
    }
}

跨平台兼容性难题

不同浏览器和操作系统对媒体技术的支持存在差异:

WebRTC兼容性矩阵:

Chrome 23+    ✓ 完整支持
Firefox 22+   ✓ 基本支持  
Safari 11+    ✓ 部分支持
Edge 12+      ✓ 完整支持
IE            ✗ 不支持

解决方案策略:

  • 多技术栈fallback机制
  • 特性检测而非浏览器检测
  • 渐进式增强设计

TRAE IDE开发建议:利用TRAE IDE的智能提示功能,可以快速识别不同浏览器的API兼容性,通过内置的polyfill建议确保代码在各平台的稳定运行。

04|主流解决方案深度对比

针对Web端RTSP播放的技术挑战,业界发展出多种解决方案。每种方案都有其适用场景和技术权衡。

方案一:服务器端转码(HLS/DASH)

技术原理: 服务器将RTSP流转码为HTTP自适应流格式,客户端通过标准HTTP请求获取分片数据。

# Nginx-RTMP配置示例
rtmp {
    server {
        listen 1935;
        application live {
            live on;
            
            # RTSP源转码
            exec ffmpeg -i rtsp://camera_ip/stream 
                       -c:v libx264 -c:a aac 
                       -f flv rtmp://localhost/live/stream;
                       
            # HLS输出
            hls on;
            hls_path /tmp/hls;
            hls_fragment 3s;
            hls_playlist_length 60s;
        }
    }
}

优势分析:

  • ✅ 浏览器原生支持,无需插件
  • ✅ 自适应码率,网络适应性强
  • ✅ CDN友好,支持大规模分发

劣势分析:

  • ❌ 延迟较高(通常5-30秒)
  • ❌ 服务器资源消耗大
  • ❌ 实时交互性差

方案二:WebRTC实时传输

技术架构: 通过WebRTC的P2P传输能力,实现低延迟的媒体传输。

// WebRTC连接建立流程
class RTSPWebRTCPlayer {
    constructor() {
        this.pc = new RTCPeerConnection({
            iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
        });
        this.ws = null;
        this.mediaStream = null;
    }
    
    async start(url) {
        // 1. 建立WebSocket信令通道
        this.ws = new WebSocket('wss://media-server/signaling');
        
        // 2. 创建媒体流
        this.mediaStream = new MediaStream();
        
        // 3. 处理ICE候选
        this.pc.onicecandidate = (event) => {
            if (event.candidate) {
                this.ws.send(JSON.stringify({
                    type: 'candidate',
                    candidate: event.candidate
                }));
            }
        };
        
        // 4. 处理远程流
        this.pc.ontrack = (event) => {
            this.mediaStream.addTrack(event.track);
            videoElement.srcObject = this.mediaStream;
        };
        
        // 5. 创建并发送offer
        const offer = await this.pc.createOffer();
        await this.pc.setLocalDescription(offer);
        this.ws.send(JSON.stringify({ type: 'offer', sdp: offer }));
    }
}

性能对比:

指标HLSWebRTCWebSocket
延迟5-30s100-500ms1-3s
兼容性100%90%+100%
服务器负载中等
开发复杂度中等

方案三:WebSocket代理传输

实现原理: 通过WebSocket建立全双工通信,将RTSP数据封装后传输到客户端。

// WebSocket媒体传输客户端
class WebSocketMediaPlayer {
    constructor(canvasId) {
        this.canvas = document.getElementById(canvasId);
        this.ctx = this.canvas.getContext('2d');
        this.ws = null;
        this.decoder = new H264Decoder();
        this.frameQueue = [];
    }
    
    connect(url) {
        this.ws = new WebSocket(url);
        this.ws.binaryType = 'arraybuffer';
        
        this.ws.onmessage = async (event) => {
            const data = new Uint8Array(event.data);
            
            if (data[0] === 0x00 && data[1] === 0x00) {
                // H.264 NAL单元
                const frame = await this.decoder.decode(data);
                this.renderFrame(frame);
            }
        };
    }
    
    renderFrame(frame) {
        // 将解码后的帧绘制到canvas
        const imageData = this.ctx.createImageData(frame.width, frame.height);
        imageData.data.set(frame.data);
        this.ctx.putImageData(imageData, 0, 0);
    }
}

方案选型决策矩阵

决策因素权重分析:
┌─────────────────┬────────┬────────┬────────┐
│     场景        │ 延迟   │ 兼容性 │ 成本   │
├─────────────────┼────────┼────────┼────────┤
│ 视频监控        │ 中     │ 高     │ 中     │
│ 视频会议        │ 高     │ 中     │ 中     │
│ 直播娱乐        │ 低     │ 高     │ 低     │
│ 在线教育        │ 中     │ 高     │ 低     │
│ 云游戏          │ 高     │ 中     │ 高     │
└─────────────────┴────────┴────────┴────────┘

推荐方案:

  • 延迟敏感场景:WebRTC + 服务器中转
  • 兼容性优先:HLS/DASH转码
  • 平衡方案:WebSocket代理 + MSE

05|基于WebRTC的完整实现方案

WebRTC作为现代浏览器的实时通信标准,为RTSP流播放提供了最优的技术路径。本节将详细介绍完整的实现架构和代码实现。

系统架构设计

graph TB A[IP Camera] -->|RTSP| B[媒体网关] B -->|WebRTC| C[STUN/TURN] B -->|信令| D[信令服务器] C -->|P2P| E[Web客户端] D -->|WebSocket| E subgraph "媒体网关" B1[RTSP客户端] B2[编解码器] B3[WebRTC端点] end style A fill:#e8f5e9 style E fill:#e3f2fd

媒体网关实现

媒体网关负责RTSP到WebRTC的协议转换,是整个系统的核心组件:

// 基于Node.js的媒体网关实现
const { RTSPClient } = require('rtsp-client');
const { NodeMediaServer } = require('node-media-server');
const { WebSocketServer } = require('ws');
 
class MediaGateway {
    constructor(config) {
        this.config = config;
        this.rtspClients = new Map();
        this.webrtcEndpoints = new Map();
        this.signalingServer = null;
    }
    
    async initialize() {
        // 初始化WebSocket信令服务器
        this.signalingServer = new WebSocketServer({ 
            port: this.config.signalingPort 
        });
        
        this.signalingServer.on('connection', (ws, req) => {
            this.handleSignalingConnection(ws, req);
        });
        
        console.log(`信令服务器启动,端口: ${this.config.signalingPort}`);
    }
    
    async handleSignalingConnection(ws, req) {
        const streamId = this.extractStreamId(req.url);
        
        ws.on('message', async (message) => {
            try {
                const data = JSON.parse(message);
                await this.handleSignalingMessage(ws, streamId, data);
            } catch (error) {
                console.error('信令消息处理失败:', error);
                ws.send(JSON.stringify({ 
                    type: 'error', 
                    message: error.message 
                }));
            }
        });
    }
    
    async handleSignalingMessage(ws, streamId, data) {
        switch (data.type) {
            case 'watch':
                await this.startStreaming(ws, streamId, data.rtspUrl);
                break;
            case 'webrtc_offer':
                await this.handleWebRTCOffer(ws, streamId, data.offer);
                break;
            case 'webrtc_candidate':
                await this.handleWebRTCCandidate(ws, streamId, data.candidate);
                break;
            case 'stop':
                await this.stopStreaming(streamId);
                break;
        }
    }
    
    async startStreaming(ws, streamId, rtspUrl) {
        // 创建RTSP客户端
        const rtspClient = new RTSPClient();
        
        try {
            // 连接到RTSP源
            await rtspClient.connect(rtspUrl);
            
            // 获取媒体描述
            const sdp = await rtspClient.describe();
            
            // 设置传输参数
            await rtspClient.setup({
                transport: 'RTP/AVP/TCP;unicast;interleaved=0-1'
            });
            
            // 开始接收RTP数据
            await rtspClient.play();
            
            // 创建WebRTC端点
            const webrtcEndpoint = await this.createWebRTCEndpoint(streamId);
            
            // 建立数据转发
            this.setupDataForwarding(rtspClient, webrtcEndpoint);
            
            // 存储连接引用
            this.rtspClients.set(streamId, rtspClient);
            this.webrtcEndpoints.set(streamId, webrtcEndpoint);
            
            ws.send(JSON.stringify({
                type: 'streaming_started',
                streamId: streamId
            }));
            
        } catch (error) {
            console.error('流媒体启动失败:', error);
            throw new Error(`无法连接到RTSP源: ${error.message}`);
        }
    }
    
    setupDataForwarding(rtspClient, webrtcEndpoint) {
        // 处理RTP视频数据
        rtspClient.on('videoData', (rtpPacket) => {
            // 提取H.264数据
            const h264Data = this.extractH264FromRTP(rtpPacket);
            
            // 转发到WebRTC
            if (h264Data) {
                webrtcEndpoint.sendVideoFrame(h264Data);
            }
        });
        
        // 处理RTP音频数据
        rtspClient.on('audioData', (rtpPacket) => {
            const audioData = this.extractAudioFromRTP(rtpPacket);
            if (audioData) {
                webrtcEndpoint.sendAudioFrame(audioData);
            }
        });
    }
    
    async createWebRTCEndpoint(streamId) {
        // 这里应该集成实际的WebRTC库,如node-webrtc
        // 简化示例返回模拟端点
        return {
            sendVideoFrame: (data) => this.handleVideoFrame(streamId, data),
            sendAudioFrame: (data) => this.handleAudioFrame(streamId, data)
        };
    }
}
 
// 启动媒体网关
const gateway = new MediaGateway({
    signalingPort: 8080,
    mediaPortRange: {
        min: 10000,
        max: 20000
    }
});
 
gateway.initialize().then(() => {
    console.log('媒体网关启动成功');
}).catch(error => {
    console.error('媒体网关启动失败:', error);
});

Web客户端实现

客户端负责与媒体网关建立WebRTC连接并渲染媒体流:

// WebRTC客户端播放器
class RTSPWebRTCPlayer {
    constructor(config) {
        this.config = config;
        this.pc = null;
        this.ws = null;
        this.videoElement = null;
        this.mediaStream = null;
        this.iceCandidates = [];
        this.connectionState = 'disconnected';
        
        // WebRTC配置
        this.rtcConfig = {
            iceServers: [
                { urls: 'stun:stun.l.google.com:19302' },
                { urls: 'stun:stun1.l.google.com:19302' }
            ],
            iceCandidatePoolSize: 10,
            bundlePolicy: 'max-bundle',
            rtcpMuxPolicy: 'require'
        };
    }
    
    async initialize(videoElement) {
        this.videoElement = videoElement;
        
        // 建立信令连接
        await this.connectSignaling();
        
        // 创建WebRTC连接
        this.createPeerConnection();
        
        console.log('播放器初始化完成');
    }
    
    connectSignaling() {
        return new Promise((resolve, reject) => {
            const wsUrl = `wss://${this.config.gatewayHost}:${this.config.gatewayPort}`;
            this.ws = new WebSocket(wsUrl);
            
            this.ws.onopen = () => {
                console.log('信令通道已建立');
                resolve();
            };
            
            this.ws.onmessage = async (event) => {
                const message = JSON.parse(event.data);
                await this.handleSignalingMessage(message);
            };
            
            this.ws.onerror = (error) => {
                console.error('信令通道错误:', error);
                reject(error);
            };
            
            this.ws.onclose = () => {
                console.log('信令通道已关闭');
                this.connectionState = 'disconnected';
            };
        });
    }
    
    createPeerConnection() {
        this.pc = new RTCPeerConnection(this.rtcConfig);
        
        // 处理ICE候选
        this.pc.onicecandidate = (event) => {
            if (event.candidate) {
                this.sendSignalingMessage({
                    type: 'webrtc_candidate',
                    candidate: event.candidate
                });
            }
        };
        
        // 处理连接状态变化
        this.pc.onconnectionstatechange = () => {
            this.connectionState = this.pc.connectionState;
            console.log('连接状态:', this.connectionState);
            
            if (this.connectionState === 'connected') {
                this.onConnected();
            } else if (this.connectionState === 'failed') {
                this.onConnectionFailed();
            }
        };
        
        // 处理远程媒体流
        this.pc.ontrack = (event) => {
            console.log('接收到媒体轨道:', event.track.kind);
            
            if (!this.mediaStream) {
                this.mediaStream = new MediaStream();
                this.videoElement.srcObject = this.mediaStream;
            }
            
            this.mediaStream.addTrack(event.track);
        };
        
        // 处理ICE连接状态
        this.pc.oniceconnectionstatechange = () => {
            console.log('ICE连接状态:', this.pc.iceConnectionState);
        };
    }
    
    async play(rtspUrl) {
        if (this.connectionState !== 'disconnected') {
            throw new Error('播放器当前状态无法开始播放');
        }
        
        try {
            // 发送观看请求
            this.sendSignalingMessage({
                type: 'watch',
                rtspUrl: rtspUrl
            });
            
            // 创建并发送offer
            await this.createAndSendOffer();
            
        } catch (error) {
            console.error('播放启动失败:', error);
            throw error;
        }
    }
    
    async createAndSendOffer() {
        try {
            // 创建offer
            const offer = await this.pc.createOffer({
                offerToReceiveVideo: true,
                offerToReceiveAudio: true
            });
            
            // 设置本地描述
            await this.pc.setLocalDescription(offer);
            
            // 等待ICE收集完成(可选优化)
            await this.waitForIceGathering();
            
            // 发送offer到服务器
            this.sendSignalingMessage({
                type: 'webrtc_offer',
                offer: this.pc.localDescription
            });
            
        } catch (error) {
            console.error('创建offer失败:', error);
            throw error;
        }
    }
    
    async handleSignalingMessage(message) {
        switch (message.type) {
            case 'streaming_started':
                console.log('流媒体已开始:', message.streamId);
                break;
                
            case 'webrtc_answer':
                await this.handleAnswer(message.answer);
                break;
                
            case 'webrtc_candidate':
                await this.handleCandidate(message.candidate);
                break;
                
            case 'error':
                console.error('服务器错误:', message.message);
                this.onError(message.message);
                break;
        }
    }
    
    async handleAnswer(answer) {
        try {
            await this.pc.setRemoteDescription(answer);
            console.log('远程描述设置完成');
        } catch (error) {
            console.error('处理answer失败:', error);
        }
    }
    
    async handleCandidate(candidate) {
        try {
            await this.pc.addIceCandidate(candidate);
        } catch (error) {
            console.error('添加ICE候选失败:', error);
        }
    }
    
    waitForIceGathering() {
        return new Promise((resolve) => {
            if (this.pc.iceGatheringState === 'complete') {
                resolve();
                return;
            }
            
            this.pc.onicegatheringstatechange = () => {
                if (this.pc.iceGatheringState === 'complete') {
                    resolve();
                }
            };
        });
    }
    
    sendSignalingMessage(message) {
        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
            this.ws.send(JSON.stringify(message));
        }
    }
    
    stop() {
        this.sendSignalingMessage({ type: 'stop' });
        
        if (this.pc) {
            this.pc.close();
            this.pc = null;
        }
        
        if (this.mediaStream) {
            this.mediaStream.getTracks().forEach(track => track.stop());
            this.mediaStream = null;
        }
        
        this.connectionState = 'disconnected';
        
        if (this.videoElement) {
            this.videoElement.srcObject = null;
        }
    }
    
    onConnected() {
        console.log('WebRTC连接已建立');
        // 可以触发UI更新等操作
    }
    
    onConnectionFailed() {
        console.error('WebRTC连接失败');
        // 可以触发重连机制或错误提示
    }
    
    onError(error) {
        console.error('播放器错误:', error);
        // 处理错误情况
    }
}
 
// 使用示例
const player = new RTSPWebRTCPlayer({
    gatewayHost: 'media-server.example.com',
    gatewayPort: 8080
});
 
// 初始化播放器
await player.initialize(document.getElementById('videoElement'));
 
// 开始播放
player.play('rtsp://camera.example.com/stream').then(() => {
    console.log('播放已开始');
}).catch(error => {
    console.error('播放失败:', error);
});

性能监控与优化

实时监控连接质量和性能指标:

// WebRTC统计信息收集
class WebRTCMonitor {
    constructor(peerConnection) {
        this.pc = peerConnection;
        this.metrics = {
            inbound: {},
            outbound: {},
            candidate: {}
        };
        this.startMonitoring();
    }
    
    async startMonitoring() {
        setInterval(async () => {
            const stats = await this.pc.getStats();
            this.processStats(stats);
        }, 1000);
    }
    
    processStats(stats) {
        stats.forEach(report => {
            switch (report.type) {
                case 'inbound-rtp':
                    this.processInboundRTP(report);
                    break;
                case 'outbound-rtp':
                    this.processOutboundRTP(report);
                    break;
                case 'candidate-pair':
                    this.processCandidatePair(report);
                    break;
            }
        });
        
        this.updateMetrics();
    }
    
    processInboundRTP(report) {
        if (report.mediaType === 'video') {
            this.metrics.inbound.video = {
                packetsReceived: report.packetsReceived,
                bytesReceived: report.bytesReceived,
                packetsLost: report.packetsLost,
                jitter: report.jitter,
                frameWidth: report.frameWidth,
                frameHeight: report.frameHeight,
                framesPerSecond: report.framesPerSecond
            };
        }
    }
    
    updateMetrics() {
        // 计算关键性能指标
        const video = this.metrics.inbound.video;
        if (video) {
            const packetLossRate = video.packetsLost / 
                (video.packetsReceived + video.packetsLost);
            
            console.log('视频质量指标:', {
                packetLossRate: (packetLossRate * 100).toFixed(2) + '%',
                jitter: video.jitter.toFixed(2) + 'ms',
                resolution: `${video.frameWidth}x${video.frameHeight}`,
                fps: video.framesPerSecond
            });
        }
    }
}

TRAE IDE开发优势:TRAE IDE提供了完整的WebRTC调试工具,可以实时查看ICE候选状态、带宽使用情况和编解码器性能,帮助开发者快速定位和解决连接问题。同时,智能代码分析功能可以自动检测潜在的内存泄漏和性能瓶颈。

(此内容由 AI 辅助生成,仅供参考)