Swapping FFMPEG input source - sockets

I'm using FFMPEG to stream RMTP to a server. I wish to change what I'm streaming without breaking the connection to this server.
My current FFMPEG command looks like so:
ffmpeg -f v4l2 -s 1280x720 -r 10 -i /dev/video0 -c:v libx264 -f flv -r 30 -pix_fmt yuv420p "rtmp://server live=true pubUser=user pubPasswd=pass playpath=stream"
If I wanted to change from /dev/video0 to /dev/video1 then I need to stop this program and re-run the command swapping out the -i bit.
Since FFMPEG can read from stdin as well as files, I believe it should be possible to switch the input source on the fly by either piping the output of a different program, or utilizing UNIX sockets. There may also be a solution built into FFMPEG which I'm not aware of.
My question now is: what's the simplest / least code / most recommended way of switching these inputs? Is there a third-party tool that's recommended? Does FFMPEG have an alternate command-line parameter I've never heard of? If I do use a UNIX socket of stdin, is there a recommended way to change what's being written to them?
One of my concerns is that if I have FFMPEG read in from a UNIX socket and in a separate shell I have a different instance of FFMPEG writing to this UNIX socket, during the brief period when I'm switching sources the first instance of FFMPEG (which is doing the broadcasting) would die, as it couldn't find any video data to stream.

Related

How to http stream FFMPEG encoded frames with VLC

I have a python script that write images (numpy arrays) on the standard output.
I want to keep this frames and encode them h264 with FFMPEG, using GPU, then give it to vlc to expose a stream over http.
Here there's a working example of my apporach, without the part of h264 encoding:
python3 script.py | ffmpeg -r 24 -s 1920x1080 -f rawvideo -i - -vcodec copy -f avi - | cvlc --demux=rawvideo --rawvid-fps=25
--rawvid-width=1920 --rawvid-height=1080 --rawvid-chroma=RV24 - --no-audio --sout '#transcode{vcodec=MJPG,venc=ffmpeg{strict=1}}:standard{access=http{user=pippo,pwd=pluto,mime=multipart/x-mixed-replace;boundary=--7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,dst=:10001/}'
Now, I'm having troubles in writing working pipes to do what I need.
Here the pipe I'm actually working on, FFMPEG process is managed by GPU, but VLC cannot correctly manage the flow, I suppose, in fact I can connect to VLC from another VLC instance used as client, but then I got an error in which VLC client cannot open MRL.
Here the pipe:
python3 script.py | ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -f rawvideo -s 1920x1080 -i - -c:a copy -c:v h264_nvenc -f h264 - | cvlc --demux=rawvideo --rawvid-fps=25 --rawvid-width=1920 --rawvid-height=1080 --rawvid-chroma=RV24 - --no-audio --sout '#transcode{vcodec=MJPG,venc=ffmpeg{strict=1}}:standard{access=http{user=pippo,pwd=pluto,mime=multipart/x-mixed-replace;boundary=--7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,dst=:10001/}'
I don't understand how to set vlc parameters in order to manage the incoming stream. I also could have made errors in ffmpeg pipe, any suggestion is welcome.

Flutter - How get use data in FFMPEG commands (input & output)

In Flutter, How to use data in FFMPEG commands (input & output).
Like:
ffmpeg -i 1.mp3 -i 2.mp3 -i 3.mp3 -i 4.mp3 -filter_complex "[0:a][1:a][2:a][3:a]amerge=inputs=4[aout]" -map "[aout]" output.mp3
2 Question regarding this command:
What is the path to bring the '1.mp3', '2.mp3'... to the FFMPEG.
Where is the 'output.mp3' goes to? eventually?
Didn't find any solution, let's speak locally and after that remotely (API/SERVER).
What is the path to bring the '1.mp3', '2.mp3'... to the FFMPEG.
Your ffmpeg command in your question assumes 1.mp3 and 2.mp3 are in the current working directory that ffmpeg is being executed in.
For example, in Linux if the files are in /home/aix/music, then you would have to navigate to /home/aix/music in your terminal (such as by running cd /home/aix/music) before running the ffmpeg command shown in your question.
Or, provide the full path to the files and the current directory will not matter:
ffmpeg -i /home/aix/videos/1.mp4 -i /home/aix/videos/2.mp4 ...
Where is the 'output.mp3' goes to? eventually?
output.mp3 goes wherever you tell it to. Because no path was provided the ffmpeg command in your question it will output output.mp3 into the current directory.
Or, provide the full path to output output.mp3 in the desired directory:
ffmpeg -i input.mp3 /home/aix/music/encoded/output.mp3

FFMPEG Streaming updated image in loop to FB Live Video

I am trying to stream image to fb live video using this command :
ffmpeg -loop 1 -re -i "input.jpg" -pix_fmt yuv420p -profile:v baseline -s 720x480 -bufsize 6000k -vb 400k -maxrate 1500k -deinterlace -t 60 -vcodec libx264 -preset veryfast -g 30 -r 30 -f flv "rtmp_link"
This command works perfectly for one single input file. But the problem is that I want ffmpeg to stream the latest and updated version of "input.jpg" file because my app is updating this "input.jpg" after every 2-3 seconds but the image that is streamed is the older version, not the updated one.
If I try to restart this loop, then streaming stops for approx. 4-5 seconds which is sufficient enough for FB live video to consider that streaming has been stopped and it then ends the live video.
So, is it possible to use the latest available version of input file for streaming in this loop? I don't know much about FFMPEG and I tried to search this issue but all in vain.
I have finally figured out a solution for this. When I was directly overwriting ‘input.jpg’ file using my rails app, this process was taking a few miliseconds but during this time too, ffmpeg was streaming this file which was incomplete for few miliseconds.
So, the solution for this issue is that first write the updated image to a temp file like ‘input.tmp.img’ and then move this file to the original file using script or using terminal like
mv input.tmp.img input.jpg
As moving process hardly takes any time, this solved the problem for me.

How to extract the bitstream from H.264 video?

I have a H.264 video and I want to extract the bitstream from it. In other words, I need to know the stream after encoding a video via H.264 standard. I am going to use the extracted stream in Matlab. How can I do this (extract the bitstream)? Is it possible to use ffmpeg?if so what is the command.
You can do this using
ffmpeg -i in.mp4 -c copy -f h264 stream.264
Depending on what MATLAB expects, you may need to add a bitstream filter
ffmpeg -i in.mp4 -c copy -f h264 -vbsf h264_mp4toannexb stream.264

FFMPEG corrupting audio data when trying to edit metadata

I'm trying to use FFMPEG to edit some metadata in Powershell. My problem is that FFMPEG simply outputs an audio file with the correct metadata, but the audio does not play. The length of the track is reduced to a fraction of a second. Here is the command I'm using in Powershell:
& $ffmpeg -y -i $flac.fullname -c copy -metadata track="$tracknumber" $flac.fullname
Previously, I tried having -map 0:0 in there too, but it didn't make a difference. Thanks for any help.
Edit: I'm not sure if this is intentional behavior or not, but if I change the output path to be a new destination (rather than saving over the old destination) it does work correctly. So as a workaround, I'm just using a temp folder as an output then moving the files back to where I want them.
FFmpeg does NOT do in-place editing. Destination has to be a new file.
ffmpeg -y -i file.flac -c copy -metadata track="$tracknumber" newfile.flac