FFmpeg学习笔记(一):实现rtsp推流rtmp以及ffplay完成拉流操作

简介: 这篇博客介绍了如何使用FFmpeg实现RTSP推流到RTMP服务器,并使用ffplay进行拉流操作,包括在Windows和Linux系统下的命令示例,以及如何通过HTML页面显示视频流。

了解

什么是RTSP?https://baike.baidu.com/item/RTSP/1276768?fr=aladdin
什么是RTMP?https://baike.baidu.com/item/rtmp/6113614?fr=aladdin
什么是ffmpeg?https://baike.baidu.com/item/ffmpeg/2665727?fr=aladdin
什么是nginx?https://baike.baidu.com/item/nginx/3817705?fr=aladdin

ffmpeg安装

ffmpeg的下载地址:https://www.gyan.dev/ffmpeg/builds/packages/ffmpeg-4.4-full_build.7z
下载后放入固定盘进行解压,把E:\ffmpeg\bin放入到系统环境变量下, 按win+R打开命令行窗口,输入ffmpeg -version,查看是否安装成功
在这里插入图片描述

Nginx安装

  • 1.配置nginx文件,在conf文件夹里面有一个nginx-win.conf文件,将文件改名为nginx.conf,然后里面配置文件如下:
    在这里插入图片描述

多加了下面这个代码,为了监听rtmp流的,这样才能正常拉流。
推流:指的是把采集阶段封包好的内容传输到服务器的过程。
拉流:是指服务器已有直播内容,用指定地址进行拉取的过程

  • 2.使用cmd命令启动nginx,在命令窗口进入之前解压的文件夹根目录,然后输入start nginx.exe,会弹出一个窗口,闪一下就关闭
  • 3.然后在任务管理器的进程管理中,可以看到nginx.exe正在运行,到此nginx搭建完毕。 在这里插入图片描述
  • 在浏览器输入localhost或者127.0.0.1或者本机的IP地址,弹出如下页面表示搭建成功。
    在这里插入图片描述

rtsp转rtmp(终端显示)

  • rtsp://admin:a12345678@10.16.55.150:555//Streaming/Channels/1
    rtsp://用户名:密码@摄像头IP地址:摄像头端口号//Streaming/Channels/1

  • rtmp://localhost:1935/live/1
    rtmp://输出IP地址:端口号/live/1,这里的端口号/live/1需要和拉流的保持一致,如果你需要将视频流传到另一台电脑,那么只需要输入对应电脑下的IP地址即可,端口号和后面可保持不变。然后通过另一台来接收

windows转换代码如下:

# 本机拉流
ffmpeg -re -rtsp_transport tcp -i "rtsp://admin:a12345678@10.16.55.150:555//Streaming/Channels/1" -f flv -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -flvflags no_duration_filesize  -s 1280x720 -q 10 "rtmp://localhost:1935/live/1"
# 其它机器拉流
ffmpeg -re -rtsp_transport tcp -i "rtsp://admin:a12345678@10.16.55.150:555//Streaming/Channels/1" -f flv -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 "rtmp://10.16.55.26:1935/live/1"

windows接收代码如下:

# 本机拉流和其它机器拉流
ffplay “rtmp://127.0.0.1:1935/live/1”

linux转换/接收代码如下:

ffmpeg -re -rtsp_transport tcp -i "rtsp://admin:a12345678@10.16.58.150:555//Streaming/Channels/1" -f flv -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 "rtmp://localhost:1935/live/1"

ffmpeg -re -rtsp_transport tcp -i "rtsp://admin:a12345678@10.16.58.150:555//Streaming/Channels/1" -f flv -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 "rtmp://localhost:1935/live/1"

export DBUS_FATAL_WARNINGS=0
ffplay "rtmp://localhost:1935/live/1"

ps  -ef | grep nginx
netstat -ano|grep 1935
/usr/local/nginx/nginx -s reload
/usr/local/nginx/nginx -s stop
/usr/local/nginx/nginx

rtsp转rtmp(htlm显示)

转换代码如下:

ffmpeg -re -stream_loop -1  -rtsp_transport tcp -i  "rtsp://admin:a12345678@10.16.55.150:555//Streaming/Channels/1" -tune zerolatency -vcodec libx264 -preset ultrafast -b:v 400k -s 720x576 -r 25 -acodec libfaac -b:a 64k -f flv  "rtmp://10.16.59.231:1935/live/1"

接收代码如下:

ffplay “rtmp://127.0.0.1:1935/live/1”

or通过下面这个代码直接打开对应的网页

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Video.js | HTML5 Video Player</title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/video.js/7.3.0/video-js.min.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/video.js/7.3.0/video.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/videojs-flash@2/dist/videojs-flash.min.js"></script>

  </head>
  <body width="640px" height="360px">
    <video
      id="example_video_1"
      class="video-js vjs-default-skin"
      controls
      preload="auto"
      width="640px"
      height="360px"
      data-setup="{}"
      style="float: left"
    >
      <source src="rtmp://127.0.0.1:1935/live/1" type="rtmp/flv" />
      <p class="vjs-no-js">
        To view this video please enable JavaScript, and consider upgrading to a
        web browser that
        <a href="http://videojs.com/html5-video-support/" target="_blank"
          >supports HTML5 video</a
        >
      </p>
    </video>
  </body>
</html>

结果如下图:
在这里插入图片描述
在这里插入图片描述

多个rtsp转rtmp(结合cmd运行)

  • 思路
    opencv读取视频 —> 将视频分割为帧 —> 将每一帧进行需求加工后 —> 将此帧写入pipe管道(放共享文件的地方) —> 利用ffmpeg进行推流直播
import cv2
import subprocess as sp
url = 'rtsp://admin:a12345678@10.16.55.150:555/h264/ch1/main/av_stream'
ur2 = 'rtsp://admin:a12345678@10.16.55.149:554/h264/ch1/main/av_stream'
# cap = cv2.VideoCapture("rtsp://" + UserName + ":" + PassW + "@" + IpAddr + ":" + Port + "/Streaming/Channels/1")
# 摄像头是否处于打开状态可以通过isOpened()方法进行判断
cap = cv2.VideoCapture(url)
cap1 = cv2.VideoCapture(ur2)
ret, frame = cap.read()
ret1, frame1 = cap1.read()
# 视频属性 自定义设定
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
sizeStr = str(size[0]) + 'x' + str(size[1])
fps = int(cap.get(cv2.CAP_PROP_FPS))  # 30p/self
hz = int(1000.0 / fps)
print('size:'+ sizeStr + ' fps:' + str(fps) + ' hz:' + str(hz))
# 视频属性 自定义设定
size1 = (int(cap1.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap1.get(cv2.CAP_PROP_FRAME_HEIGHT)))
sizeStr1 = str(size1[0]) + 'x' + str(size1[1])
fps1 = int(cap1.get(cv2.CAP_PROP_FPS))  # 30p/self
hz1 = int(1000.0 / fps1)
print('size:'+ sizeStr1 + ' fps:' + str(fps1) + ' hz:' + str(hz1))
# ffmpeg推送rtmp 重点 : 通过管道 共享数据的方式 将图片帧 通过ffmpeg上传到服务器 上
command="ffmpeg -re -rtsp_transport tcp -i \"rtsp://admin:a12345678@10.16.55.149:554//Streaming/Channels/1\" -f flv -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 5 \"rtmp://localhost:1935/live/2"""
command1="ffmpeg -re -rtsp_transport tcp -i \"rtsp://admin:a12345678@10.16.55.150:555//Streaming/Channels/1\" -f flv -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 5 \"rtmp://localhost:1935/live/1"""
#管道特性配置 按需测试优化
# pipe = sp.Popen(command, stdout = sp.PIPE, bufsize=10**8)
# print(command)
pipe = sp.Popen(command, stdin=sp.PIPE) #,shell=False
pipe1 = sp.Popen(command1, stdin=sp.PIPE) #,shell=False
while ret:
    ret, frame = cap.read()
    ret1, frame1 = cap1.read()
    # cv2.imshow("frame",frame)
    pipe.stdin.write(frame.tostring())  # 存入管道用于直播
    pipe.stdin.write(frame1.tostring())  # 存入管道用于直播
    # if cv2.waitKey(1) & 0xFF == ord('q'):
    #     break
# cv2.destroyAllWindows()
cap.release()
cap1.release()

运行结果:
在这里插入图片描述
到这里推流成功,后面通过ffplay进行拉流,拉流的话这就取决于你设置的推理后面的IP地址,如果是本机,那么就可以直接通过本机的终端执行

ffplay “rtmp://127.0.0.1:1935/live/1”
或者
ffplay “rtmp://127.0.0.1:1935/live/2”

这里的1和2根据你前面rtsp后面部分设置的有关

执行效果如下:
在这里插入图片描述
上面这个代码由于是同步的关系很容易报存入管道的错误,你可以采用多线程的方式,多线程的方式可以看这篇博客
https://blog.csdn.net/m0_51004308/article/details/117487630

目录
相关文章
|
1天前
|
网络协议 应用服务中间件 nginx
FFmpeg错误笔记(一):nginx-rtmp-module推流出现 Server error: Already publishing
这篇文章讨论了在使用nginx-rtmp-module进行RTMP推流时遇到的“Server error: Already publishing”错误,分析了错误原因,并提供了详细的解决办法,包括修改nginx配置文件和终止异常的TCP连接。
15 0
FFmpeg错误笔记(一):nginx-rtmp-module推流出现 Server error: Already publishing
|
1天前
|
存储 编解码 网络协议
FFmpeg学习笔记(三):FFmpeg和FFplay参数介绍
这篇文章是关于FFmpeg和FFplay参数的介绍,包括如何使用这些参数进行视频流的捕获、处理和播放。
10 0
|
1天前
FFmpeg学习笔记(二):多线程rtsp推流和ffplay拉流操作,并储存为多路avi格式的视频
这篇博客主要介绍了如何使用FFmpeg进行多线程RTSP推流和ffplay拉流操作,以及如何将视频流保存为多路AVI格式的视频文件。
16 0
|
4天前
|
XML 开发工具 Android开发
FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频
ExoPlayer最初是为了解决Android早期MediaPlayer控件对网络视频兼容性差的问题而推出的。现在,Android官方已将其升级并纳入Jetpack的Media3库,使其成为音视频操作的统一引擎。新版ExoPlayer支持多种协议,解决了设备和系统碎片化问题,可在整个Android生态中一致运行。通过修改`build.gradle`文件、布局文件及Activity代码,并添加必要的权限,即可集成并使用ExoPlayer进行网络视频播放。具体步骤包括引入依赖库、配置播放界面、编写播放逻辑以及添加互联网访问权限。
27 1
FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频
|
5天前
|
Web App开发 安全 程序员
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
多年的互联网寒冬在今年尤为凛冽,坚守安卓开发愈发不易。面对是否转行或学习新技术的迷茫,安卓程序员可从三个方向进阶:1)钻研谷歌新技术,如Kotlin、Flutter、Jetpack等;2)拓展新功能应用,掌握Socket、OpenGL、WebRTC等专业领域技能;3)结合其他行业,如汽车、游戏、安全等,拓宽职业道路。这三个方向各有学习难度和保饭碗指数,助你在安卓开发领域持续成长。
20 1
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
|
27天前
|
XML Java Android开发
FFmpeg开发笔记(五十二)移动端的国产视频播放器GSYVideoPlayer
GSYVideoPlayer是一款国产移动端视频播放器,支持弹幕、滤镜、广告等功能,采用IJKPlayer、Media3(EXOPlayer)、MediaPlayer及AliPlayer多种内核。截至2024年8月,其GitHub星标数达2万。集成时需使用新版Android Studio,并按特定步骤配置依赖与权限。提供了NormalGSYVideoPlayer、GSYADVideoPlayer及ListGSYVideoPlayer三种控件,支持HLS、RTMP等多种直播链接。
77 18
FFmpeg开发笔记(五十二)移动端的国产视频播放器GSYVideoPlayer
|
2天前
|
Android开发 开发者
FFmpeg开发笔记(五十七)使用Media3的Transformer加工视频文件
谷歌推出的Transformer,作为Jetpack Media3架构的一部分,助力开发者实现音视频格式转换与编辑。Media3简化了媒体处理流程,提升了定制性和可靠性。Transformer可用于剪辑、添加滤镜等操作,其示例代码可在指定GitHub仓库中找到。要使用Transformer,需在`build.gradle`中添加相关依赖,并按文档编写处理逻辑,最终完成音视频转换任务。具体步骤包括配置剪辑参数、设置空间效果以及监听转换事件等。
12 0
FFmpeg开发笔记(五十七)使用Media3的Transformer加工视频文件
|
26天前
|
Linux 开发工具 Android开发
FFmpeg开发笔记(五十三)移动端的国产直播录制工具EasyPusher
EasyPusher是一款国产RTSP直播录制推流客户端工具,支持Windows、Linux、Android及iOS等系统。尽管其GitHub仓库(安卓版:https://github.com/EasyDarwin/EasyPusher-Android)已多年未更新,但通过一系列改造,如升级SDK版本、迁移到AndroidX、指定本地NDK版本及更新Gradle版本等,仍可在最新Android Studio上运行。以下是针对Android Studio Dolphin版本的具体改造步骤。
43 3
FFmpeg开发笔记(五十三)移动端的国产直播录制工具EasyPusher
|
6天前
|
Linux 视频直播
FFmpeg开发笔记(五十四)使用EasyPusher实现移动端的RTSP直播
本文介绍了如何使用EasyPusher-Android实现RTSP直播流程。首先对比了RTSP、RTMP、SRT和RIST四种流媒体协议,并以RTSP为例,详细说明了使用EasyPusher-Android向流媒体服务器进行RTSP直播推流的方法。文中还提供了OBS Studio配置RTSP插件及ZLMediaKit云服务器部署的相关信息,通过修改EasyPusher-Android源码使其支持通用RTSP地址,最终验证了直播功能的成功实现。
21 0
FFmpeg开发笔记(五十四)使用EasyPusher实现移动端的RTSP直播
|
1月前
|
编解码 移动开发 安全
FFmpeg开发笔记(五十)聊聊几种流媒体传输技术的前世今生
自互联网普及以来,流媒体技术特别是视频直播技术不断进步,出现了多种传输协议。早期的MMS由微软主导,但随WMV格式衰落而减少使用。RTSP由网景和RealNetworks联合提出,支持多种格式,但在某些现代应用中不再受支持。RTMP由Adobe开发,曾广泛用于网络直播,但因HTML5不支持Flash而受影响。HLS由苹果开发,基于HTTP,适用于点播。SRT和RIST均为较新协议,强调安全与可靠性,尤其SRT在电视直播中应用增多。尽管RTMP仍占一定市场,但SRT等新协议正逐渐兴起。
77 8
FFmpeg开发笔记(五十)聊聊几种流媒体传输技术的前世今生