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 <[email protected]> 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:[email protected]: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:[email protected]:554/VideoInput/1/h264/1\ > <http://admin:[email protected]: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:[email protected]:554/VideoInput/1/h264/1\ > <http://admin:[email protected]: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:[email protected]:554/VideoInput/1/h264/1\ > <http://admin:[email protected]: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:[email protected]:554/VideoInput/1/h264/1\ > <http://admin:[email protected]: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 <[email protected]> > 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 <[email protected]> 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" <[email protected]> > 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 < > [email protected]> > >> >wrote: > >> > > >> >> Nginx > >> >> > >> >> On Sat, Mar 30, 2019 at 12:05 PM qw <[email protected]> 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" <[email protected]> > >> 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 <[email protected]> wrote: > >> >>> > > >> >>> >> Hi, > >> >>> >> > >> >>> >> > >> >>> >> does ffmpeg 4 still support ffserver? > >> >>> >> > >> >>> >> > >> >>> >> > >> >>> >> Regards > >> >>> >> > >> >>> >> > >> >>> >> Andrew > >> >>> >> _______________________________________________ > >> >>> >> ffmpeg-user mailing list > >> >>> >> [email protected] > >> >>> >> https://ffmpeg.org/mailman/listinfo/ffmpeg-user > >> >>> >> > >> >>> >> To unsubscribe, visit link above, or email > >> >>> >> [email protected] with subject "unsubscribe". > >> >>> >_______________________________________________ > >> >>> >ffmpeg-user mailing list > >> >>> >[email protected] > >> >>> >https://ffmpeg.org/mailman/listinfo/ffmpeg-user > >> >>> > > >> >>> >To unsubscribe, visit link above, or email > >> >>> >[email protected] with subject "unsubscribe". > >> >>> _______________________________________________ > >> >>> ffmpeg-user mailing list > >> >>> [email protected] > >> >>> https://ffmpeg.org/mailman/listinfo/ffmpeg-user > >> >>> > >> >>> To unsubscribe, visit link above, or email > >> >>> [email protected] with subject "unsubscribe". > >> >> > >> >> > >> >_______________________________________________ > >> >ffmpeg-user mailing list > >> >[email protected] > >> >https://ffmpeg.org/mailman/listinfo/ffmpeg-user > >> > > >> >To unsubscribe, visit link above, or email > >> >[email protected] with subject "unsubscribe". > >> _______________________________________________ > >> ffmpeg-user mailing list > >> [email protected] > >> https://ffmpeg.org/mailman/listinfo/ffmpeg-user > >> > >> To unsubscribe, visit link above, or email > >> [email protected] with subject "unsubscribe". > > > > > _______________________________________________ > ffmpeg-user mailing list > [email protected] > https://ffmpeg.org/mailman/listinfo/ffmpeg-user > > To unsubscribe, visit link above, or email > [email protected] with subject "unsubscribe". _______________________________________________ ffmpeg-user mailing list [email protected] https://ffmpeg.org/mailman/listinfo/ffmpeg-user To unsubscribe, visit link above, or email [email protected] with subject "unsubscribe".
