您当前的位置: 首页 > 慢生活 > 程序人生 网站首页程序人生
ffmpeg转推rtsp为rtmp到nginx流媒体(多个推流拉流地址的实现)及解决php同步阻塞问题
发布时间:2025-02-16 12:30:10编辑:雪饮阅读()
-
前番实现了基于nginx+ffmpeg的rtsp转推rtmp流。
那么接下来是实现多路推拉流地址。
其实多路推流nginx配置文件中就可以实现如:
application liveA {
live on;
record off;
allow publish all;
allow play all;
}
application liveB{
live on;
record off;
allow publish all;
allow play all;
}
这样虽然可行,但是不够零活。应该要客户端调用灵活。
那么其实只需要如:
application live {
live on;
record off;
allow publish all;
allow play all;
}
然后客户端推流地址如rtmp://local.sunba.cc:1935/live/A,rtmp://local.sunba.cc:1935/live/B这样,然后拉流用户A拉取rtmp://local.sunba.cc:1935/live/A则看到的是推流A的流,拉流用户B拉取rtmp://local.sunba.cc:1935/live/B,则看到的是推流B的流。
当然这里我发现就是你推流一发起就要赶紧去拉流,否则拉流者可能拉到别的推流者的流或者出现屏幕花屏的效果。
播rtmp流我是用ffplay,如:
ffplay "rtmp://local.sunba.cc:1935/live/stream_20250216101521"
但是我们不能手推,我们最终肯定是要集成到代码里面的,例如集成的php里面的。
那么我们面临的问题就是大多php的web应用都是http阻塞的,推流比较阻塞是io密集型,我们必须异步它。
所以我这里是fastadmin,我的实现思路是集成workerman,fastadmin是thinkphp5的,怎么集成,可以参考如:
https://www.cnblogs.com/wt645631686/p/18447825
集成后,然后我写一个从海康开放平台取得的rtsp流并推流到我们的本地流媒体的实现参考如:
public function pushStream(){
$fileId="test".date("YmdHis");
$target_log=$_SERVER["DOCUMENT_ROOT"].'/orderVideoTmp/'.$fileId.".log";
$progress_output=$target_log;
$ffmpeg_stdOutLog=$_SERVER["DOCUMENT_ROOT"].'/orderVideoTmp/'.$fileId."_ffmpeg_stdout.log";
$ffmpeg_errorOutLog=$_SERVER["DOCUMENT_ROOT"].'/orderVideoTmp/'.$fileId."_ffmpeg_errorOut.log";
$haiv = new ServiceHaiv;
$cameraIndexCode = $this->request->post('cameraIndexCode');
$beginTime = $this->request->post('beginTime');
$beginTimeInt=strtotime($beginTime);
$reBeginTime=date("Y-m-d",$beginTimeInt).'T'.date("H:i:s",$beginTimeInt).".000+08:00";
$endTime = $this->request->post('endTime');
$endTimeInt=strtotime($endTime);
$reEndTime=date("Y-m-d",$endTimeInt)."T".date("H:i:s",$endTimeInt).".000+08:00";
$pointDetails = $haiv->camerasIndexCode($cameraIndexCode);
$playbackList = $haiv->playbackURLsByPoint($cameraIndexCode,$reBeginTime,$reEndTime,$pointDetails["data"]["recordLocation"]);
$download_url=$playbackList["data"]["url"];
$stream="stream_".date("YmdHis")."_".date("YmdHis",$beginTimeInt)."_".date("YmdHis",$endTimeInt);
$push_url="rtmp://127.0.0.1:1935/live/".$stream;
$pull_url="rtmp://local.sunba.cc:1935/live/".$stream;
$ffmpegDir=$_SERVER["DOCUMENT_ROOT"].'/../ffmpeg/ffmpeg-master-latest-linux64-gpl/bin/';
/* $command=<<<EOF
ffmpeg -re -rtsp_transport tcp -i "$download_url" -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 -progress "$progress_output" "$push_url" > "$ffmpeg_stdOutLog" 2> "$ffmpeg_errorOutLog"
EOF; */
$command=<<<EOF
ffmpeg -re -rtsp_transport tcp -i "$download_url" -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 "$push_url" > "$ffmpeg_stdOutLog" 2> "$ffmpeg_errorOutLog"
EOF;
//$command=$ffmpegDir.$command;
file_put_contents("command.txt",$command);
$client = new Client("ws://127.0.0.1:".config('workerman.websocket_port'));
$client->send($command);
$client->close();
$playCommand=<<<EOF
ffplay "$pull_url"
EOF;
$data["pullUrl"]=$pull_url;
$data["pushCommand"]=$command;
$data["playCommand"]=$playCommand;
$data["beginTime"]=$beginTime;
$this->success('success', $data);
}
这里用到的客户端其实是模拟websocket客户端给workerman发送推流命令,用composer可以安装到。
"textalk/websocket": "^1.6"
然后我们集成的wokerman的WorkerEvents.php中的onMessage接收命令去异步执行推送,防止接口阻塞。
public static function onMessage($client_id, $message)
{
var_dump("收到消息了");
exec($message);
//不作处理
}
当然这里还是不是很合理,因为onMessage好像是在首次接收消息很快,当已经有推流任务的时候,接收消息就非常慢,导致用户拿到的拉流地址有可能拉到了上个推流的流。
最好就是前端websocket监听onMessage,由上面服务端的onMessage发送给前端,那么也就是说命令所需要的参数什么也都是通过前端的websocket的send方法发给workerman的,后端的onMessage收到这个消息后进行处理。
另外一个小坑就是glibc,现在的ffmpeg在centos上从ffmpeg4到ffmpeg7我的尝试了,glibc版本过低,至少要2.22以上,而centos7的glibc基本都是2.17.如果要升级风险很大,手动编译2.23在make install之后报错,竟然还影响到系统底层了,导致各种致命的伤害,要不是阿里云的工程师帮忙恢复到2.17,基本嗝屁了。感觉阿里云的工程师都有点害怕恢复不好。
最好的方案是换centos8.
最后祭出成果:

关键字词:ffmpeg,rtsp,nginx,多个,推流,地址,拉流,php,阻塞
相关文章
- 使用ffmpeg将海康开放平台rtsp回放流转rtmp流及转存为
- win10下搭建基于nginx的流媒体服务器(nginx 1.7.11.3
- 调试请求数据并创建project(为基于sail的laravel项目
- thinkphp6(thinkcmf6.0.7)导出excel(含单个单元格的多
- uniapp、php生成pdf
- php与ffmpeg实现vip视频m3u8的解析下与自动合并ts
- php项目集成stripe pay支付(v3)阿拉伯联合酋长国(阿联
- 解决ffmpeg下载远程m3u8视频大量ts分片失败重试成本高
- windows环境下php开启fpm服务
- 6-6: 获取文章作者、分类、浏览次数等信息(发布时间,所