2013-05-07 138 views
0

我试图让实时视频输入延迟10秒。我试过使用delay();但这只是停止并启动代码,我需要它更多的时间转移。我听说有可能制作一系列帧,然后将它们移动一定的时间,但我还没有想出如何做到这一点。延迟MJPEG流10秒

我最初是在网页上的工作,但我认为你最有可能不能耽误只有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; 
} 




编辑 我试着添加一个基于本教程的缓冲区,并基于我从最后一个回复中收集的内容。它运行时没有任何错误,但不会延迟视频。任何想法我做错了什么?

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; 
     } 
     } 
    } 

回答

0

如果您以设定的速率传送帧,那么添加延迟非常简单。您只需以正常速度将它们“播放”到环形缓冲区中,并以相同的速度将它们“传递”到另一端。延迟量随后成为缓冲区大小的函数。

环形缓冲区基本上只是一个数组。它可以存储帧,字节或其他内容。您只需存储“前”和“后”索引。无论什么时候你推入某物,你都会推进'后退'指数。每当你弹出一些东西,你就推进'前面'。

举一个简单的例子,假设您每秒提供1帧。帧确定A,B,C等

对于前10秒,你只是在...

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

推框架现在,数组已满。您可以从前面开始传送帧。此外,'后'必须循环并开始从顶部填充数组。

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 
... 

在20fps,你的缓冲区将是200帧。

+0

我试着添加一个缓冲区(我发布了我上面更新的代码),但它似乎没有延迟10秒的视频输入。 – 2013-05-07 04:27:46

+0

从我可以告诉你,你应该改变'captureMJPEGEvent'来增加一个帧到你的缓冲区,并改变'draw'去除一个帧(并绘制它)。看起来你已经对代码进行了一半修改并添加了一个新的函数'captureEvent'。 – paddy 2013-05-07 04:51:53