一个使用纯php开发的rtmp直播服务器,支持rtmp协议推流,rtmp拉流,支持flv格式拉流,可以使用http或者ws协议拉流。
composer create-project xiaosongshu/rtmp_server
本项目使用php8.1,建议新手使用phpstudy这个集成环境,一键搞定环境搭建工作。
或者使用本项目提供的docker环境,在本项目根目录下命令行执行以下命令:
docker-compose up -d
本项目自带的docker配置已经集成了php相关扩展和ffmpeg。
本项目默认使用三个端口:
1935:rtmp服务
8501:flv服务
80:web服务
进入本项目的根目录,在命令行执行以下命令:
php server.php
windows系统
ctrl + c
linux系统
kill -9 pid
推流地址:rtmp://127.0.0.1/a/b
其中a是应用名称,b是频道名称,这两个参数可以改变,但只能是英文或者数字。可以自行修改。
我自己调试使用的OBS,使用方法可以参考
网上教程,
OBS工具下载。
你也可以使用ffmpeg工具,命令如下
ffmpeg -re -stream_loop 1 -i "movie.mp4" -vcodec h264 -acodec aac -f flv rtmp://127.0.0.1/a/b
命令详解
-re:表示以实时模式运行 FFMpeg。
-stream_loop 1:设置流循环次数为1。
-i "movie.mp4":指定输入文件为"movie.mp4"。
-vcodec h264:强制使用 H.264 视频编解码器进行编码。
-acodec aac:强制使用 AAC 音频编解码器进行编码。
-f flv:指定输出格式为 FLV。
rtmp://127.0.0.1/a/b:指定 RTMP 服务器的地址和路径。
rtmp: rtmp://127.0.0.1/a/b
flv(http): http://127.0.0.1:8501/a/b.flv
flv(ws): ws://127.0.0.1:8501/a/b.flv
hls:http://127.0.0.1:80/a/b.m3u8 (需要使用ffmpeg转换协议)
播放工具可以使用:
VLC打开网络串流地址
ffplay ffplay rtmp://127.0.0.1/a/b
本项目提供网页播放,直接使用浏览器打开index.html即可,访问地址 http://127.0.0.1:80/index.html
。
本项目提供网页播放,直接使用浏览器打开play.html即可,访问地址 href="http://127.0.0.1:80/play.html
。
在理想状态的情况下测试,延迟在1秒以内。理想状态就是:直播服务器和推流,拉流都在同一台电脑,减少了网络波动的影响。
另外,如果使用浏览器播放,某些浏览器如果切换到后台,因为节能的关系,浏览器不会播放直播,当浏览器切换到前台才会接着上一次的位置重新播放,这样子延迟
就相当高了。
当然了如果服务端处理器性能拉胯,延迟也会很高,因为直播服务很耗性能的。
本项目非常抱歉没有实现对hls的支持,但是提供了一个解决办法,使用ffmpeg工具对协议的转换,以上面的rtmp://127.0.0.1/a/b
流为例,本项目默认将
hls协议的文件保存在hls目录下,所以你需要在项目根目录手动创建一个/a/目录。然后在命令行执行以下命令即可完成rtmp协议转换为hls协议。
ffmpeg -i rtmp://127.0.0.1/a/b -c:v h264 -c:a aac -f hls -hls_time 3 -hls_list_size 0 ./a/b.m3u8
若需要退出协议转换,请在命令行输入q
即可退出。
注意:如果需要使用hls协议,那么创建流的时候,应用名称(比如上面的变量a)要避免使用本项目的目录,否则会污染项目。需要避开的关键字如下所示:
MediaServer,public,Root,SabreAMF,vendor。另外不建议使用php语言相关关键字,可能后期拓展会用到。
命令详解
-i rtmp://127.0.0.1/a/b rtmp输入流,即rtmp拉流地址 可以修改
-c:v h264 选择视频编码方式为h264 不用修改
-c:a aac 选择音频编码方式为aac 不用修改
-f hls 指定输出格式为hls 不用修改
-hls_time 3 设置hls切片的时间间隔为1秒 可以修改
-hls_list_size 0 设置hls播放列表的大小为0,即只生成一个播放列表文件 不用修改
./a/b.m3u8 指定输出文件的路径和名称 可以修改
本项目提供直播转发服务,使用多进程转发音视频数据。因为如果所有的播放器都接入到主进程,一旦播放器客户端数量上升到一定数量级后,只靠一个进程处理延迟会很高。
所以加入了子进程转发数据的服务。开启子进程转发服务后,播放器客户端可以接入到子进程。
启动主进程服务
php server.php
启动子进程服务
php gateway.php
子进程转发的是flv数据流。子进程可以设置一个flv的端口,不要和主进程server.php
一样。你可以开启多个子进程转发,每一个子进程的端口都不一样。你的播放器
可以接入子进程的服务器。
比如:开启一个主进程服务推流服务器,开启一个子进程,端口好为8504
,创建一个直播应用为/a/b
,使用ffmpeg
或者obs
推流到服务器。那么子进程的拉流
地址是
http://127.0.0.1:8504/a/b.flv
ws://127.0.0.1:8504/a/b.flv
。如果播放不了,可能是因为转发延迟,刷新一下重新播放。
本项目提供了两个测试播放转发数据页面。访问地址是:http://127.0.0.1:80/daili.html
和 http://127.0.0.1:80/flv.html
。
转发后的数据,可能是因为数据还原有问题,或者丢失了关键帧,或者关键帧之间的数据顺序错乱了,或者关键帧之间的时间相距过长,导致花屏马赛克,不清晰。
尚未找到具体原因,等待后面解决吧。
转发后,使用vlc播放器可以立即解码播放(虽然花屏有马赛克,可终究可以播放是吧),但是使用js的浏览器不能立即解码(目测是js不够强大,不能还原数据),
看运气,有时候能够立刻解码,有时候要很久才能解码。猜测是缺少完整的连续帧引起的,但是检测连续帧是正确的,奇了怪了。
另外,经过测试,项目在Linux环境能够正常工作。但是在windows环境下,如果使用移动端拉流,可能无法播放,转发功能也不能正常工作。目前还不知道原因,大概
是和windows环境有关吧。
需要注意的是,本项目使用的是php的cli模式,和传统的fpm模式有根本的区别。
如果在运行的时候报错,请检查报错信息,多半是缺少php扩展,根据报错信息安装对应扩展,如果使用本项目的docker配置,一般不会报错的。
本项目已经添加了自定义的hls协议,在Root\HLSDemo::class
,开启hls协议在MediaServer::publisherOnFrame()
方法里面。不过本协议尚有问题。有兴趣的
朋友可以帮忙修正一下。
本项目只用于学习,里面很多资料来源于网络,如有侵权,请联系删除。本项目完全开源,用于相互学习交流,如有问题,欢迎联系我。
如果你觉得项目还将就,请点个星星吧。
email: 2723659854@qq.com 171892716@qq.com
- FFmpeg https://ffmpeg.xianwaizhiyin.net/ 虽然这里面大多数讲的都是ffmpeg工具,但是里面涉及到了很多音视频开发的基础知识。