ofxVideoPipe - addon for reading from a video pipe/FIFO created by FFMPEG

I couldn’t find a way to read RTMP streams in OF, so I made one: https://github.com/heisters/ofxVideoPipe . The upshot is that it should work with any input format FFMPEG supports, not just RTMP, or really any application that can write a PPM stream to a pipe.

I haven’t tested it much yet or used it in a production environment, so YMMV. Feedback welcome.

screenshot or it didn’t happen:

Click-for-large-view

Hey, I am trying to use this addon, I have a question, I launch ffmpeg from terminal and the pipes are created.

I am not able to get the stream with the app- I followed all directions. Should I do make the pipes with ffmpeg through terminal before I run my app?

yes, the pipe needs to be created before you run your app. You also need to be sure the pipe is created in a directory where your app can find it. Usually bin/data/.

If that doesn’t fix your problem, please post your code, the FFMPEG command you’re using, the error message you’re getting, and your operating system.

Ok, here is my code in cpp

  
void ofApp::setup(){  
       
     video.open("/Users/fredrodrigues/Dropbox/Code/OF_0.8.0/openFrameworks/apps/myApps/VideoPipeRTMP/bin/fifo.ppm"); // <---- remember this for FFMPEG  
     video.setFrameRate(30);  
  
  
}  
  
//--------------------------------------------------------------  
void ofApp::update(){  
     video.update();  
     video.updatePixels();  
}  
  
//--------------------------------------------------------------  
void ofApp::draw(){  
     ofSetColor(255);  
     video.draw(0, 0);  
   
      
  
}  
  

First I cd to my app directory (folder containing xcode project and bin folder).

  
freds-macbook-retina:~ fredrodrigues$ cd /Users/fredrodrigues/Dropbox/Code/OF_0.8.0/openFrameworks/apps/myApps/VideoPipeRTMP   
freds-macbook-retina:VideoPipeRTMP fredrodrigues$ mkfifo bin/data/fifo.ppm  
mkfifo: bin/data/fifo.ppm: File exists  
freds-macbook-retina:VideoPipeRTMP fredrodrigues$ ffmpeg -i "rtmp://cp114761.live.edgefcs.net:443/live/tpc-live_1@44263" \  
> -an -f image2pipe -vcodec ppm -r 30 -y bin/data/fifo.ppm  

ffmpeg gives me this output.

  
ffmpeg version 1.0.1 Copyright (c) 2000-2012 the FFmpeg developers  
  built on Dec  5 2012 21:12:10 with Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)  
  configuration: --prefix=/opt/local --enable-swscale --enable-avfilter --enable-libmp3lame --enable-libvorbis --enable-libopus --enable-libtheora --enable-libschroedinger --enable-libopenjpeg --enable-libmodplug --enable-libvpx --enable-libspeex --enable-libfreetype --mandir=/opt/local/share/man --enable-shared --enable-pthreads --cc=/usr/bin/clang --arch=x86_64 --enable-yasm --enable-gpl --enable-postproc --enable-libx264 --enable-libxvid  
  libavutil      51. 73.101 / 51. 73.101  
  libavcodec     54. 59.100 / 54. 59.100  
  libavformat    54. 29.104 / 54. 29.104  
  libavdevice    54.  2.101 / 54.  2.101  
  libavfilter     3. 17.100 /  3. 17.100  
  libswscale      2.  1.101 /  2.  1.101  
  libswresample   0. 15.100 /  0. 15.100  
  libpostproc    52.  0.100 / 52.  0.100  
[flv @ 0x7fddda01e200] negative cts, previous timestamps might be wrong  
    Last message repeated 2 times  
[flv @ 0x7fddda01e200] DTS discontinuity in stream 0: packet 75 with DTS -2264900, packet 76 with DTS 67  
[flv @ 0x7fddda01e200] Estimating duration from bitrate, this may be inaccurate  
Input #0, flv, from 'rtmp://cp114761.live.edgefcs.net:443/live/tpc-live_1@44263':  
  Metadata:  
    author          :   
    copyright       :   
    description     :   
    keywords        : TPCWEB1_primary  
    rating          :   
    title           :   
    presetname      : Custom  
    creationdate    : Wed Oct 23 14:07:21 2013  
                    :   
    videodevice     : Osprey-700 HD Video Device 4  
    avclevel        : 31  
    avcprofile      : 66  
    videokeyframe_frequency: 5  
    audiodevice     : SDI Input 1 (Osprey-700 HD 4)  
    audiochannels   : 2  
    audioinputvolume: 100  
  Duration: N/A, start: -2269.911000, bitrate: 610 kb/s  
    Stream #0:0: Video: h264 (Baseline), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 512 kb/s, 1 tbr, 1k tbn, 30 tbc  
    Stream #0:1: Audio: mp3, 44100 Hz, stereo, s16, 98 kb/s  
  

Then I run the terminal script as above, then I launch the app but I never get anything drawn.

I am on a macbook pro retina on 10.8.5

Cheers

Fred

The path you’re referencing in your application code is bin/fifo.ppm, while with FFMPEG you’re referencing bin/data/fifo.ppm. Also, when you run mkfifo it complains that the file already exists, so you might want to

  
rm bin/data/fifo.ppm  

before running mkfifo, in case some other file is sitting there. I’m not sure what happens if you try to overwrite a normal file with a FIFO.

ofxVideoPipe doesn’t check whether the file exists or not, and doesn’t expose the isPipeOpen flag. I guess ::open() really should return a bool, true if it succeeded. In the meantime, it might be a good idea for you to call

  
ofFile::doesFileExist  

before calling

  
video.open  

to catch errors like the one you’re experiencing, and output a more useful error message.

Ok, I had messed up the paths trying things.

My open path is

  
  
 video.open("fifo.ppm");  
  

I put this in terminal, I added a delete line in case there is a pipe

  
  
rm bin/data/fifo.ppm  
mkfifo bin/data/fifo.ppm  
ffmpeg -i "rtmp://cp114761.live.edgefcs.net:443/live/tpc-live_1@44263" \  
-an -f image2pipe -vcodec ppm -r 30 -y bin/data/fifo.ppm  
  
  

and here is what I get back

  
[flv @ 0x7f8ee081e200] negative cts, previous timestamps might be wrong  
    Last message repeated 2 times  
[flv @ 0x7f8ee081e200] DTS discontinuity in stream 0: packet 75 with DTS -3102005, packet 76 with DTS 65  
[flv @ 0x7f8ee081e200] Estimating duration from bitrate, this may be inaccurate  
Input #0, flv, from 'rtmp://cp114761.live.edgefcs.net:443/live/tpc-live_1@44263':  
  Metadata:  
    author          :   
    copyright       :   
    description     :   
    keywords        : TPCWEB1_primary  
    rating          :   
    title           :   
    presetname      : Custom  
    creationdate    : Wed Oct 23 14:07:21 2013  
                    :   
    videodevice     : Osprey-700 HD Video Device 4  
    avclevel        : 31  
    avcprofile      : 66  
    videokeyframe_frequency: 5  
    audiodevice     : SDI Input 1 (Osprey-700 HD 4)  
    audiochannels   : 2  
    audioinputvolume: 100  
  Duration: N/A, start: -3107.010000, bitrate: 610 kb/s  
    Stream #0:0: Video: h264 (Baseline), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 512 kb/s, 6.75 tbr, 1k tbn, 30 tbc  
    Stream #0:1: Audio: mp3, 44100 Hz, stereo, s16, 98 kb/s  
Output #0, image2pipe, to 'bin/data/fifo.ppm':  
  Metadata:  
    author          :   
    copyright       :   
    description     :   
    keywords        : TPCWEB1_primary  
    rating          :   
    title           :   
    presetname      : Custom  
    creationdate    : Wed Oct 23 14:07:21 2013  
                    :   
    videodevice     : Osprey-700 HD Video Device 4  
    avclevel        : 31  
    avcprofile      : 66  
    videokeyframe_frequency: 5  
    audiodevice     : SDI Input 1 (Osprey-700 HD 4)  
    audiochannels   : 2  
    audioinputvolume: 100  
    encoder         : Lavf54.29.104  
    Stream #0:0: Video: ppm, rgb24, 640x360 [SAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 90k tbn, 30 tbc  
Stream mapping:  
  Stream #0:0 -> #0:0 (h264 -> ppm)  
Press [q] to stop, [?] for help  
freds-macbook-retina:VideoPipeRTMP fredrodrigues$   
  

I get this response every time though

[ error ] Pipe has been closed, attempting to reopen.

Any clues?

Is FFMPEG exiting right away? It looks like it from the console output you posted, but I can’t tell for sure. If it is, it must be having some issue reading the RTMP stream. You can diagnose this by using a non-RTMP stream and see if the rest works. I use a script like this:

  
  
#!/bin/bash  
  
fifo="bin/data/fifo.ppm"  
  
rm "${fifo}"  
mkfifo "${fifo}"  
  
status=1  
while [ $status -ne 0 ]  
do  
  echo "================================================================================"  
  ffmpeg -loop 1 -f image2 -i script/color_test.png -an -f image2pipe -vcodec ppm -r 20 -y "${fifo}"  
  status=$?  
  echo "--------------------------------------------------------------------------------"  
  echo "Pausing for 1 second..."  
  sleep 1  
done  
  

… where color_test.png is just a test pattern.