zoukankan      html  css  js  c++  java
  • 使用FFmpeg如何转发一个RTSP视频流

     
    转发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负责逐帧编码。

     
  • 相关阅读:
    CSS截断字符串
    [VB.NET] 打印DataGridView类
    [C#] 打印DataGridView类
    [MySQL] errno:150
    [C#] 用户自定义控件(含源代码)透明文本框
    [分享] 微软面试题
    [C#] 用户自定义控件(含源代码)圆角Panel
    [MySQL] 史上最全的MySQL备份方法
    [C#(WebForm)] 利用递归遍历文件夹和文件存入TreeView
    [VB] (开源)VB高仿Windows7桌面炫丽版
  • 原文地址:https://www.cnblogs.com/renhui/p/6930221.html
Copyright © 2011-2022 走看看