您的位置:首页 > 房产 > 建筑 > 武汉市人民政府研究室_甘肃省兰州市新闻_市场监督管理局投诉电话_杭州哪家seo公司好

武汉市人民政府研究室_甘肃省兰州市新闻_市场监督管理局投诉电话_杭州哪家seo公司好

2025/4/22 16:46:01 来源:https://blog.csdn.net/m0_71817461/article/details/147252326  浏览:    关键词:武汉市人民政府研究室_甘肃省兰州市新闻_市场监督管理局投诉电话_杭州哪家seo公司好
武汉市人民政府研究室_甘肃省兰州市新闻_市场监督管理局投诉电话_杭州哪家seo公司好

简言:视频流格式大致分为:RTMP、RTSP、RTP、HLS、MPEG-DASH。
本文就只说一下Rtsp转Rtmp格式,转换成功之后Rtmp的视频流存储到srs上
Pom文件

<dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platform</artifactId><version>1.5.1</version>
</dependency>

Constant类

public class Constant {public final static String rtmp="rtmp://";public final static String colon=":";public final static String slash="/";public final static String stop="stop";
}

application.properties

rtmp.host: 
rtmp.port: 
rtmp.folder: 

rtmp.host: srs安装的ip地址
rtmp.port: srs的端口
rtmp.folder:视频流存储的位置

具体实现

import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.FFmpegLogCallback;
import org.bytedeco.javacv.Frame;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author: majinzhong* @date: 2022/6/10 13:53* @Version 1.0*/
@RestController
@CrossOrigin
@RequestMapping("/stream")
public class CameraPushController {@Value("${rtmp.host}")public String rtmpHost;@Value("${rtmp.port}")public String rtmpPort;@Value("${rtmp.folder}")public String rtmpFolder;@RequestMapping("/info")public String info(){return "项目启动成功";}/**** @param rtsUrl rtsp的推流地址(在用户关闭时也要传值)* @param status 是否停止的状态(在用户关闭时传值,其他时候不传)* @return*/@RequestMapping("/push")public String streamPush(String rtsUrl,String status)throws Exception{//取出rtsUrl入参中的最后一个/后的streamIdString streamId = rtsUrl.substring(rtsUrl.lastIndexOf(Constant.slash) + 1);//对SRS的推流地址进行拼接String rtmpUrl = Constant.rtmp + rtmpHost + Constant.colon + rtmpPort + Constant.slash + rtmpFolder + Constant.slash + streamId;//实例化帧抓取器对象,将rtsp地址放入FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(rtsUrl);grabber.setOption("rtsp_transport", "tcp");//初始化帧抓取器grabber.start();//实例化FFmpegFrameRecorder,将SRS地址传入FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(rtmpUrl,grabber.getImageWidth() * 2,grabber.getImageHeight() * 2,grabber.getAudioChannels());int v_rs = 25;//设置编码格式recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);//设置封装格式recorder.setFormat("flv");//一秒内的帧数recorder.setFrameRate(v_rs);//两个关键帧之间的帧数recorder.setGopSize(v_rs);//设置音频通道,与视频源的通道数相等recorder.setAudioChannels(grabber.getAudioChannels());FFmpegLogCallback.set();//初始化帧录制器recorder.start();try {//使用异步线程让视频流 从rtsp转为rtmpif(!StringUtils.isEmpty(status)) {//获取当前所有在运行的线程ThreadGroup currentGroup =Thread.currentThread().getThreadGroup();int noThreads = currentGroup.activeCount();Thread[] lstThreads = new Thread[noThreads];currentGroup.enumerate(lstThreads);for (int i = 0; i < noThreads; i++){//找到视频流的线程if("push".equals(lstThreads[i].getName())){//让视频流线程睡眠1秒,因为在执行的线程不能直接结束lstThreads[i].sleep(1000);//结束线程,阻止推流lstThreads[i].suspend();}}//如果是停止就关闭录制器和抓取器并退出程序,如果是替换,就继续创建新线程推流if(Constant.stop.equals(status)) {//关闭帧录制器recorder.close();//关闭帧抓取器grabber.close();return "停止推流成功!";}}//创建新线程进行推流Thread thread = new Thread(() -> {try {//持续从视频源取帧Frame frame;while (null != (frame = grabber.grab())) {//取出的每一帧都推送到SRSrecorder.record(frame);}} catch (Exception e) {e.printStackTrace();}});//给线程设置名称,方便后续查找thread.setName("push");//启动线程thread.start();}catch (Exception e){e.printStackTrace();System.out.println(e);}return rtmpUrl;}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com