草庐IT

视频直播搭建(个人记录)

eddiead 2023-08-13 原文

简易视频直播 demo 搭建

1.SRS 流媒体服务器搭建

选取 SRS 流媒体服务器的理由
https://gitee.com/ossrs/srs/wikis/v4_CN_Home

1.在 windows 环境下搭建 SRS

由于 SRS 不支持 Windows 环境下直接搭建,所以采取本地搭建 docker 再搭建 SRS 方法。
拉取 SRS 镜像
https://hub.docker.com/r/ossrs/srs/tags?page=1&ordering=last_updated

docker run -p 1935:1935 -p 1985:1985 -p 8080:8080 \
--name srs-eds1 \
ossrs/srs:latest

启动 SRS 服务器映射到 docker 端口 8080

访问 docker 地址 8080 端口

2.windows 端口映射

由于 SRS 管理页面 部署在宿主机,宿主机可通过 docker 的 ip 地址加端口访问,但其他机器无法访问,这样就需要把宿主机的端口映射到 docker 的端口,其他机器可通过宿主机 ip 加端口访问 SRS 管理页面。

1.映射 SRS 管理页面端口

netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8080 connectaddress=192.168.99.100 connectport=8080

2.映射 rtmp 端口

netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=1935 connectaddress=192.168.99.100 connectport=1935
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=1985 connectaddress=192.168.99.100 connectport=1985

至此 SRS 流媒体服务和 windows 端口映射已搭建完毕。

3.尝试直播

1.采用 OBS 推流到 SRS 服务器

2.查看推流情况

3.点击预览查看直播

2.SRS 流媒体进阶版搭建

1.实现文件共享,共享录播文件 (以下为投机取巧方法,以 docker-ToolBox 为例)

文件共享实现的方法。本地<–>虚拟机<–>docker 容器

1.打开 VirtualBox

2.设置共享文档文件夹路径,这个路径为与 docker 容器共享的路径,注意启动镜像

设置成功后重启虚拟机后输入 mount,可以看到我们新加入的共享文件夹。

3.重新运行镜像。
docker run -d --name srsVideo -p 1935:1935 -p 1985:1985 -p 8080:8080 -v /d/srsVideo:/usr/local/srs/objs/nginx/html dce4eca99585

-v 是挂载宿主机的目录 上面我们设置了虚拟机共享目录 d/srsVideo 映射到本地 D:\srsVideo,因此我们指定挂载到共享目录为 d/srsVideo。因为 srs 服务器的默认录播保存路径默认是 usr/local/srs/objs/nginx/html,所以我们将
usr/local/srs/objs/nginx/html 路径映射到 d/srsVideo。再通过虚拟机的共享目录 d/srsVideo 映射到本地 D:\srsVideo,实现文件共享功能。dce4eca99585 是镜像 id。

4.检测文件共享是否实现
进入 docker 容器下的 usr/local/srs/objs/nginx/html 目录。

查看本地 D:\srsVideo 目录

可以看到已经实现了文件共享

当然也可以通过修改配置文件修改录播文件保存的位置。

2.在项目上通过ffmpeg对直播流进行保存并保存为MP4实现录播

本地安装ffmpeg,通过命令去拉取直播rtmp流并转为MP4
ffmpeg -i rtmp://xxxx -c:v copy -c:a copy -bsf:a aac_adtstoasc /xxx/xxx.mp4

rtmp://xxx为rtmp流具体地址
/xxx 为你要保存的路径地址
例如:若为linux /xxx 可为/home/myroot/
若为windows /xxx 可为 D:/srsVideo/
xxx.mp4 为文件名
一下为ffmpeg 方法命令 具体可以自行查阅
-bsf:a 比特流过滤器:音频
aac:advanced audio coding 高级音频编码
aac_adtstoasc 从MPEG-2/4 ADTS标头创建MPEG-4 AudioSpecificConfig并删除ADTS标头(adts+es+audioSpecificConfig-adts=mp4)

另外还可以设置在规定时间内判断流是否存在而进行是否停止录播
ffmpeg -rw_timeout 500000 -i rtmp://xxx -c:v copy -c:a copy -bsf:a aac_adtstoasc /home/myroot/Live/srs/replay/eddie.mp4

-rw_timeout 500000:超时5s断流不再拉取rtmp流

温馨提示:为了解决linux和windows环境执行命令不同,执行一次终端命令就要开一个窗口

class PrintErrorReader extends Thread {
        java.io.InputStream __is = null;

        public PrintErrorReader(java.io.InputStream is) {
            __is = is;
        }

        @Override
        public void run() {
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(__is));
                String line = null;
                while ((line = br.readLine()) != null) {
                    log.info(line);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    class PrintInputStream extends Thread {
        java.io.InputStream __is = null;

        public PrintInputStream(java.io.InputStream is) {
            __is = is;
        }

        @Override
        public void run() {
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(__is));
                String line = null;
                while ((line = br.readLine()) != null) {
                    log.info(line);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

具体使用如下:

3.直播(设置推流地址后缀,推流密钥)

1.设置推流地址的后缀,如 123456,密钥可以通过后台随机生成

这样设置的好处是:录播会根据推流地址后缀生成文件夹,并且会根据推流密钥生成录播 m3u8 文件。这样方便我们获取录播文件

4.直播延迟优化方法

修改 srs.conf 文件

主要参考:https://github.com/ossrs/srs/wiki/v2_CN_LowLatency#gop-cache

min_latency:最小延迟打开,默认是打开的,该选项打开的时候,mr 默认关闭。因此这里我们选择 min_latency: on;

mr:Merged-Read,针对 RTMP 协议,为了提高性能,SRS 对于上行的 read 使用 merged-read,即 SRS 在读写时一次读取 N 毫秒的数据

mr {
enabled off;
}

mw_latency:
Merged-Write,SRS 永远使用 Merged-Write,即一次发送 N 毫秒的包给客户端。这个算法可以将 RTMP 下行的效率提升 5 倍左右,范围[350-1800]

gop_cache:

gop 是视频流中两个 I 帧的时间距离,gop 有什么影响?Flash(解码器)只有拿到 gop 才能开始解码播放。也就是说,服务器一般先给一个 I 帧给 Flash。可惜问题来了,假设 gop 是 10 秒,也就是每隔 10 秒才有关键帧
编码器调低 gop,譬如 0.5 秒一个 gop,这样延迟也很低,也不用等待。坏处是编码器压缩率会降低,图像质量没有那么好。

服务器提供配置,可以选择前面两个方案之一:SRS 就这么做,有个 gop_cache 配置项,on 就会马上播放,off 就低延迟。
因此为了降低延迟我们选择 gop_cache off;

queue_length:

配置直播队列的长度,服务器会将数据放在直播队列中,如果超过这个长度就清空到最后一个 I 帧。

tcp_nodelay:

(1)tcp_nodelay off,会增加通信的延时,但是会提高带宽利用率。在高延时、数据量大的通信场景中应该会有不错的效果

(2)tcp_nodelay on,会增加小包的数量,但是可以提高响应速度。在及时性高的通信场景中应该会有不错的效果

因此我们这边选择tcp_nodelay:on 提高响应速度直播降低延时。

5.录播时长问题

由于配置文件 hls 默认设置时长为 60 秒,多余的会被丢弃。所以我们可以通过设置 HLS 最大时长来改变录播丢失问题。由官方 wiki 文档可以获取到相关 hls 配置https://gitee.com/winlinvip/srs.oschina/wikis/v3_CN_DeliveryHLS?sort_id=1701917
因此我们修改 srs.conf

hls_window 36000: hls 视频保存最长秒数。默认 60,这里为方便实现录播功能设置为 36000 秒,

hls_cleanup off: 切换 HLS 清理,默认情况下,该功能处于打开状态。 在这种模式下,nginx 缓存管理器进程从 HLS 目录中删除旧的 HLS 片段和播放列表。 这里我们设置 off,不清除旧的 ts 文件。

hls_dispose 0: hls_dispose:HLS 清理的过期时间(秒),系统重启或者超过这个时间时,清理 HLS 的所有文件,包括 m3u8 和 ts。默认为 0,即不清理。
HLS 目录中删除旧的 HLS 片段和播放列表。 这里我们设置 off,不清除旧的 ts 文件。

hls_dispose 0: hls_dispose:HLS 清理的过期时间(秒),系统重启或者超过这个时间时,清理 HLS 的所有文件,包括 m3u8 和 ts。默认为 0,即不清理。

6. 直播平台部署坑点 Linux

1.部署

1.环境编译

1.进入 linux 服务器,选择存放 SRS 文件夹执行

git clone -b 4.0release https://gitee.com/ossrs/srs.git &&
cd srs/trunk && ./configure && make && ./objs/srs -c conf/srs.conf

获取 SRS 相关环境并进行环境编译和运行(Centos7 为例)。
如果报错(Centos8 出现的)

安装环境编译工具 执行命令 yum -y install perl-CPAN

2.SRS 服务器运行

1.可以修改任一 srs 服务器下的 conf 文件,并执行./objs/srs -c conf/xxx.conf 就可以运行自定义的配置下的服务。

2.可以选择后台运行 nohup ./objs/srs -c conf/xxx.conf。

3.端口修改

1.可以自主修改 conf 文件下的端口,注意:如果想要用 webRtc 拉流,需要注意的是:webRtc 的开放端口需要开启 udp 转发。flv,hls 需要开启端口 tcp 转发。

例如:

4.webRtc 相关坑点

1.webRtc 配置文件设置

值得注意的是:candidate 的配置。candidate 默认会配置成网卡地址,如果是自己本地内网搭建需要做端口转发。例如 本地 docker toolBox 部署默认 candidate 地址是 172.17.0.x 需要通过路由转发命令 route add 172.17.0.0 mask 255.255.0.0 192.168.99.100 把 docker 虚拟机经过的数据转发到网卡 172.17.0.x 网段内,实现拉流。

但现在部署到公网,所以我们把 candidate 设置成域名或者服务器公网 ip。也可以在拉流的时候 webrtc://项目部署地址/live/livestream?eip=服务器 ip 地址 具体设置规则可通过。部署地址可以为域名。

具体规则可以查看:https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate

本地 vhost 配置

vhost __defaultVhost__ {
gop_cache   off;
mr {
enabled off;
}
tcp_nodelay on;
rtc {
enabled on;
bframe  discard;
aac transcode;
twccon;
}
mw_latency  100;
dvr {
enabled  on;
dvr_applyall;
dvr_path ./objs/nginx/html/[app]/[stream].[timestamp].mp4;
dvr_plan session;
time_jitter  full;
}
http_remux {
enabled on;
mount   [vhost]/[app]/[stream].flv;
}
play {
mw_latency   0;
mw_msgs  0;
}
min_latency on;
}

5.webRtc 拉流格式

1.webrtc 拉流不带端口号 webrtc://SRS 服务器地址(ip 地址或域名)

有关视频直播搭建(个人记录)的更多相关文章

  1. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  2. ruby-on-rails - Rails 5 Active Record 记录无效错误 - 2

    我有两个Rails模型,即Invoice和Invoice_details。一个Invoice_details属于Invoice,一个Invoice有多个Invoice_details。我无法使用accepts_nested_attributes_forinInvoice通过Invoice模型保存Invoice_details。我收到以下错误:(0.2ms)BEGIN(0.2ms)ROLLBACKCompleted422UnprocessableEntityin25ms(ActiveRecord:4.0ms)ActiveRecord::RecordInvalid(Validationfa

  3. 动漫制作技巧如何制作动漫视频 - 2

    动漫制作技巧是很多新人想了解的问题,今天小编就来解答与大家分享一下动漫制作流程,为了帮助有兴趣的同学理解,大多数人会选择动漫培训机构,那么今天小编就带大家来看看动漫制作要掌握哪些技巧?一、动漫作品首先完成草图设计和原型制作。设计草图要有目的、有对象、有步骤、要形象、要简单、符合实际。设计图要一致性,以保证制作的顺利进行。二、原型制作是根据设计图纸和制作材料,可以是手绘也可以是3d软件创建。在此步骤中,要注意的问题是色彩和平面布局。三、动漫制作制作完成后,加工成型。完成不同的表现形式后,就要对设计稿进行加工处理,使加工的难易度降低,并得到一些基本准确的概念,以便于后续的大样、准确的尺寸制定。四、

  4. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

  5. TimeSformer:抛弃CNN的Transformer视频理解框架 - 2

    Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图

  6. ruby-on-rails - 事件记录 : Select max of limit - 2

    我正在尝试将以下SQL查询转换为ActiveRecord,它正在融化我的大脑。deletefromtablewhereid有什么想法吗?我想做的是限制表中的行数。所以,我想删除少于最近10个条目的所有内容。编辑:通过结合以下几个答案找到了解决方案。Temperature.where('id这给我留下了最新的10个条目。 最佳答案 从您的SQL来看,您似乎想要从表中删除前10条记录。我相信到目前为止的大多数答案都会如此。这里有两个额外的选择:基于MurifoX的版本:Table.where(:id=>Table.order(:id).

  7. Ruby 守护进程导致 ActiveRecord 记录器 IOError - 2

    我目前正在用Ruby编写一个项目,它使用ActiveRecordgem进行数据库交互,我正在尝试使用ActiveRecord::Base.logger记录所有数据库事件具有以下代码的属性ActiveRecord::Base.logger=Logger.new(File.open('logs/database.log','a'))这适用于迁移等(出于某种原因似乎需要启用日志记录,因为它在禁用时会出现NilClass错误)但是当我尝试运行包含调用ActiveRecord对象的线程守护程序的项目时脚本失败并出现以下错误/System/Library/Frameworks/Ruby.frame

  8. ruby-on-rails - 在 Rails 中更高效地查找或创建多条记录 - 2

    我有一个应用需要发送用户事件邀请。当用户邀请friend(用户)参加事件时,如果尚不存在将用户连接到该事件的新记录,则会创建该记录。我的模型由用户、事件和events_user组成。classEventdefinvite(user_id,*args)user_id.eachdo|u|e=EventsUser.find_or_create_by_event_id_and_user_id(self.id,u)e.save!endendend用法Event.first.invite([1,2,3])我不认为以上是完成我的任务的最有效方法。我设想了一种方法,例如Model.find_or_cr

  9. ruby - 在模块/类之间共享全局记录器 - 2

    在许多ruby​​类之间共享记录器实例的最佳(正确)方法是什么?现在我只是将记录器创建为全局$logger=Logger.new变量,但我觉得有更好的方法可以在不使用全局变量的情况下执行此操作。如果我有以下内容:moduleFooclassAclassBclassC...classZend在所有类之间共享记录器实例的最佳方式是什么?我是以某种方式在Foo模块中声明/创建记录器还是只是使用全局$logger没问题? 最佳答案 在模块中添加常量:moduleFooLogger=Logger.newclassAclassBclassC..

  10. ruby - Sinatra 中的全局救援和日志记录异常 - 2

    如何在出现异常时指定全局救援,如果您将Sinatra用于API或应用程序,您将如何处理日志记录? 最佳答案 404可以在not_found方法的帮助下处理,例如:not_founddo'Sitedoesnotexist.'end500s可以通过调用带有block的错误方法来处理,例如:errordo"Applicationerror.Plstrylater."end错误的详细信息可以通过request.env中的sinatra.error访问,如下所示:errordo'Anerroroccured:'+request.env['si

随机推荐