rtsp+rtmp多路网页播放

article/2025/11/6 19:14:12

一、前言

  之前博主有写过 一篇博文,讲的是使用videojs在谷歌浏览器网页上播放rtmp流媒体,具体可参考我之前的博客:videojs+hls+rtmp网页播放 - 蛋片鸡 - 博客园

  最近又开始研究了一下网页播放流媒体,在这里我主要补充一些播放rtmp、rtsp流媒体的其他方法

二、rtsp和rtmp流媒体

2.1 视频传输原理

  从网络上接收视频时首先需要解协议(RTSP/RTMP/HTTP),然后是解格式(MKV,RMVB),之后才是将视频(H264)和音频(AAC)格式数据分别解码为图像(RGB/YUV)和声音(PCM),再根据时间戳同步播放

2.2 RTSP和RTMP介绍

  

  RTSP(Real Time Streaming Protocol),RFC2326,实时流传输协议,是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学、网景和RealNetworks公司提交的IETF RFC标准。该协议定义了一对多应用程序如何有效地通过IP网络传送多媒体数据。RTSP在体系结构上位于RTP和RTCP之上,它使用TCP或UDP完成数据传输。目前多数网络摄像机支持RTSP、ONVIF等通用的协议,而支持RTMP比较少

  RTMP是Real Time Messaging Protocol(实时消息传输协议)的首字母缩写。该协议基于TCP,是一个协议族,包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种。RTMP是一种设计用来进行实时数据通信的网络协议,主要用来在Flash/AIR平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信。支持该协议的软件包括Adobe Media Server/Ultrant Media Server/red5等。使用RTMP技术的流媒体系统有一个非常明显的特点:使用 Flash Player 作为播放器客户端,而Flash Player 现在已经安装在了全世界将近99%的PC上,因此一般情况下收看RTMP流媒体系统的视音频是不需要安装插件的。用户只需要打开网页,就可以直接收看流媒体,十分方便。直播服务普遍采用了RTMP作为流媒体协议,FLV作为封装格式,H.264作为视频编码格式,AAC作为音频编码格式。FLV是RTMP使用的封装格式,H.264是当今实际应用中编码效率最高的视频编码标准,AAC则是当今实际应用中编码效率最高的音频编码标准。

  RTSP和RTMP是2种不同的网络传输协议,RTSP(Real Time Streaming Protocol)是实时流传输协议,而RTMP是Real Time Messaging Protocol(实时消息传输协议)。RTSP主要用于IPTV,原因是传输数据使用的是UDP,在网络环境比较稳定的情况下,传输效率是比较高的。RTMP主要用于互联网音视频传输,它使用的是TCP传输,因为互联网环境相对较差,采用RTMP保证了视频的传输质量,但是其传输延迟相对较高,传输效率相对较低

  参考:RTSP、RTMP和HTTP协议的区别_H-KING的博客-CSDN博客

                  [总结]视音频编解码技术零基础学习方法_雷霄骅的博客-CSDN博客 (视音频编解码技术,推荐)

2.3 补充 

  RTSP直播源地址:

    rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov

三、rtsp、rtmp播放方法

3.1 videojs播放rtmp流媒体——videojs不支持rtsp——仅支持在Hbuilder等自带服务器环境下打开才可以播放rtmp

代码如下:

<!-- 播放rtmp网络视频 -->
<!DOCTYPE html>
<html><head><title>播放器</title><link href="./videolib/css/video-js.min.css" rel="stylesheet" type="text/css"><style>html,body{height: 100%;width: 100%;padding: 0;margin: 0;}</style></head><body><div><video id="myvideo1" width="350" height="250" class="video-js vjs-default-skin" muted controls><!-- rtmp视频流 --><source src="rtmp://202.69.69.180:443/webcast/bshdlive-pc" type="rtmp/flv"></video><br /><video id="myvideo2" width="350" height="250" class="video-js vjs-default-skin" muted controls><!-- rtmp视频流 --><source src="rtmp://media3.sinovision.net:1935/live/livestream" type="rtmp/flv"></video></div><script src="./videolib/js/video.min.js"></script><script src="./videolib/videojs-flash.min.js"> </script><script>var player1 = videojs("myvideo1", {}, function() {console.log("videojs播放器初始化成功")})player1.play()var player2 = videojs("myvideo2", {}, function() {console.log("videojs播放器初始化成功")})player2.play()</script></body>
</html>

效果:

3.2 flowplayerjs播放rtmp流媒体——flowplayerjs不支持rtsp——支持在本地直接打开播放rtmp

代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>rtmp直播</title><link rel="stylesheet" href="./css/video-js.css"><link rel="stylesheet" href="./css/h5splayer.css"><script src="./js/flowplayer-3.2.13.min.js"></script>
</head>
<body><div class="h5video" id="playerDiv1" style="float: left;"></div>    <div class="h5video" id="playerDiv2" style="float: left;"></div><div class="h5video" id="playerDiv3" style="float: left;"></div><script>// 播放地址var url_1 = 'rtmp://202.69.69.180:443/webcast/bshdlive-pc';var url_2 = 'rtmp://media3.sinovision.net:1935/live/livestream';var url_3 = 'rtmp://58.200.131.2:1935/livetv/hunantv';var oPlayerDiv1 = document.getElementById('playerDiv1');var    oPlayerDiv2 = document.getElementById('playerDiv2');var    oPlayerDiv3 = document.getElementById('playerDiv3');oPlayerDiv1.setAttribute("data-rtmp", url_1);oPlayerDiv1.setAttribute("href", url_1);oPlayerDiv2.setAttribute("data-rtmp", url_2);oPlayerDiv2.setAttribute("href", url_2);oPlayerDiv3.setAttribute("data-rtmp", url_3);oPlayerDiv3.setAttribute("href", url_3);var swfStr = "./swf/flowplayer-3.2.18.swf"var    obj_1 = {clip: {provider: 'rtmp',bufferLength: 0,bufferTime: 0,autoPlay: true,live: true},plugins: {rtmp: {url: "flowplayer.rtmp-3.2.13.swf",netConnectionUrl: url_1}}};const obj_2 = JSON.parse(JSON.stringify(obj_1))   //js对象的深拷贝   // JSON.stringify() 方法将 JavaScript 对象转换为字符串   JSON.parse() 方法将数据转换为 JavaScript 对象obj_2.plugins.rtmp.netConnectionUrl = url_2;const obj_3 = JSON.parse(JSON.stringify(obj_1)) obj_3.plugins.rtmp.netConnectionUrl = url_3;flowplayer('playerDiv1', swfStr, obj_1);flowplayer('playerDiv2', swfStr, obj_2);flowplayer('playerDiv3', swfStr, obj_3);</script>
</body>
</html>

效果:

 注意!!!

  1. 由于RTMP协议是在 Flash 播放器上播放的,所以对于H5的video播放器是不能直接播放的,必须要让所用浏览器支持flash,才可以播放rtmp流媒体。目前来说,谷歌浏览器是支持Flash的,但是在2020年12月后谷歌浏览器将不再支持Flash,所以以上两种方法只能暂时使用,并不是长久之计!  

  

   2. flowplayerjs不支持rtsp流媒体,浏览器原生js只支持http,基于flash的播放器也只能支持到rtmp,如果要支持rtsp需要使用c/c++插件(npapi或者activex)。videojs同样如此,不支持rtsp流媒体

3.3 python搭建flask服务器播放rtsp、rtmp流媒体

python代码如下:

from flask import Flask, render_template, Response
import cv2class VideoCamera():def __init__(self,vurl):# 通过opencv获取实时视频流self.video = cv2.VideoCapture(vurl)def __del__(self):self.video.release()def get_frame(self):success, image = self.video.read()ret, jpeg = cv2.imencode('.jpg', image)#转化为字节流return jpeg.tobytes()# app是Flask的实例,它接收包或者模块的名字作为参数,但一般都是传递__name__
app = Flask(__name__)
@app.route('/')  # 主页
def index():return render_template('index.html')@app.route('/video1_feed')  # 这个地址返回rtsp视频流响应
def video1_feed():return Response(gen1(VideoCamera("rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov")), mimetype='multipart/x-mixed-replace; boundary=frame')@app.route('/video2_feed')  # 这个地址返回rtmp视频流响应
def video2_feed():return Response(gen2(VideoCamera("rtmp://202.69.69.180:443/webcast/bshdlive-pc")), mimetype='multipart/x-mixed-replace; boundary=frame')\@app.route('/video3_feed')  # 这个地址返回rtmp视频流响应
def video3_feed():return Response(gen3(VideoCamera("rtmp://media3.sinovision.net:1935/live/livestream")), mimetype='multipart/x-mixed-replace; boundary=frame')@app.route('/video4_feed')  # 这个地址返回rtmp视频流响应
def video4_feed():return Response(gen4(VideoCamera("rtmp://58.200.131.2:1935/livetv/hunantv")), mimetype='multipart/x-mixed-replace; boundary=frame')def gen1(camera):while True:frame = camera.get_frame()yield (b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
def gen2(camera):while True:frame = camera.get_frame()yield (b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
def gen3(camera):while True:frame = camera.get_frame()yield (b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
def gen4(camera):while True:frame = camera.get_frame()yield (b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')if __name__ == '__main__':app.run(host='127.0.0.1', debug=True, port = 5000)

html代码如下:

<html><head><title>多路视频直播</title><style>html, body {height: 100%;width: 100%;padding: 0;margin: 0;}.divbg{width:300px;height:200px;}.videostyle{min-height: 100%;min-width: 100%;max-height: 100%;max-width: 100%;}</style></head><body><h2>rtsp流媒体</h2><!-- 第一个rtsp视频流 --><div class="divbg"><img  class="videostyle" src="{{ url_for('video1_feed') }}"></div><br><h2>rtmp流媒体</h2><!-- 第一个rtmp视频流 --><div class="divbg" style="float: left; margin-right: 5px;"><img class="videostyle" src="{{ url_for('video2_feed') }}"></div><!-- 第二个rtmp视频流 --><div class="divbg" style="float: left; margin-right: 5px;"><img  class="videostyle" src="{{ url_for('video3_feed') }}"></div><!-- 第三个rtmp视频流 --><div class="divbg" style="float: left;"><img class="videostyle" src="{{ url_for('video4_feed') }}"></div></body>
</html>

效果:

python控制台:

 网页效果:

 注意!!!

   python搭建一个flask服务器后,就可以播放任何格式的流媒体协议,因为flask后端直接将视频流转换为一帧一帧的图片,然后推送到网页上显示即可!但是,python搭建flask服务器播放rtsp、rtmp流媒体的缺点就是没办法播放声音,只有图片!

 源程序可到博主github上下载:https://github.com/HuerFu/h5_rtmp_play


http://chatgpt.dhexx.cn/article/Hk2TVfbn.shtml

相关文章

低延时极简RTMP播放器

RtmpPlaySdk简介 近期将项目上RTMP播放相关功能进行打包整理&#xff0c;实现了一款低延时的极简接口RTMP播放器&#xff08;Windows版和Android版&#xff09;。市面上的RTMP播放器较多&#xff0c;有开源的ijkplayer及其衍生品&#xff0c;也有收费的功能繁多的播放器&#…

rtmp 点播系统之播放器篇

rtmp (Real Time Media Protocal) ,是实时流媒体协议,由Adobe公司提出,属于半开放的协议。此协议基于flash平台的音视频点播协议。 音视的点播系统分为两部分,分别为客户端和服务端。在本文中我会先讲解如何实现一个简单的rtmp播放器。至于rtmp服务器的实现,会在下文中分析…

pgsql 使用技巧

1.CASCADE 级联删除&#xff0c;如果表或模式或数据库有序列、分区相关 依赖时&#xff0c;需要修改表或模式或数据库&#xff0c;则使用它 DROP SCHEMA viid_facestatic CASCADE 2.pgsql隐藏字段ctid&#xff0c;一般用于去重 3. pg 表自连接使用场景 3.1 有一张卡口表 求…

pgsql

这里写目录标题 pgpool安装pgsql流复制备份与恢复客户端验证服务器设置及操作服务器配置监控数据活动 PostgreSQL是以加州大学伯克利分校计算机系开发的 POSTGRES, Version 4.2为基础的对象关系型数据库管理系统(ORDBMS)。 PostgreSQL是最初伯克利代码的一个开放源码的继承者。…

pgsql基本操作

pgsql基本操作 1. 修改postgresql.conf postgresql.conf存放位置在/etc/postgresql/9.x/main下&#xff0c;这里的x取决于你安装PostgreSQL的版本号&#xff0c;编辑或添加下面一行&#xff0c;使PostgreSQL可以接受来自任意IP的连接请求。 listen_addresses *2. 修改pg_hb…

pgsql常用sql和函数

常用pgsql -- 列出所有schema select * from information_schema.schemata; -- Schema下所有表 select * from pg_tables where schemaname query_db and tablename in(port,device,res_carry_business,hardware,shelf,device_hardware_relation); -- Schema下所有索引 select…

PGSQL大小写敏感总结

PGSQL大小写敏感总结 由于PGSQL使用会出现大小写敏感的问题&#xff0c;所以在设置字段名字的时候&#xff0c;如果字段名需要大写需要加上""号来表示&#xff0c;该字段需要大写 公司业务需要我使用PGSQL创建自增主键&#xff0c;我在使用 nextval() 绑定创建的序列…

PGSQL常用操作

0. 启动pgsl数据库 pg_ctl -D /xx/pgdata start 回到顶部 1. 查看pgsl版本 pg_ctl --version 回到顶部 1. 命令行登录数据库 1 psql -U username -d dbname -h hostip -p port 回到顶部 2. 列出所有数据库 \l 回到顶部 3. 切换数据库 1 \c dbname 回到顶部 …

PL/pgSQL

1.简介 L/pgSQL是一种用于PostgreSQL数据库系统的可载入的过程语言。 可以被用来创建函数和触发器过程对SQL语言增加控制结构可以执行复杂计算继承所有用户定义类型、函数和操作符可以被定义为受服务器信任便于使用 [1]使用PL/pgSQL的优点 SQL 是一种查询语言&#xff0c;可…

Windows 10 安装配置连接PostgreSQL教程

Windows 10 安装配置连接PostgreSQL教程 1.1 PostgreSQL 下载1.2 配置环境变量1.3 PostgreSQL 初始化1.4 创建postgres用户1.5 启动postgresql1.6 客户端连接测试1.6.1 SQL Shell (psql)命令行连接测试1.6.2 客户端 pdAdmin 4 连接测试1.6.3 客户端Navicat Permium 连接测试 1.…

Spring原理-IOC控制反转

spring相关文章 Spring原理-IOC控制反转 Spring框架七大核心模块 Spring Beans原理–bean生命周期 一、Spring概述 1、 定义 Spring是一个轻量级Java开发框架&#xff0c;最早有Rod Johnson创建&#xff0c;目的是为了解决企业级应用开发复杂性。它是一个分层的JavaSE/Java…

依赖倒置和控制反转

依赖倒置 定义 依赖反转原则&#xff08;Dependency inversion principle&#xff0c;DIP&#xff09;是指一种特定的解耦形式&#xff0c;使得高层次的类不依赖于低层次的类的实现细节&#xff0c;依赖关系被颠倒&#xff08;反转&#xff09;&#xff0c;从而使得低层次类依…

Inversion of Control (IOC)控制反转 有什么好处

要了解控制反转( Inversion of Control ), 我觉得有必要先了解软件设计的一个重要思想&#xff1a;依赖倒置原则&#xff08;Dependency Inversion Principle &#xff09;。 什么是依赖倒置原则&#xff1f;假设我们设计一辆汽车&#xff1a;先设计轮子&#xff0c;然后根据…

Spring学习:IOC控制反转

一、Spring概述&#xff1a; Spring是一个开源框架&#xff0c;其存在的根本使命就是简化JAVA开发。为了降低JAVA开发的复杂性&#xff0c;Spring采取了以下四种关键策略&#xff1a; 基于POJO的最轻量级和最小侵入性编程&#xff1b;通过依赖注入和面向接口实现松耦合&#x…

控制反转(IOC)简介

IOC是Inversion of Control的缩写&#xff0c;多数书籍翻译成“控制反转”&#xff0c;还有些书籍翻译成为“控制反向”或者“控制倒置”。 1996年&#xff0c;Michael Mattson在一篇有关探讨面向对象框架的文章中&#xff0c;首先提出了IOC 这个概念。对于面向对象设计及编程…

IoC 控制反转理解

控制反转——Inversion of Control&#xff0c;缩写为IoC &#xff0c;是一个重要的面向对象编程的法则&#xff0c;说到底它是一种设计思想&#xff0c;其可以降低程序中的耦合度&#xff0c;在以前&#xff0c;我们通过new进行创建对象&#xff0c;这是程序主动去创建依赖对象…

IOC控制反转理解

1. IOC基础 IOC&#xff1a;全称Inversion Of Control&#xff0c;中文翻译是控制反转的意思。初学Spring绕不过去的一个弯&#xff0c;需要好好理解IOC的思想。网上看了很多博客&#xff0c;也看了很多网课&#xff0c;但是还是云里云雾。终于看到一个容易理解的例子&#xf…

C# IoC控制反转学习笔记

一、什么是IOC IoC-Invertion of Control&#xff0c;即控制反转&#xff0c;是一种程序设计思想。 先初步了解几个概念&#xff1a; 依赖&#xff08;Dependency&#xff09;&#xff1a;就是有联系&#xff0c;表示一个类依赖于另一个类。 依赖倒置原则&#xff08;DIP&a…

spring -- 控制反转IOC

1.IOC的理论背景 在面向对象设计的软件系统中&#xff0c;它的底层都是由N个对象构成的&#xff0c;各个对象之间通过相互合作&#xff0c;最终实现系统地业务逻辑。 图1 软件系统中耦合的对象 齿轮组中齿轮之间的啮合关系,与软件系统中对象之间的耦合关系非常相似。对象之间…

Java:控制反转

Java中自带的函数或对象都是编写软件的时候写的&#xff0c;当它需要调用你自己编写的数据的时候&#xff0c;它如何又不知道你定义的类&#xff08;对象&#xff09;是什么&#xff0c;里面有什么成员&#xff0c;它无法调用你的代码&#xff0c;这个时候就需要用到控制反转了…