简体   繁体   English

将MJPEG流延迟10秒

[英]Delaying MJPEG stream by 10 seconds

I am trying to make the live video feed delay by 10 seconds. 我正在尝试将实时视频馈送延迟10秒。 I've tried using delay(); 我试过使用delay(); but that just stops and starts the code and I need it to be more of a time shift. 但这只是停止并启动了代码,我需要更多时间上的偏移。 I've heard its possible to make an array of a sequence of frames and then shift them by a certain amount of time but I haven't figured out how to do that. 我听说有可能对一系列帧进行排列,然后将它们移动一定的时间,但是我还没有弄清楚该怎么做。

I was originally working with on a webpage, but I assume you most likely can't delay a live feed with just html (although that would be way more preferable than processing) 我原本是在网页上工作的,但我想您很可能无法仅使用html来延迟实时供稿(尽管比处理更可取)

import processing.video.*; 
import it.lilik.capturemjpeg.*;

CaptureMJPEG capture;
PImage next_img = null;
Capture video;

void setup() {
    size(800, 800);

    background(0);

    capture = new CaptureMJPEG (this, "http://url.com/cam.mjpg" );

    // or this if you don't need auth
    // capture = new CaptureMJPEG(this, "http://mynetworkcamera.foo/image?speed=20");

    capture.startCapture();
    frameRate(20);
}

void draw() {
    if (next_img != null) {
        image(next_img, 0, 0);  
    }
}

void captureMJPEGEvent(PImage img) {
    next_img = img;
}




EDIT I tried to add a buffer based on the tutorial and based on what I gathered from the last reply. 编辑我试图根据本教程以及根据我从上次答复中收集的信息来添加缓冲区。 It runs without any errors but it does not delay the video. 它可以正常运行,但不会延迟视频。 Any idea what I am doing wrong? 知道我在做什么错吗?

    import processing.video.*; 

    import it.lilik.capturemjpeg.*;

    CaptureMJPEG capture;

    PImage next_img = null;

    VideoBuffer vb;
    Capture video;

    int w = 800;
    int h = 800;
    int offset = 200;

    void setup() {

      frameRate(20);

      size(800, 800);

      background(0);
      vb = new VideoBuffer(200, 200, h);
      capture = new CaptureMJPEG (this, "http://192.168.1.83/smartcam.mjpg" );


      // or this if you don't need auth
      // capture = new CaptureMJPEG(this, "http://mynetworkcamera.foo/image?speed=20");


      capture.startCapture();
    }
    void captureEvent(Capture video)  
    {
      video.read();
      video.updatePixels();
      PImage blog = video.get(300, 0, 48, h);
      vb.addFrame( blog );

      offset++;
      if (offset >= 200)
        offset = 0;
    }

    void draw() {
      int yPos = 150;

      for (int i = 0; i < 27; i++)
      {
        image( vb.getFrame( 200 - (i * 5) + offset), i*48, yPos );
      }

      if (next_img != null) {

        image(next_img, 0, 0);
      }
    }

    void captureMJPEGEvent(PImage img) {
      next_img = img;
    }
    class VideoBuffer  
    {
      PImage[] buffer;

      int inputFrame = 200;

      int frameWidth = 800;
      int frameHeight = 8000;

      /*
    parameters:

       frames - the number of frames in the buffer (fps * duration)
       width - the width of the video
       height - the height of the video
       */

      VideoBuffer( int frames, int width, int height )  
      {
        buffer = new PImage[frames];
        for (int i = 0; i < frames; i++)  
        {
          buffer[i] = new PImage(width, height);
        }

        inputFrame = 200;

        frameWidth = width;
        frameHeight = height;
      }

      // return the current "playback" frame.
      PImage getFrame( int frame )  
      {
        int f = frame;

        while (f >= buffer.length)
        {
          f -= buffer.length;
        }

        return buffer[f];
      }


      // Add a new frame to the buffer.
      void addFrame( PImage frame )  
      {
        // copy the new frame into the buffer.
        arraycopy(frame.pixels, 0, buffer[inputFrame].pixels, 0, frameWidth * frameHeight);

        // advance the input and output indexes
        inputFrame++;

        // wrap the values..
        if (inputFrame >= buffer.length)  
        {
          inputFrame = 0;
        }
      }
    } 

If you are delivering frames at a set rate, then adding a delay is pretty simple. 如果您以设定的速率交付帧,则添加延迟非常简单。 You just 'play' them into a ring buffer at the normal speed, and 'deliver' them off the other end at the same speed. 您只需以正常速度将它们“播放”到环形缓冲区中,然后以相同速度将它们“传送”到另一端即可。 The amount of delay then becomes a function of the buffer size. 延迟量随即成为缓冲区大小的函数。

A ring buffer is essentially just an array. 环形缓冲区本质上只是一个数组。 It can store frames, bytes, or whatever in it. 它可以存储帧,字节或其他内容。 You simply store a 'front' and 'back' index. 您只需存储“前”和“后”索引。 Whenever you push something in, you advance the 'back' index. 每当您推入某些东西时,都会前进“后退”索引。 Whenever you pop something out you advance the 'front'. 每当您弹出某物时,您都会前进“前部”。

For a simple example, let's just assume that you deliver 1 frame per second. 举一个简单的例子,我们假设您每秒交付1帧。 Frames are identified A, B, C etc. 框架标识为A,B,C等。

For the first 10 seconds, you just push frames in... 在开始的10秒钟内,您只需要推入框架...

A -> [A]
B -> [A B]
C -> [A B C]
...
J -> [A B C D E F G H I J]

Now, the array is full. 现在,阵列已满。 You can start delivering frames from the front. 您可以从前面开始传送框架。 Also, the 'back' must loop around and start filling the array from the top. 同样,“后”必须循环并从顶部开始填充阵列。

K -> [K B C D E F G H I J] -> A
L -> [K L C D E F G H I J] -> B
M -> [K L M D E F G H I J] -> C
...

At 20 fps, your buffer would be 200 frames. 在20 fps下,您的缓冲区为200帧。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM