Feeding FFMPEG from buffer in c code RAW H264 to MP4 wrapping - c

i have a raw h264 stream coming in from cameras with a custom API. data gets put into a callback function in my c code.
i need to wrap this as mp4. i'm using ffmpeg to do this now, but only after the h264es file has been written and closed, so very time consuming on a beaglebone-like processor.
i have been trying to write this data to a named pipe and feed that to ffmpeg but can not get this to work. maybe i'm not opening/closing pipes properly, it hangs. or not specifying the piping properly for ffmpeg.
is it possible to feed the buffered data more directly to ffmpeg?
or, how do i set up the named pipe to work properly?
first i'm opening the fifo like this
g_fifoname="/tmp/fifocam1.h264";
mkfifo(g_fifoname, 0666); // make the fifos
fd_fifo[ch+brd*2] = open(g_fifoname, O_RDWR);
then, i'm calling ffmpeg like this, at this moment anyway. trying many things.
char* execargs[]={PATH_TO_FFMPEG,"-re","-y","-framerate","30","-f","h264","-video_size","1920x1080","-i",g_fifname,"-c:v","copy","-an",pathname, (char*)0};
i probably got the ffmpeg call wrong. argh.
i open the fifo first, then start ffmpeg.
when streaming is stopped i close fifo's, then close ffmpeg output file.
ffmpeg is so powerful and frustrating to wrangle.
thanks all,

Related

Output FFmpeg rawvideo to stdin with lib

I am writing a C program using FFmpeg libav, and trying to output rawvideo (from file or device) packets to stdin so that they can be picked up by another program running on my system.
Any suggestions on how to do this?
For example, can I relate to stdin like a filename and just use avformat_alloc_output_context2 and avio_open like I would when recording to a file?
I there some code reference which deals with this scenario?
Thanks.

How to pipe stdout to external app, internally within my code? C

I've currently written a udp client, which simply listens on specified port, for packets destined to a specific multicast group.
at the end, i'm printing the input to stdout in the following manner:
write(STDOUT_FILENO, buffer, num_of_bytes);
And executing the program in the following manner:
./udp_listen 224.10.10.10 4567 | mpg321 -
That way all output is piped to mpg321 app, which plays the stream of bytes as music.
The above implementation, is of course making me kind of "lose control" over my program, as it opens mpg321 app and plays.
I want to avoid this, and in someway, pipe the write(....) into mpg321, directly within my program.
How can one achieve this? I'm coding in C.
Thank you.
Thanks #kaylum for providing the answer i was looking for.
i've used popen with the command to initiate mpg321 , with redirecting its stderr output to a file.
After that i've used fileno() method to get the file descriptor number,
to be used with write() calls.
Worked great.
Thanks

Writing output of an application as a sound file

I am using espeak on BSD to output text as sound. My problem is that I want it to take it as a .mp3 but I am having little luck. I tried piping the output to tee but I guess that only works with stdout not just playing a sound.
Any ideas? My last resort would be recompiling my own version of espeak that allows me to save to a file instead of playing it
you can write it as wave and then convert it with ffmpeg:
espeak "HelloWorld" -w <file>.wav
Or pipe to ffmpeg
espeak "HelloWorld" --stdout | ffmpeg -i pipe:0 output.mp3
From the documentation:
-w < wave file>
Writes the speech output to a file in WAV format, rather than speaking it.
--stdout
Writes the speech output to stdout as it is produced, rather than speaking it. The data starts with a WAV file header which indicates the sample rate and format of the data. The length field is set to zero because the length of the data is unknown when the header is produced.
It looks like both of those options produce WAV files, but you can easily convert those without another program like ffmpeg.

Fake directory containing png informations

As we all know we can have /dev/video0 as a directory for receiving the output of a webcam.
Is it possible to create a fake /dev/something directory through a C program and continuously output there the contents of some created png files in order to create a fake webcam for example?
I will then read the live stream for an other application.
Thanks.
If all you need is a place in the filesystem where some application can read some specific data, use mkfifo to create it.
Then you can write a producer that writes whatever you need at whatever bitrate to it and have a consumer reading from it. If you output what the consumer expects, you might be able to get something that resembles a "live stream" of faked data.

using pipes to channel file i/o to another process

Just started learning/using pipes and was wondering how to route file output of an application into a pipe so that another application can use it.
To be exact, I want to pipe ffmpeg's output (transcoded video data) into my application to use it. If I create a named pipe like /tmp/out.mp4 and give it to ffmpeg as output filename, ffmpeg is going to try to create this file again, probably overwriting my pipe (Or something like that). How to deal with this kind of situation?
is there any general way to divert File IO of an application transparently?
(I am trying to write a video streaming server (Just for learning and fun) which transcodes formats like avi into streaming friendly format like mpeg4 during streaming, I found ffmpeg to be too slow for this purpose, it was taking like 2 secs to transcode 1 sec video :(
Is it the problem with my setup/PC or ffmpeg is known for sluggishness?
)
PS : I am writing this in C by the way.
ffmpeg can be persuaded to output to a pipe:
ffmpeg -i whatever.avi -f mp4 -
The "-" tells it to output to stdout instead of to a file, and the "-f" tells it what output the output file should be.
You could redirect that to a named pipe, of course, but calling it with popen to get the output as a file descriptor directly seems the way to go to me.
ffmpeg can also read from stdin and write to stdout like this:
ffmpeg -i pipe:0 -f wav pipe:1
where 0 and 1 are the standard POSIX file descriptors.

Resources