Can't seem to figure this one out... I have a set up NGINX server with the excellent RTMP extension and everything is working fine. However, I'm trying to restream/push a copy of a couple specific streams that need to be streamed in another RTMP stream application (specifically, these streams are streamed to application "static" but in the current situation also need to be pushed over to "live"). The process of restreaming/pushing a stream in NGINX-RTMP is relatively simple, however, in my case I need to selectively push a couple of streams instead of every stream being streamed to the application "static".
Idea is to have NGINX-RTMP pass the stream name off to the bash script, which then does the restreaming without interrupting any other streams or services.
With some success, I've tried doing this by creating a bash scrip..
The relevant NGINX config bit that runs the bash script is:
exec_publish /etc/nginx/rtmp_conf.d/stream_id.sh $name;
I tried it with an "if / else"
if [ $1 == "stream_name_1" ]; then
ffmpeg -re -i rtmp://127.0.0.1:2000/static/stream_name_1 -vcodec libx264 -acodec copy -f flv rtmp://127.0.0.1:2000/live/live_0
elif [ $1 == "stream_name_2" ]; then
ffmpeg -re -i rtmp://127.0.0.1:2000/static/stream_name_2 -vcodec libx264 -acodec copy -f flv rtmp://127.0.0.1:2000/live/live_1
elif [ $1 == "stream_name_3" ]; then
ffmpeg -re -i rtmp://127.0.0.1:2000/static/stream_name_3 -vcodec libx264 -acodec copy -f flv rtmp://127.0.0.1:2000/live/live_2
elif [ $1 == "stream_name_4" ]; then
ffmpeg -re -i rtmp://127.0.0.1:2000/static/stream_name_4 -vcodec libx264 -acodec copy -f flv rtmp://127.0.0.1:2000/live/live_3
else
echo "FAIL" >> /etc/nginx/rtmp_conf.d/stream.log && echo date > /etc/nginx/rtmp_conf.d/stream.log
exit
fi
And I tried it with Switches
case "$1" in
"stream_name_1")
ffmpeg -re -i rtmp://127.0.0.1:2000/static/stream_name_1 -vcodec libx264 -acodec copy -f flv rtmp://127.0.0.1:2000/live/live_0
;;
"stream_name_2")
ffmpeg -re -i rtmp://127.0.0.1:2000/static/stream_name_2 -vcodec libx264 -acodec copy -f flv rtmp://127.0.0.1:2000/live/live_1
;;
"stream_name_3")
ffmpeg -re -i rtmp://127.0.0.1:2000/static/stream_name_3 -vcodec libx264 -acodec copy -f flv rtmp://127.0.0.1:2000/live/live_2
;;
"stream_name_4")
ffmpeg -re -i rtmp://127.0.0.1:2000/static/stream_name_4 -vcodec libx264 -acodec copy -f flv rtmp://127.0.0.1:2000/live/live_3
;;
echo "FAIL " >> /etc/nginx/rtmp_conf.d/stream.log && echo date > /etc/nginx/rtmp_conf.d/stream.log
esac
Problem with both is that they both end up spamming a ton of ffmpeg processes ... and I don't know why - I've tried changing the code but I either end up with ffmpeg not firing at all or spamming the server.
Need more info.
What do ffmpegs say?
Have you checked the $1?
I would like to see the entire script.
It turns out that in my situation ffmpeg didn't like the argument flag "-vcodec x264" (weird because the source stream is encoded with x264, but oh well), changing it to use "copy" audio and video codec fixed my problem - ffmpeg doesn't spawn tens of processes, each trying to use abnormal resource amounts, anymore.
The examples for the working code in my case is:
To initiate the bash scripts I'm placing this in my NGINX config (which passes the incoming stream name to the bash script as by design of the RTMP module):
exec_publish /etc/nginx/rtmp_conf.d/stream_id.sh $name;
Using switches:
#!/bin/bash
case "$1" in
"stream_name_1")
ffmpeg -re -i rtmp://127.0.0.1:2000/static/stream_name_1 -vcodec copy -acodec copy -f flv rtmp://127.0.0.1:2000/live/live_0
;;
"stream_name_2")
ffmpeg -re -i rtmp://127.0.0.1:2000/static/stream_name_2 -vcodec copy -acodec copy -f flv rtmp://127.0.0.1:2000/live/live_1
;;
"stream_name_3")
ffmpeg -re -i rtmp://127.0.0.1:2000/static/stream_name_3 -vcodec copy -acodec copy -f flv rtmp://127.0.0.1:2000/live/live_2
;;
"stream_name_4")
ffmpeg -re -i rtmp://127.0.0.1:2000/static/stream_name_4 -vcodec copy -acodec copy -f flv rtmp://127.0.0.1:2000/live/live_3
;;
esac
And using If/Else:
#!/bin/bash
if [ $1 == "stream_name_1" ]; then
ffmpeg -re -i rtmp://127.0.0.1:2000/static/$1 -vcodec copy -acodec copy -f flv rtmp://127.0.0.1:2000/live/live_0
elif [ $1 == "stream_name_2" ]; then
ffmpeg -re -i rtmp://127.0.0.1:2000/static/$1 -vcodec copy -acodec copy -f flv rtmp://127.0.0.1:2000/live/live_1
elif [ $1 == "stream_name_3" ]; then
ffmpeg -re -i rtmp://127.0.0.1:2000/static/$1 -vcodec copy -acodec copy -f flv rtmp://127.0.0.1:2000/live/live_2
else [ $1 == "stream_name_4" ]; then
ffmpeg -re -i rtmp://127.0.0.1:2000/static/$1 -vcodec copy -acodec copy -f flv rtmp://127.0.0.1:2000/live/live_3
fi
Related
#!/bin/bash
cmd="ffmpeg -re -i http://10.10.10.3:9981/stream/channelnumber/9 -vcodec copy -acodec copy -f mpegts udp://224.2.2.119:2001?pkt_size=188&localaddr=192.168.2.119"
until $cmd > /dev/null 2>&1 < /dev/null; do
echo "restarting ffmpeg command..."
sleep 2
cmd="ffmpeg -re -i http://10.10.10.3:9981/stream/channelnumber/15 -vcodec copy -acodec copy -f mpegts udp://224.2.2.120:2002?pkt_size=188&localaddr=192.168.2.119"
until $cmd > /dev/null 2>&1 < /dev/null; do
echo "restarting ffmpeg command..."
sleep 2
done
Combined command:
ffmpeg -i http://10.10.10.3:9981/stream/channelnumber/9 -i http://10.10.10.3:9981/stream/channelnumber/15 -map 0 -c copy -f mpegts "udp://224.2.2.119:2001?pkt_size=188&localaddr=192.168.2.119" -map 1 -c copy -f mpegts "udp://224.2.2.120:2002?pkt_size=188&localaddr=192.168.2.119"
Do not use -re for live input streams.
I have two long audio files. I want to merge cut some part from each video
and merge both parts in one file.
In below command the problem there is no audio in the second audio part. It contain the first part and the second is empty.
What is the problem?
ffmpeg -f lavfi -i color=c=black
-ss 157.824 -t 99.818
-i "file1.mp4"
-ss 315.764 -t 50.308
-i "file2.mp4"
-s 854x480
-aspect 1.779167
-r 25
-c:v libx264
-b:v 800k
-c:a aac
-strict experimental
-b:a 128k
-f mp4
-t 150.126 -async 1
-y "output.mp4"
Currently, using ffmpeg, I am using two commands on my Terminal to:
1) create a video from a bunch of images:
ffmpeg -r 60 -f image2 -s 1920x1080 -i rotated-pano_frame%05d_color_corrected_gradblend.jpg -vcodec libx264 -crf 25 -pix_fmt yuv420p test.mp4
2) stream the video to a udp address:
ffmpeg -re -i test.mp4 -c copy -f flv udp://127.0.0.1:48550
I am trying to combine both these instructions into one command line instruction, using &&, as suggested in the answer to a previous question of mine:
ffmpeg -r 60 -f image2 -s 1920x1080 -i rotated-pano_frame%05d_color_corrected_gradblend.jpg -vcodec libx264 -crf 25 -pix_fmt yuv420p test.mp4 \
&& ffmpeg -re -i test.mp4 -c copy -f flv udp://127.0.0.1:48550
but am encountering an error which prevents streaming:
[flv # 0x7fa2ba800000] video stream discovered after head already parsed.
Thoughts on a different command line syntax to join the two instructions, different ffmpeg instruction (filters perhaps?), and why I am getting the error?
Currently, using ffmpeg, I am using two commands on my Terminal to:
1) create a video from a bunch of images:
ffmpeg -r 60 -f image2 -s 1920x1080 -i rotated-pano_frame%05d_color_corrected_gradblend.jpg -vcodec libx264 -crf 25 -pix_fmt yuv420p test.mp4
2) stream the video to a udp address:
ffmpeg -re -i test.mp4 -c copy -f flv udp://127.0.0.1:48550
How can I combine these two commands, into one single ffmpeg command?
A concern I have is that it takes a couple of minutes to generate the video from the images. Therefore, these commands have to happen serially, whereby the second command waits a few minutes for the first command to be completed, before it ensues.
Just add && between the two commands. This will execute the second command if the first executes successfully.
ffmpeg -r 60 -f image2 -s 1920x1080 -i rotated-pano_frame%05d_color_corrected_gradblend.jpg -vcodec libx264 -crf 25 -pix_fmt yuv420p test.mp4 && ffmpeg -re -i test.mp4 -c copy -f flv udp://127.0.0.1:48550
I tried
ffmpeg -i rtsp://172.19.1.34/live.sdp -acodec copy -vcodec copy b.mp4 2>>log.txt 2>&1
to keep stderr output and also redirect it to file.
But it failed.
However, I can keep the stderr output by
ffmpeg -i rtsp://172.19.1.34/live.sdp -acodec copy -vcodec copy b.mp4 2>log.txt
You can redirect stderr to stdout with 2>&1, and then use tee command.
cmd 2>&1 | tee -a log
try this
ffmpeg -i rtsp://172.19.1.34/live.sdp -acodec copy -vcodec copy b.mp4 &> log.txt
or this
nohup ffmpeg -i rtsp://172.19.1.34/live.sdp -acodec copy -vcodec copy b.mp4
and look for nohup.out after the command returns.