‘liusuyi’
2023-07-13 35d87ba0e7567ec001123ef7d83e63f211dc02e7
增加流媒体编解码业务
已添加9个文件
已删除1个文件
378 ■■■■■ 文件已修改
ard-work/src/main/java/com/ruoyi/media/controller/MediaController.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/media/domain/Conf.java 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/media/domain/Items.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/media/domain/JsonsRoot.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/media/domain/MediaInfo.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/media/domain/Source.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/media/service/IMediaService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/media/service/impl/MediaService.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/utils/forest/MediaClient.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/utils/forest/client.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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());
    }
}
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;
}
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;
}
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;
}
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;
}
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;
}
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();
}
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(转码速度最快,视频往往也最模糊)、superfast、veryfast、faster、fast、medium、slow、slower、veryslow、placebo这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();
    }
}
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);
}
ard-work/src/main/java/com/ruoyi/utils/forest/client.java
ÎļþÒÑɾ³ý