[FFmpeg-user] does ffmpeg support ffserver

andrei ka andrei.k.gml at gmail.com
Tue Apr 2 11:38:13 EEST 2019


with nginx you can recieve rtmp and convert it into hls without transcoding
(nginx-rtmp-module, almost no cpu wasted on it). then you can run ffmpeg
script taking that hls as a source and do whatever you need....
nginx/nginx-rtmp-module worked better on linux for me, on windoze it'd get
weird freezes sometimes...

&rei


On Mon, Apr 1, 2019 at 12:13 AM Michael Shaffer <mikeshaffer at gmail.com>
wrote:

> Here is the script I made for restarting the cameras.. Could alter it so it
> lets you switch streams etc..
>
>
> import tkinter as tk
> from tkinter import *
> import mysql.connector
> import subprocess
> from subprocess import Popen, PIPE, STDOUT, call
> import threading
> import re
> import time
>
> top = tk.Tk()
> t = None
>
> # Enable auto restart for individual cameras
> cam1 = 1
> cam2 = 1
> cam3 = 1
> cam4 = 1
> cam5 = 1
>
> # Time of last restart
> c1lastRestartTime = time.time()
> c2lastRestartTime = time.time()
> c3lastRestartTime = time.time()
> c4lastRestartTime = time.time()
> c5lastRestartTime = time.time()
>
> c2UptimeTotal = 0
>
> c1RecordUptime = 0
> c2RecordUptime = 0
> c3RecordUptime = 0
> c4RecordUptime = 0
> c5RecordUptime = 0
>
> # Counts to keep track of how many times cameras restart
> cam1RestartCount = 1
> cam2RestartCount = 1
> cam3RestartCount = 1
> cam4RestartCount = 1
> cam5RestartCount = 1
>
> # Disabled by default, enabled using button
> autoRestart = 0
>
> def Start1():
>   global c1lastRestartTime
>   global cam1RestartCount
>   timeNow = time.time()
>   delay = timeNow - c1lastRestartTime
>   print(delay)
>   if delay > 20:
>     c1lastRestartTime = time.time()
>     cam1RestartCount = cam1RestartCount + 1
>     addRecord(1)
>     Stop1()
>     myUrl='xterm -geometry 80x25+50+20 -fg green -hold -e
> /home/dell/ffmpeg1 -rtsp_transport tcp -thread_queue_size 5096 -i \"rtsp://
> admin:pw at 192.168.1.64:554\" -rtbufsize 1000M -f lavfi -f dshow -f alsa -i
> default -c:a libmp3lame -ab 128k -ar 44100 -c:v copy -f flv \"rtmp://
> a.rtmp.youtube.com/live2/xxxxxxxxxxxxxxxx\
> <http://a.rtmp.youtube.com/live2/xxxxxxxxxxxxxxxx%5C>"'
>     subprocess.Popen(myUrl, shell=True)
>     print("Camera 1 started.")
> def Start2():
>   global c2lastRestartTime
>   global cam2RestartCount
>   timeNow = time.time()
>   delay = timeNow - c2lastRestartTime
>   print(delay)
>   if delay > 20:
>     c2lastRestartTime = time.time()
>     cam2RestartCount = cam2RestartCount + 1
>     addRecord(2)
>     Stop2()
>     myUrl='xterm -geometry 80x25+50+380 -fg green -hold -e
> /home/dell/ffmpeg2 -rtsp_transport tcp -thread_queue_size 5096 -i \"rtsp://
> admin:pw at 192.168.1.102:554/VideoInput/1/h264/1\
> <http://admin:pw@192.168.1.102:554/VideoInput/1/h264/1%5C>" -f lavfi -f
> dshow
> -rtbufsize 500M -f alsa -i default -c:a libmp3lame -ab 128k -ar 44100 -c:v
> copy -threads 0 -bufsize 512k -f flv \"rtmp://
> a.rtmp.youtube.com/live2/xxxxxxxxxxxxxxxxxxx\
> <http://a.rtmp.youtube.com/live2/xxxxxxxxxxxxxxxxxxx%5C>"'
>     subprocess.Popen(myUrl, shell=True)
>     print("Camera 2 started.")
>
> def Start3():
>   global c3lastRestartTime
>   global cam3RestartCount
>   timeNow = time.time()
>   delay = timeNow - c3lastRestartTime
>   print(delay)
>   if delay > 20:
>     c3lastRestartTime = time.time()
>     cam3RestartCount = cam3RestartCount + 1
>     addRecord(3)
>     Stop3()
>     myUrl='xterm -geometry 80x25+50+730 -fg green -hold -e
> /home/dell/ffmpeg3 -rtsp_transport tcp -thread_queue_size 5096 -i \"rtsp://
> admin:pw at 192.168.1.103:554/VideoInput/1/h264/1\
> <http://admin:pw@192.168.1.103:554/VideoInput/1/h264/1%5C>" -f lavfi -f
> dshow
> -rtbufsize 500M -f alsa -i default -c:a libmp3lame -ab 128k -ar 44100 -c:v
> copy -threads 0 -bufsize 512k -f flv \"rtmp://
> a.rtmp.youtube.com/live2/xxxxxxxxxxxxxxxxxxxxx\
> <http://a.rtmp.youtube.com/live2/xxxxxxxxxxxxxxxxxxxxx%5C>"'
>     subprocess.Popen(myUrl, shell=True)
>     print("Camera 3 started.")
>
> def Start4():
>   global c4lastRestartTime
>   global cam4RestartCount
>   timeNow = time.time()
>   delay = timeNow - c4lastRestartTime
>   print(delay)
>   if delay > 20:
>     c4lastRestartTime = time.time()
>     cam4RestartCount = cam4RestartCount + 1
>     addRecord(4)
>     Stop4()
>     myUrl='xterm -geometry 80x25+560+20 -fg green -hold -e
> /home/dell/ffmpeg4 -rtsp_transport tcp -thread_queue_size 5096 -i \"rtsp://
> admin:pw at 192.168.1.104:554/VideoInput/1/h264/1\
> <http://admin:pw@192.168.1.104:554/VideoInput/1/h264/1%5C>" -rtbufsize
> 500M -f lavfi
> -f dshow -f alsa -i default -c:a libmp3lame -ab 128k -ar 44100 -c:v copy -f
> flv \"rtmp://a.rtmp.youtube.com/live2/xxxxxxxxxxxxxxxxxxxxxx\
> <http://a.rtmp.youtube.com/live2/xxxxxxxxxxxxxxxxxxxxxx%5C>"'
>     subprocess.Popen(myUrl, shell=True)
>     print("Camera 4 started.")
>
> def Start5():
>   global c5lastRestartTime
>   global cam5RestartCount
>   timeNow = time.time()
>   delay = timeNow - c5lastRestartTime
>   print(delay)
>   if delay > 20:
>     c5lastRestartTime = time.time()
>     cam5RestartCount = cam5RestartCount + 1
>     addRecord(5)
>     Stop5()
>     myUrl='xterm -geometry 80x25+560+380 -fg green -hold -e
> /home/dell/ffmpeg5 -rtsp_transport tcp -thread_queue_size 5096 -i \"rtsp://
> admin:pw at 192.168.1.105:554/VideoInput/1/h264/1\
> <http://admin:pw@192.168.1.105:554/VideoInput/1/h264/1%5C>" -f lavfi -f
> dshow
> -rtbufsize 500M -f alsa -i default -c:a libmp3lame -ab 128k -ar 44100 -c:v
> copy -bufsize 512k -f flv \"rtmp://
> a.rtmp.youtube.com/live2/xxxxxxxxxxxxxxxxxxxxxx\
> <http://a.rtmp.youtube.com/live2/xxxxxxxxxxxxxxxxxxxxxx%5C>"'
>     subprocess.Popen(myUrl, shell=True)
>     print("Camera 5 started.")
>
> def addRecord(camNum):
>     mydb = mysql.connector.connect(
>     host="localhost",
>     user="xxx",
>     passwd="xxx",
>     database="cameras"
>     )
>
>     mycursor = mydb.cursor()
>
>     t = time.time()
>
>     sql = "INSERT INTO test2 (cid, tstamp) VALUES (%s, %s)"
>     val = (camNum, t)
>     mycursor.execute(sql, val)
>
>     mydb.commit()
>
> def StartAll():
>     Start1()
>     Start2()
>     Start3()
>     Start4()
>     Start5()
> def ListProcesses():
>     print("\n-----------------\nFFMpeg Processes: \n")
>     call("ps -A | grep ffmpeg", shell=True)
> def Stop1():
>     call("ps -ef | grep ffmpeg1 | grep -v grep | awk '{print $2}' | xargs
> -r kill -9", shell=True)
>     print("Camera 1 stopped.")
>     #call("ps -ef | grep defunct | grep -v grep | cut -b8-20 | xargs kill
> -9", shell=True)
> def Stop2():
>     call("ps -ef | grep ffmpeg2 | grep -v grep | awk '{print $2}' | xargs
> -r kill -9", shell=True)
>     print("Camera 2 stopped.")
>     #call("ps -ef | grep defunct | grep -v grep | cut -b8-20 | xargs kill
> -9", shell=True)
> def Stop3():
>     call("ps -ef | grep ffmpeg3 | grep -v grep | awk '{print $2}' | xargs
> -r kill -9", shell=True)
>     print("Camera 3 stopped.")
>     #call("ps -ef | grep defunct | grep -v grep | cut -b8-20 | xargs kill
> -9", shell=True)
> def Stop4():
>     call("ps -ef | grep ffmpeg4 | grep -v grep | awk '{print $2}' | xargs
> -r kill -9", shell=True)
>     print("Camera 4 stopped.")
>     #call("ps -ef | grep defunct | grep -v grep | cut -b8-20 | xargs kill
> -9", shell=True)
> def Stop5():
>     call("ps -ef | grep ffmpeg5 | grep -v grep | awk '{print $2}' | xargs
> -r kill -9", shell=True)
>     print("Camera 5 stopped.")
>     #call("ps -ef | grep defunct | grep -v grep | cut -b8-20 | xargs kill
> -9", shell=True)
> def StopAll():
>     call("ps -ef | grep ffmpeg | grep -v grep | awk '{print $2}' | xargs -r
> kill -9", shell=True)
>     print("All cameras stopped.\n")
>     #call("ps -ef | grep defunct | grep -v grep | cut -b8-20 | xargs kill
> -9", shell=True)
>
> def getUptime(camNum):
>   global c1lastRestartTime
>   global c2lastRestartTime
>   global c3lastRestartTime
>   global c4lastRestartTime
>   global c5lastRestartTime
>   global c1RecordUptime
>   global c2RecordUptime
>   global c3RecordUptime
>   global c4RecordUptime
>   global c5RecordUptime
>
>   currentTime = time.time()
>   if camNum == 1:
>     compareTime = c1lastRestartTime
>     upTime = currentTime - compareTime
>     upTime = int(upTime)
>     if upTime > c1RecordUptime:
>       c1RecordUptime = upTime
>   if camNum == 2:
>     compareTime = c2lastRestartTime
>     upTime = currentTime - compareTime
>     upTime = int(upTime)
>     if upTime > c2RecordUptime:
>       c2RecordUptime = upTime
>   if camNum == 3:
>     compareTime = c3lastRestartTime
>     upTime = currentTime - compareTime
>     upTime = int(upTime)
>     if upTime > c3RecordUptime:
>       c3RecordUptime = upTime
>   if camNum == 4:
>     compareTime = c4lastRestartTime
>     upTime = currentTime - compareTime
>     upTime = int(upTime)
>     if upTime > c4RecordUptime:
>       c4RecordUptime = upTime
>   if camNum == 5:
>     compareTime = c5lastRestartTime
>     upTime = currentTime - compareTime
>     upTime = int(upTime)
>     if upTime > c5RecordUptime:
>       c5RecordUptime = upTime
>
>   return upTime
>
> def check():
>   global t
>   global cam1
>   global cam2
>   global cam3
>   global cam4
>   global cam5
>   global autoRestart
>   global c1RecordUptime
>   global c2RecordUptime
>   global c3RecordUptime
>   global c4RecordUptime
>   global c5RecordUptime
>
>   X_list = []
>   Y_list = []
>   cam1sum=0
>   cam1avg=0
>   cam1instances=0
>   cam2sum=0
>   cam2avg=0
>   cam2instances=0
>   cam3sum=0
>   cam3avg=0
>   cam3instances=0
>   cam4sum=0
>   cam4avg=0
>   cam4instances=0
>   cam5sum=0
>   cam5avg=0
>   cam5instances=0
>   totalUploadAvg=0
>   call("timeout 5 sysdig -c topprocs_net > camstatus1.txt", shell=True)
>   with open("/home/dell/camstatus1.txt") as catalog:
>     for line in catalog:
>         goodletters = ('1','2','3','4','5','6','7','8','9')
>         if line.startswith(goodletters):
>           column = line.split()
>           x = str(column[0])
>           y = str(column[1])
>           x = x[:3]
>           z = y[:6]
>           x = re.sub("[^0-9]", "", x)
>           if z == 'ffmpeg':
>             xfloat = float(x)
>             xint = int(xfloat)
>             X_list.append(xint)
>             y = y[:7]
>             Y_list.append(y)
>           if y == 'ffmpeg1':
>             cam1sum = cam1sum + xint
>             cam1instances = cam1instances + 1
>           if y == 'ffmpeg2':
>             cam2sum = cam2sum + xint
>             cam2instances = cam2instances + 1
>           if y == 'ffmpeg3':
>             cam3sum = cam3sum + xint
>             cam3instances = cam3instances + 1
>           if y == 'ffmpeg4':
>             cam4sum = cam4sum + xint
>             cam4instances = cam4instances + 1
>           if y == 'ffmpeg5':
>             cam5sum = cam5sum + xint
>             cam5instances = cam5instances + 1
>
>   if cam1instances != 0:
>     cam1avg = (cam1sum / cam1instances) * 8
>   if cam2instances != 0:
>     cam2avg = (cam2sum / cam2instances) * 8
>   if cam3instances != 0:
>     cam3avg = (cam3sum / cam3instances) * 8
>   if cam4instances != 0:
>     cam4avg = (cam4sum / cam4instances) * 8
>   if cam5instances != 0:
>     cam5avg = (cam5sum / cam5instances) * 8
>   totalUploadAvg = cam1avg + cam2avg + cam3avg + cam4avg + cam5avg
>
>   print("Instances in file")
>   print(cam1instances)
>   print(cam2instances)
>   print(cam3instances)
>   print(cam4instances)
>   print(cam5instances)
>   c2uptimeavg = c2UptimeTotal / cam2RestartCount
>   print("Camera 1 - Avg Speed: ",cam1avg," Uptime: ",getUptime(1),"
> Restarts: ",cam1RestartCount,"Record Uptime: ",c1RecordUptime)
>   print("Camera 2 - Avg Speed: ",cam2avg," Uptime: ",getUptime(2),"
> Restarts: ",cam2RestartCount,"Record Uptime: ",c2RecordUptime)
>   print("Camera 3 - Avg Speed: ",cam3avg," Uptime: ",getUptime(3),"
> Restarts: ",cam3RestartCount,"Record Uptime: ",c3RecordUptime)
>   print("Camera 4 - Avg Speed: ",cam4avg," Uptime: ",getUptime(4),"
> Restarts: ",cam4RestartCount,"Record Uptime: ",c4RecordUptime)
>   print("Camera 5 - Avg Speed: ",cam5avg," Uptime: ",getUptime(5),"
> Restarts: ",cam5RestartCount,"Record Uptime: ",c5RecordUptime)
>   print("           Total UL:  ",totalUploadAvg)
>
>   if autoRestart == 1:
>     if cam1 == 1:
>       if cam1avg < 50 or cam1instances == 0:
>         Start1()
>     if cam2 == 1:
>       if cam2avg < 50 or cam2instances == 0:
>         Start2()
>     if cam3 == 1:
>       if cam3avg < 50 or cam3instances == 0:
>         Start3()
>     if cam4 == 1:
>       if cam4avg < 50 or cam4instances == 0:
>         Start4()
>     if cam5 == 1:
>       if cam5avg < 50 or cam5instances == 0:
>         Start5()
>   t = threading.Timer(10, check)
>   t.start()
>
> check()
>
> def AutoRestartOn():
>   global autoRestart
>   t = threading.Timer(5, check)
>   t.start()
>   autoRestart = 1
>   print("Auto restart ON")
>
> def AutoRestartOff():
>   global autoRestart
>   t.cancel()
>   autoRestart = 0
>   print("Auto restart OFF")
>
> B = tk.Button(top, text ="Cam 1 Start", command = Start1)
> B.pack()
> B = tk.Button(top, text ="Cam 2 Start", command = Start2)
> B.pack()
> B = tk.Button(top, text ="Cam 3 Start", command = Start3)
> B.pack()
> B = tk.Button(top, text ="Cam 4 Start", command = Start4)
> B.pack()
> B = tk.Button(top, text ="Cam 5 Start", command = Start5)
> B.pack()
> B = tk.Button(top, text ="Cam 1 Stop", command = Stop1)
> B.pack()
> B = tk.Button(top, text ="Cam 2 Stop", command = Stop2)
> B.pack()
> B = tk.Button(top, text ="Cam 3 Stop", command = Stop3)
> B.pack()
> B = tk.Button(top, text ="Cam 4 Stop", command = Stop4)
> B.pack()
> B = tk.Button(top, text ="Cam 5 Stop", command = Stop5)
> B.pack()
> B = tk.Button(top, text ="Start All", command = StartAll)
> B.pack()
> B = tk.Button(top, text ="Stop All", command = StopAll)
> B.pack()
> B = tk.Button(top, text ="List Processes", command = ListProcesses)
> B.pack()
> B = tk.Button(top, text ="Auto Restart Off", command = AutoRestartOff)
> B.pack()
> B = tk.Button(top, text ="Auto Restart On", command = AutoRestartOn)
> B.pack()
>
> top.mainloop()
>
> On Sun, Mar 31, 2019 at 5:55 PM Michael Shaffer <mikeshaffer at gmail.com>
> wrote:
>
> > Hmm I don't know. My python script basically just runs ffmpeg in a shell.
> > It uses nethogs (in Ubunu) to measure how much bandwidth ffmpeg is using.
> > If it drops below a certain level the script restarts the ffmpeg
> process. I
> > also have different buttons for manually starting and stopping each of
> the
> > 5 camera streams. Plus turning the auto-restart on and off.
> >
> > It wouldn't be hard at all to make a script that would let you switch
> > which input stream to use for the destination. The ffmpeg process would
> > restart though so there would be a very short interruption in the sending
> > to the destination rtmp address.
> >
> > Basically I'm using python to manage ffmpeg sessions. I"m not using a
> rtmp
> > library in python. I don't know if there is one.
> >
> > On Sun, Mar 31, 2019 at 2:47 AM qw <applemax82 at 163.com> wrote:
> >
> >> Hi,
> >>
> >>
> >> Does python's rtmp lib support switch two input rtmp streams, and relay
> >> one of them to destination rtmp address?
> >>
> >>
> >> Thanks!
> >>
> >>
> >> Regards
> >>
> >>
> >> Andrew
> >>
> >>
> >>
> >> At 2019-03-31 00:09:17, "Michael Shaffer" <mikeshaffer at gmail.com>
> wrote:
> >> >I haven't used Nginx but I think it does rtmp relay. I used a python
> >> script
> >> >for relaying from my ip cameras to youtube..
> >> >
> >> >On Sat, Mar 30, 2019 at 12:08 PM Michael Shaffer <
> mikeshaffer at gmail.com>
> >> >wrote:
> >> >
> >> >> Nginx
> >> >>
> >> >> On Sat, Mar 30, 2019 at 12:05 PM qw <applemax82 at 163.com> wrote:
> >> >>
> >> >>> Hi,
> >> >>>
> >> >>>
> >> >>> Is there some active popular rtmp server that can relay rtmp stream?
> >> >>>
> >> >>>
> >> >>>
> >> >>> Thanks!
> >> >>>
> >> >>>
> >> >>> Regards
> >> >>>
> >> >>>
> >> >>> Andrew
> >> >>>
> >> >>>
> >> >>>
> >> >>>
> >> >>> At 2019-03-30 23:52:45, "Michael Shaffer" <mikeshaffer at gmail.com>
> >> wrote:
> >> >>> >I don't think so. I think you have to use an older version of
> >> ffmpeg. I
> >> >>> >could never get ffserver to work right..
> >> >>> >
> >> >>> >On Sat, Mar 30, 2019 at 11:49 AM qw <applemax82 at 163.com> wrote:
> >> >>> >
> >> >>> >> Hi,
> >> >>> >>
> >> >>> >>
> >> >>> >> does ffmpeg 4 still support ffserver?
> >> >>> >>
> >> >>> >>
> >> >>> >>
> >> >>> >> Regards
> >> >>> >>
> >> >>> >>
> >> >>> >> Andrew
> >> >>> >> _______________________________________________
> >> >>> >> ffmpeg-user mailing list
> >> >>> >> ffmpeg-user at ffmpeg.org
> >> >>> >> https://ffmpeg.org/mailman/listinfo/ffmpeg-user
> >> >>> >>
> >> >>> >> To unsubscribe, visit link above, or email
> >> >>> >> ffmpeg-user-request at ffmpeg.org with subject "unsubscribe".
> >> >>> >_______________________________________________
> >> >>> >ffmpeg-user mailing list
> >> >>> >ffmpeg-user at ffmpeg.org
> >> >>> >https://ffmpeg.org/mailman/listinfo/ffmpeg-user
> >> >>> >
> >> >>> >To unsubscribe, visit link above, or email
> >> >>> >ffmpeg-user-request at ffmpeg.org with subject "unsubscribe".
> >> >>> _______________________________________________
> >> >>> ffmpeg-user mailing list
> >> >>> ffmpeg-user at ffmpeg.org
> >> >>> https://ffmpeg.org/mailman/listinfo/ffmpeg-user
> >> >>>
> >> >>> To unsubscribe, visit link above, or email
> >> >>> ffmpeg-user-request at ffmpeg.org with subject "unsubscribe".
> >> >>
> >> >>
> >> >_______________________________________________
> >> >ffmpeg-user mailing list
> >> >ffmpeg-user at ffmpeg.org
> >> >https://ffmpeg.org/mailman/listinfo/ffmpeg-user
> >> >
> >> >To unsubscribe, visit link above, or email
> >> >ffmpeg-user-request at ffmpeg.org with subject "unsubscribe".
> >> _______________________________________________
> >> ffmpeg-user mailing list
> >> ffmpeg-user at ffmpeg.org
> >> https://ffmpeg.org/mailman/listinfo/ffmpeg-user
> >>
> >> To unsubscribe, visit link above, or email
> >> ffmpeg-user-request at ffmpeg.org with subject "unsubscribe".
> >
> >
> _______________________________________________
> ffmpeg-user mailing list
> ffmpeg-user at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-user
>
> To unsubscribe, visit link above, or email
> ffmpeg-user-request at ffmpeg.org with subject "unsubscribe".


More information about the ffmpeg-user mailing list