版权声明:转载请说明出处: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负责逐帧编码。

 

最新文章

  1. Linq中使用反射实现--LINQ通用数据表绑定DataGrid控件的方法(原创)
  2. Redmine 插件安装
  3. hdu 1318 Palindromes
  4. 获取Trustedinstalled权限.reg
  5. Java异常与运行时异常,以及与线程的关系
  6. Map和HashMap
  7. [LeetCode] Interleaving String 解题思路
  8. php调用js变量
  9. CSS3学习系列之盒样式(一)
  10. 【学习笔记】Hibernate关联映射(Y2-1-6)
  11. MUI开发大全
  12. 学号 20175201张驰 《Java程序设计》第7周学习总结
  13. Elasticsearch 删除数据
  14. 雷林鹏分享:C# 程序结构
  15. .net MVC入门
  16. Linux反编译
  17. SpringMVC框架学习
  18. 枚举1--求小于n的最大素数
  19. spring的FactoryBean
  20. sql 数据库数据 批量判断修改

热门文章

  1. @ResponseBody 与 response.getWriter.write
  2. 恢复mysql 中root 用户的所有权限
  3. 设置同一个域名同一个源通过cdn用不同的端口访问网站设置
  4. Java学习笔记(十五):import关键字
  5. 2018 ICPC青岛网络赛 B. Red Black Tree(倍增lca好题)
  6. FortiGate高校图书馆SSLvpn配置案例
  7. 716. Max Stack实现一个最大stack
  8. ES6自我总结笔记(阮一峰ES6入门)
  9. uboot——git代码仓
  10. 最近素数问题——C语言