使用FFmpeg如何转发一个RTSP视频流
2024-09-17 03:21:24
版权声明:转载请说明出处:http://www.cnblogs.com/renhui/p/6930221.html
转发RTSP流,这类需求一般出现于转发一些摄像头采集视频,并在摄像头上做RTSP Server,然后通过转发的设备将视频内容转发出去。或者是直接拉取网络上的一些RTSP服务器的内容流,然后进行转发。
如果转发设备是Windows,则需要做的事情,就是在Windows上安装FFmpeg,配置好环境后,直接执行类似下面的命令即可(地址需要替换成你需要的地址):
ffmpeg -i rtsp://localhost/live -c copy -f flv rtmp://server/live/h264Stream
如果需要在Android设备上转发RTSP流,则需要用到JavaCV。相关介绍可以参考:JavaCV 初体验
核心逻辑如下:
long startTimestamp = 0;
FrameGrabber grabber = FFmpegFrameGrabber.createDefault(inputPath);
try {
grabber.start();
} catch (Exception e) {
try {
grabber.restart();
} catch (Exception e1) {
throw e;
}
}
OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
Frame grabframe = grabber.grab();
IplImage grabbedImage = null;
if (grabframe != null) {
Log.e(TAG, "has fetched first frame");
grabbedImage = converter.convert(grabframe);
} else {
Log.e(TAG, "not fetched first frame");
}
FrameRecorder recorder = FrameRecorder.createDefault(outputPath, 640, 360);
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // avcodec.AV_CODEC_ID_H264
recorder.setFormat("flv");
recorder.setFrameRate(25);
recorder.setGopSize(10);try {
recorder.start();
} catch (FrameRecorder.Exception e) {
try {
Log.e(TAG, "recorder start failed, try to restart recorder...");
Log.e(TAG, "close recorder...");
recorder.stop(); // 停止录制器的执行状态
Log.e(TAG, "restart recorder...");
recorder.start(); // 开启录制器
} catch (FrameRecorder.Exception e1) {
throw e;
}
}
Log.e(TAG, "start push stream");
while ((grabframe = grabber.grab()) != null && push_stream) {
grabbedImage = converter.convert(grabframe);
Frame rotatedFrame = converter.convert(grabbedImage);
if (startTimestamp == 0) {
startTimestamp = System.currentTimeMillis();
}
recorder.setTimestamp(1000 * (System.currentTimeMillis() - startTimestamp));// 时间戳
if (rotatedFrame != null) {
recorder.record(rotatedFrame);
}
}
Log.e(TAG, "has stop push stream");
recorder.stop();
recorder.release();
grabber.stop();
最重要的两个对象为:FFmpegFrameGrabber 和 FrameRecorder,其中FFmpegFrameGrabber负责逐帧解码,FrameRecorder负责逐帧编码。
最新文章
- Linq中使用反射实现--LINQ通用数据表绑定DataGrid控件的方法(原创)
- Redmine 插件安装
- hdu 1318 Palindromes
- 获取Trustedinstalled权限.reg
- Java异常与运行时异常,以及与线程的关系
- Map和HashMap
- [LeetCode] Interleaving String 解题思路
- php调用js变量
- CSS3学习系列之盒样式(一)
- 【学习笔记】Hibernate关联映射(Y2-1-6)
- MUI开发大全
- 学号 20175201张驰 《Java程序设计》第7周学习总结
- Elasticsearch 删除数据
- 雷林鹏分享:C# 程序结构
- .net MVC入门
- Linux反编译
- SpringMVC框架学习
- 枚举1--求小于n的最大素数
- spring的FactoryBean
- sql 数据库数据 批量判断修改