From 35d87ba0e7567ec001123ef7d83e63f211dc02e7 Mon Sep 17 00:00:00 2001 From: ‘liusuyi’ <1951119284@qq.com> Date: 星期四, 13 七月 2023 17:28:09 +0800 Subject: [PATCH] 增加流媒体编解码业务 --- ard-work/src/main/java/com/ruoyi/media/domain/Conf.java | 133 +++++++++++++++++++ /dev/null | 15 -- ard-work/src/main/java/com/ruoyi/media/domain/Items.java | 23 +++ ard-work/src/main/java/com/ruoyi/media/controller/MediaController.java | 50 +++++++ ard-work/src/main/java/com/ruoyi/media/domain/JsonsRoot.java | 23 +++ ard-work/src/main/java/com/ruoyi/utils/forest/MediaClient.java | 26 +++ ard-work/src/main/java/com/ruoyi/media/domain/Source.java | 16 ++ ard-work/src/main/java/com/ruoyi/media/service/IMediaService.java | 10 + ard-work/src/main/java/com/ruoyi/media/domain/MediaInfo.java | 16 ++ ard-work/src/main/java/com/ruoyi/media/service/impl/MediaService.java | 66 +++++++++ 10 files changed, 363 insertions(+), 15 deletions(-) diff --git a/ard-work/src/main/java/com/ruoyi/media/controller/MediaController.java b/ard-work/src/main/java/com/ruoyi/media/controller/MediaController.java new file mode 100644 index 0000000..83bdeea --- /dev/null +++ b/ard-work/src/main/java/com/ruoyi/media/controller/MediaController.java @@ -0,0 +1,50 @@ +package com.ruoyi.media.controller; + +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.ruoyi.common.annotation.Anonymous; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.media.domain.MediaInfo; +import com.ruoyi.media.service.IMediaService; +import com.ruoyi.media.service.impl.MediaService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * @Description: + * @ClassName: controller + * @Author: 鍒樿嫃涔� + * @Date: 2023骞�07鏈�13鏃�9:26 + * @Version: 1.0 + **/ +@RestController +@Api(tags = "娴佸獟浣撴帴鍙�") +@Anonymous +public class MediaController { + @Resource + private IMediaService mediaService; + + @PostMapping("/add") + @ApiOperation("澧炲姞杞爜") + public AjaxResult addPath(@RequestBody MediaInfo mediaInfo) { + String rtsp = mediaService.addPath(mediaInfo.getName(), mediaInfo.getRtspPath()); + return AjaxResult.success(rtsp); + } + @PostMapping("/remove") + @ApiOperation("绉婚櫎杞爜") + @ApiOperationSupport(includeParameters={"mediaInfo.name"}) + public AjaxResult removePath(@RequestBody MediaInfo mediaInfo) { + mediaService.removePath(mediaInfo.getName()); + return AjaxResult.success(); + } + @GetMapping("/getList") + @ApiOperation("鑾峰彇褰撳墠杞爜鍒楄〃") + public AjaxResult getList() { + return AjaxResult.success(mediaService.list()); + } +} diff --git a/ard-work/src/main/java/com/ruoyi/media/domain/Conf.java b/ard-work/src/main/java/com/ruoyi/media/domain/Conf.java new file mode 100644 index 0000000..85480b8 --- /dev/null +++ b/ard-work/src/main/java/com/ruoyi/media/domain/Conf.java @@ -0,0 +1,133 @@ +package com.ruoyi.media.domain; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +/** + * @Description: + * @ClassName: MediaInfo + * @Author: 鍒樿嫃涔� + * @Date: 2023骞�07鏈�13鏃�9:32 + * @Version: 1.0 + **/ +@Data +public class Conf { + private String source; + @JsonProperty("sourceFingerprint") + private String sourcefingerprint; + @JsonProperty("sourceOnDemand") + private boolean sourceondemand; + @JsonProperty("sourceOnDemandStartTimeout") + private String sourceondemandstarttimeout; + @JsonProperty("sourceOnDemandCloseAfter") + private String sourceondemandcloseafter; + @JsonProperty("publishUser") + private String publishuser; + @JsonProperty("publishPass") + private String publishpass; + @JsonProperty("publishIPs") + private List<String> publiships; + @JsonProperty("readUser") + private String readuser; + @JsonProperty("readPass") + private String readpass; + @JsonProperty("readIPs") + private List<String> readips; + @JsonProperty("disablePublisherOverride") + private boolean disablepublisheroverride; + private String fallback; + @JsonProperty("sourceProtocol") + private String sourceprotocol; + @JsonProperty("sourceAnyPortEnable") + private boolean sourceanyportenable; + @JsonProperty("rtspRangeType") + private String rtsprangetype; + @JsonProperty("rtspRangeStart") + private String rtsprangestart; + @JsonProperty("sourceRedirect") + private String sourceredirect; + @JsonProperty("rpiCameraCamID") + private int rpicameracamid; + @JsonProperty("rpiCameraWidth") + private int rpicamerawidth; + @JsonProperty("rpiCameraHeight") + private int rpicameraheight; + @JsonProperty("rpiCameraHFlip") + private boolean rpicamerahflip; + @JsonProperty("rpiCameraVFlip") + private boolean rpicameravflip; + @JsonProperty("rpiCameraBrightness") + private int rpicamerabrightness; + @JsonProperty("rpiCameraContrast") + private int rpicameracontrast; + @JsonProperty("rpiCameraSaturation") + private int rpicamerasaturation; + @JsonProperty("rpiCameraSharpness") + private int rpicamerasharpness; + @JsonProperty("rpiCameraExposure") + private String rpicameraexposure; + @JsonProperty("rpiCameraAWB") + private String rpicameraawb; + @JsonProperty("rpiCameraDenoise") + private String rpicameradenoise; + @JsonProperty("rpiCameraShutter") + private int rpicamerashutter; + @JsonProperty("rpiCameraMetering") + private String rpicamerametering; + @JsonProperty("rpiCameraGain") + private int rpicameragain; + @JsonProperty("rpiCameraEV") + private int rpicameraev; + @JsonProperty("rpiCameraROI") + private String rpicameraroi; + @JsonProperty("rpiCameraTuningFile") + private String rpicameratuningfile; + @JsonProperty("rpiCameraMode") + private String rpicameramode; + @JsonProperty("rpiCameraFPS") + private int rpicamerafps; + @JsonProperty("rpiCameraIDRPeriod") + private int rpicameraidrperiod; + @JsonProperty("rpiCameraBitrate") + private int rpicamerabitrate; + @JsonProperty("rpiCameraProfile") + private String rpicameraprofile; + @JsonProperty("rpiCameraLevel") + private String rpicameralevel; + @JsonProperty("rpiCameraAfMode") + private String rpicameraafmode; + @JsonProperty("rpiCameraAfRange") + private String rpicameraafrange; + @JsonProperty("rpiCameraAfSpeed") + private String rpicameraafspeed; + @JsonProperty("rpiCameraLensPosition") + private int rpicameralensposition; + @JsonProperty("rpiCameraAfWindow") + private String rpicameraafwindow; + @JsonProperty("rpiCameraTextOverlayEnable") + private boolean rpicameratextoverlayenable; + @JsonProperty("rpiCameraTextOverlay") + private String rpicameratextoverlay; + @JsonProperty("runOnInit") + private String runoninit; + @JsonProperty("runOnInitRestart") + private boolean runoninitrestart; + @JsonProperty("runOnDemand") + private String runondemand; + @JsonProperty("runOnDemandRestart") + private boolean runondemandrestart; + @JsonProperty("runOnDemandStartTimeout") + private String runondemandstarttimeout; + @JsonProperty("runOnDemandCloseAfter") + private String runondemandcloseafter; + @JsonProperty("runOnReady") + private String runonready; + @JsonProperty("runOnReadyRestart") + private boolean runonreadyrestart; + @JsonProperty("runOnRead") + private String runonread; + @JsonProperty("runOnReadRestart") + private boolean runonreadrestart; +} diff --git a/ard-work/src/main/java/com/ruoyi/media/domain/Items.java b/ard-work/src/main/java/com/ruoyi/media/domain/Items.java new file mode 100644 index 0000000..bb933cd --- /dev/null +++ b/ard-work/src/main/java/com/ruoyi/media/domain/Items.java @@ -0,0 +1,23 @@ +package com.ruoyi.media.domain; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +/** + * @Description: + * @ClassName: Items + * @Author: 鍒樿嫃涔� + * @Date: 2023骞�07鏈�13鏃�10:23 + * @Version: 1.0 + **/ +@Data +public class Items { + private String name; + private String confname; + private Conf conf; + private Source source; + private boolean sourceready; + private List<String> tracks; +} diff --git a/ard-work/src/main/java/com/ruoyi/media/domain/JsonsRoot.java b/ard-work/src/main/java/com/ruoyi/media/domain/JsonsRoot.java new file mode 100644 index 0000000..0c8808d --- /dev/null +++ b/ard-work/src/main/java/com/ruoyi/media/domain/JsonsRoot.java @@ -0,0 +1,23 @@ +package com.ruoyi.media.domain; + +import lombok.Data; + +import java.util.List; + +/** + * @Description: + * @ClassName: JsonObject + * @Author: 鍒樿嫃涔� + * @Date: 2023骞�07鏈�13鏃�10:06 + * @Version: 1.0 + **/ +@Data +public class JsonsRoot { + + private int itemcount; + + private int pagecount; + + private List<Items> items; + +} diff --git a/ard-work/src/main/java/com/ruoyi/media/domain/MediaInfo.java b/ard-work/src/main/java/com/ruoyi/media/domain/MediaInfo.java new file mode 100644 index 0000000..8def810 --- /dev/null +++ b/ard-work/src/main/java/com/ruoyi/media/domain/MediaInfo.java @@ -0,0 +1,16 @@ +package com.ruoyi.media.domain; + +import lombok.Data; + +/** + * @Description: + * @ClassName: MediaInfo + * @Author: 鍒樿嫃涔� + * @Date: 2023骞�07鏈�13鏃�10:11 + * @Version: 1.0 + **/ +@Data +public class MediaInfo { + String name; + String rtspPath; +} diff --git a/ard-work/src/main/java/com/ruoyi/media/domain/Source.java b/ard-work/src/main/java/com/ruoyi/media/domain/Source.java new file mode 100644 index 0000000..966d3d8 --- /dev/null +++ b/ard-work/src/main/java/com/ruoyi/media/domain/Source.java @@ -0,0 +1,16 @@ +package com.ruoyi.media.domain; + +import lombok.Data; + +/** + * @Description: + * @ClassName: Source + * @Author: 鍒樿嫃涔� + * @Date: 2023骞�07鏈�13鏃�10:24 + * @Version: 1.0 + **/ +@Data +public class Source { + private String type; + private String id; +} diff --git a/ard-work/src/main/java/com/ruoyi/media/service/IMediaService.java b/ard-work/src/main/java/com/ruoyi/media/service/IMediaService.java new file mode 100644 index 0000000..b23fff6 --- /dev/null +++ b/ard-work/src/main/java/com/ruoyi/media/service/IMediaService.java @@ -0,0 +1,10 @@ +package com.ruoyi.media.service; +import com.ruoyi.media.domain.Items; +import java.util.List; + +public interface IMediaService { + + public String addPath(String name, String rtspPath); + public void removePath(String name); + public List<Items>list(); +} diff --git a/ard-work/src/main/java/com/ruoyi/media/service/impl/MediaService.java b/ard-work/src/main/java/com/ruoyi/media/service/impl/MediaService.java new file mode 100644 index 0000000..b360b82 --- /dev/null +++ b/ard-work/src/main/java/com/ruoyi/media/service/impl/MediaService.java @@ -0,0 +1,66 @@ +package com.ruoyi.media.service.impl; + +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.media.domain.Conf; +import com.ruoyi.media.domain.Items; +import com.ruoyi.media.domain.JsonsRoot; +import com.ruoyi.media.service.IMediaService; +import com.ruoyi.utils.forest.MediaClient; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * @Description: + * @ClassName: MediaService + * @Author: 鍒樿嫃涔� + * @Date: 2023骞�07鏈�13鏃�9:28 + * @Version: 1.0 + **/ +@Service +public class MediaService implements IMediaService { + + @Resource + MediaClient mediaClient; + + @Value("${mediamtx.host}") + String mediamtxHost; + + @Override + public String addPath(String name, String rtspPath) { + String apiUrl="http://"+mediamtxHost+":9997/v2"; + String rtspUrl="rtsp://"+mediamtxHost+":8554/"; + Conf mediaInfo = new Conf(); + //-vcodec libx264 //鎸囧畾瑙嗛缂栫爜鍣ㄤ负 libx264锛屼娇鐢� H.264 缂栫爜鏍煎紡杩涜瑙嗛鍘嬬缉 + //-preset ultrafast //--preset鐨勫弬鏁颁富瑕佽皟鑺傜紪鐮侀�熷害鍜岃川閲忕殑骞宠 锛屾湁ultrafast锛堣浆鐮侀�熷害鏈�蹇紝瑙嗛寰�寰�涔熸渶妯$硦锛夈�乻uperfast銆乿eryfast銆乫aster銆乫ast銆乵edium銆乻low銆乻lower銆乿eryslow銆乸lacebo杩�10涓�夐」锛屼粠蹇埌鎱� + //-r 25 //璁剧疆杈撳嚭瑙嗛鐨勫抚鐜囦负 25 甯�/绉� + //-rtsp_transport tcp //杩欎釜閫夐」鍛婅瘔 FFmpeg 浣跨敤 TCP 浣滀负 RTSP 鐨勪紶杈撳崗璁� + //-threads 4: 鎸囧畾瑕佷娇鐢ㄧ殑绾跨▼鏁颁负 4銆�//杩欏厑璁� FFmpeg 鍦ㄥ鏍稿鐞嗗櫒涓婁娇鐢ㄥ涓嚎绋嬫潵杩涜瑙嗛缂栫爜锛屼互鍔犲揩閫熷害銆� + // -i //鐢ㄤ簬鎸囧畾杈撳叆濯掍綋鏂囦欢鎴栬緭鍏ユ祦鐨勫湴鍧� + //-f rtsp //杩欎釜閫夐」鍛婅瘔 FFmpeg 杈撳嚭涓� RTSP 鏍煎紡銆� + //CPU杞В鐮佺紪鐮� + //String cmd = "ffmpeg -rtsp_transport udp -i \"" + rtspPath + "\" -vcodec libx264 -preset:v veryfast -r 25 -threads 4 -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH"; + //GPU纭В鐮佺紪鐮� + String cmd = "ffmpeg -hwaccel cuvid -c:v h264_cuvid -rtsp_transport udp -i \"" + rtspPath + "\" -c:v h264_nvenc -r 25 -threads 4 -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH"; + mediaInfo.setRunoninit(cmd); + mediaInfo.setRunoninitrestart(true); + mediaClient.add(apiUrl, name, mediaInfo); + return rtspUrl + name; + } + + @Override + public void removePath(String name) { + String apiUrl="http://"+mediamtxHost+":9997/v2"; + mediaClient.remove(apiUrl, name); + } + + @Override + public List<Items> list() { + String apiUrl="http://"+mediamtxHost+":9997/v2"; + String list = mediaClient.list(apiUrl); + JsonsRoot jsonsRoot = JSONObject.parseObject(list, JsonsRoot.class); + return jsonsRoot.getItems(); + } +} diff --git a/ard-work/src/main/java/com/ruoyi/utils/forest/MediaClient.java b/ard-work/src/main/java/com/ruoyi/utils/forest/MediaClient.java new file mode 100644 index 0000000..0f8adfc --- /dev/null +++ b/ard-work/src/main/java/com/ruoyi/utils/forest/MediaClient.java @@ -0,0 +1,26 @@ +package com.ruoyi.utils.forest; + +import com.dtflys.forest.annotation.Get; +import com.dtflys.forest.annotation.JSONBody; +import com.dtflys.forest.annotation.Post; +import com.dtflys.forest.annotation.Var; +import com.ruoyi.media.domain.Conf; + +/** + * @Description: mediamtx娴佸獟浣撳鎴风 + * @ClassName: client + * @Author: 鍒樿嫃涔� + * @Date: 2023骞�07鏈�06鏃�9:51 + * @Version: 1.0 + **/ +public interface MediaClient { + + @Post("{apiUrl}/config/paths/add/{name}") + String add(@Var("apiUrl") String apiUrl,@Var("name") String name, @JSONBody Conf body); + + @Post("{apiUrl}/config/paths/remove/{name}") + String remove(@Var("apiUrl") String apiUrl,@Var("name") String name); + + @Get("{apiUrl}/paths/list") + String list(@Var("apiUrl") String apiUrl); +} diff --git a/ard-work/src/main/java/com/ruoyi/utils/forest/client.java b/ard-work/src/main/java/com/ruoyi/utils/forest/client.java deleted file mode 100644 index 3ad830a..0000000 --- a/ard-work/src/main/java/com/ruoyi/utils/forest/client.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.ruoyi.utils.forest; - -import com.dtflys.forest.annotation.Get; - -/** - * @Description: - * @ClassName: client - * @Author: 鍒樿嫃涔� - * @Date: 2023骞�07鏈�06鏃�9:51 - * @Version: 1.0 - **/ -public interface client { - @Get("http://www.baidu.com") - String getBaiDu(); -} -- Gitblit v1.9.3