网站正在建设中 手机版深圳网站定制建设
web/
2025/10/8 23:05:43/
文章来源:
网站正在建设中 手机版,深圳网站定制建设,批量做单页网站,百度搜索广告服务支撑#xff1a;FFmpeg srs(流媒体服务器)
整个流程是 FFmpeg 收流转码 推 rtmp 到流媒体服务 流媒体服务再 分发流到公网 搭建流媒体服务:
1. SRS (Simple Realtime Server) | SRS #xff08;本例子使用的是SrS 安装使用docker #xff09;
2.GitHub - ZLMedi…服务支撑FFmpeg srs(流媒体服务器)
整个流程是 FFmpeg 收流转码 推 rtmp 到流媒体服务 流媒体服务再 分发流到公网 搭建流媒体服务:
1. SRS (Simple Realtime Server) | SRS 本例子使用的是SrS 安装使用docker
2.GitHub - ZLMediaKit/ZLMediaKit: WebRTC/RTSP/RTMP/HTTP/HLS/HTTP-FLV/WebSocket-FLV/HTTP-TS/HTTP-fMP4/WebSocket-TS/WebSocket-fMP4/GB28181/SRT server and client framework based on C11
3.nginx实现 自己百度
4. 其他的还有收费的那种 2.服务器安装FFmpeg yum 可以安装 java 服务实现调用ffmpeg 1.ProcessManager 用于执行指令以及 关闭这个流等操作
package io.renren.common.live;import cn.hutool.core.thread.ThreadUtil;
import org.springframework.beans.factory.DisposableBean;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;/*** author chenkang* date 2023年8月3日09:43:21*/
public class ProcessManager implements DisposableBean {private MapString, WeakReferenceProcess processMapnew HashMap();/*** 启动一个进程* param processName 进程名称key* param command 执行指令*/public void startProcess(String processName, String command) {ThreadUtil.execAsync(() - {try {ProcessBuilder processBuilder new ProcessBuilder(command.split( ));Process process processBuilder.start();processMap.put(processName, new WeakReference(process));BufferedReader reader new BufferedReader(new InputStreamReader(process.getErrorStream()));String line;while ((line reader.readLine()) ! null) {System.out.println(processName : line);}int exitCode process.waitFor();System.out.println(processName : Process execution completed with exit code: exitCode);} catch (IOException | InterruptedException e) {e.printStackTrace();}});}/*** 销毁* param processName key*/public void terminateProcess(String processName) {WeakReferenceProcess weakRef processMap.get(processName);if (weakRef ! null) {Process process weakRef.get();if (process ! null) {process.destroy();}processMap.remove(processName);}}private void terminateAllProcesses() {for (WeakReferenceProcess weakRef : processMap.values()) {Process process weakRef.get();if (process ! null) {process.destroy();}}}Overridepublic void destroy() throws Exception {this.terminateAllProcesses();this.processMap.clear();}
} 对接的是大华的摄像头
/** * 开始推流 * 备注现在客户的设备是NVR NVR 下大概有54个摄像头 公网映射rtsp 554 端口 根据channel 开区分是那个摄像头 * 必须条件1.服务端要安装好 ffmpeg 2.要搭建一个流媒体服务器 这个使用的是 srs * 流程用户端想要查看某个摄像头-查询到设备信息获取到摄像头的channel 这个是提前维护好的 * -拿到channel走如下方法 调用FFmpeg 执行转码推流指令客户的摄像头是h265-》rtsp流会被转码 重新设定分辨率 码率转h264 并把转码流推向流媒体服务器 srs * -客户想看的时候就 拉取 流媒体服务端的rtmp流 完成播放 * * 其他 * 1.用户再播放的时候 要先确定这个摄像头有没有别的人在观看 观看了就不在执行了 1.可以调用srs 接口查询流是不是存在 这个比较稳妥 2.或者是 processManager 判断是否在推了 * 2.有时候用户强制关闭客户端 无法感知用户不在观看了这面还要 定时的去调用srs 接口查询闲置的流及时的给关闭 同时也要 把服务的process 给主动关闭不然一直推 * 这个要先去关闭process再调用接口关闭srs服务的流 * * * http://127.0.0.1:1985/api/v1/streams 查询服务端所有流 *{ * code: 0, * server: vid-f1gt8j3, * streams: [ * { * id: vid-143p019, * //streamName * name: 3, * vhost: vid-5847096, * app: live, * live_ms: 1691039306435, * //客户端数量 这个要注意 默认就有1 个客户端是推流 * clients: 1, * frames: 0, * send_bytes: 0, * recv_bytes: 1068, * kbps: { * recv_30s: 0, * send_30s: 0 * }, * publish: { * //是否正在推流 有时候服务端流停推了 但是还有客户端在看 这个流还能查到 但是 active 为false * active: false, * cid: * }, * video: null, * audio: null * } * ] * } * * * * http://127.0.0.1:1985/api/v1/clients * *{ * code: 0, * server: vid-f1gt8j3, * clients: [ * { * id: 868249e9, * vhost: vid-5847096, * stream: vid-778ujy0, * ip: 172.17.0.1, * pageUrl: , * swfUrl: , * tcUrl: rtmp://127.0.0.1:1935/live, * url: /live/9, * //类型是 fmle-publish 推流 删除掉这个推流就会停止 * //类型是 rtmp-play 拉流 删除掉这个拉流就会停止 * //剔除方法 Method DELETE api /api/v1/clients/{id} 停止推流/踢掉用户端 * type: fmle-publish, * publish: true, * alive: 16.18, * kbps: { * recv_30s: 0, * send_30s: 0 * } * } * ] * } * * * param channel */
GetMapping(/start)ResponseBodypublic void start(RequestParam(defaultValue 1) String channel){RtspUrlBuilder builder new RtspUrlBuilder();RtmpUrlBuilder rtmpUrlBuilder new RtmpUrlBuilder();//构建 rtsp 这个是客户的nvr rtsp 地址 只有channel 是灵活的 他们是64路 现在接了50多摄像头对应50 多路channelString rstp builder.setUsername(admin).setPassword(xx).setIpAddress(xx).setChannel(channel).build();//这个是流媒体服务器的rtmp 推流地址String rtmp rtmpUrlBuilder.setApplication(live).setStreamName(channel).build();final String vcodeclibx264;String camera1String.format(RTSP_RTMP, rstp,vcodec,rtmp);//TODO 判断是否已经再推了 推就直接返回拉流地址processManager.startProcess(channel,camera1);//拉流地址和推流地址是一至的 除非 java 服务和srs 在一台服务器 那么 推流地址 rtmp ip为127.0.0.1 拉流 rtmp ip 为公网// 就是java通过ffmpeg 收流转发到本地 rtmp srs分发流 到公网去System.out.println(拉流地址rtmp);}GetMapping(/end)ResponseBodypublic void end(String channel){processManager.terminateProcess(channel);}两个辅助类 package io.renren.common.live;/*** author chenkang* date 2023-8-3 12:27*/
public class RtspUrlBuilder {private String username;private String password;private String ipAddress;private int port;private String channel;private int subtype;public RtspUrlBuilder() {// 默认端口为554this.port 554;// 默认子类型为0this.subtype 0;}public RtspUrlBuilder setUsername(String username) {this.username username;return this;}public RtspUrlBuilder setPassword(String password) {this.password password;return this;}public RtspUrlBuilder setIpAddress(String ipAddress) {this.ipAddress ipAddress;return this;}public RtspUrlBuilder setPort(int port) {this.port port;return this;}public RtspUrlBuilder setChannel(String channel) {this.channel channel;return this;}public RtspUrlBuilder setSubtype(int subtype) {this.subtype subtype;return this;}public String build() {return rtsp:// username : password ipAddress : port /cam/realmonitor?channel channel subtype subtype;}
}
package io.renren.common.live;/*** author chenkang* date 2023-8-3 12:30*/
public class RtmpUrlBuilder {private String ipAddress;private int port;private String application;private String streamName;public RtmpUrlBuilder() {// 默认IP地址为127.0.0.1this.ipAddress 127.0.0.1;// 默认端口为1935this.port 1935;}public RtmpUrlBuilder setIpAddress(String ipAddress) {this.ipAddress ipAddress;return this;}public RtmpUrlBuilder setPort(int port) {this.port port;return this;}public RtmpUrlBuilder setApplication(String application) {this.application application;return this;}public RtmpUrlBuilder setStreamName(String streamName) {this.streamName streamName;return this;}public String build() {return rtmp:// ipAddress : port / application / streamName;}
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/89314.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!