It lists a few streaming options here https://trac.ffmpeg.org/wiki/StreamingGuide FWIW.
On Sat, Apr 6, 2019 at 8:21 AM qw <applema...@163.com> wrote: > > Hi, > > > Thanks for your help. > > > Have you used python-librtmp to transfer rtmp stream? > > > Thanks > > > Regards > > > Andrew > > At 2019-04-01 06:13:19, "Michael Shaffer" <mikeshaf...@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@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\"' > > 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@192.168.1.102:554/VideoInput/1/h264/1\" -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\"' > > 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@192.168.1.103:554/VideoInput/1/h264/1\" -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\"' > > 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@192.168.1.104:554/VideoInput/1/h264/1\" -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\"' > > 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@192.168.1.105:554/VideoInput/1/h264/1\" -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\"' > > 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 <mikeshaf...@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 <applema...@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" <mikeshaf...@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 <mikeshaf...@gmail.com> > >>> >wrote: > >>> > > >>> >> Nginx > >>> >> > >>> >> On Sat, Mar 30, 2019 at 12:05 PM qw <applema...@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" <mikeshaf...@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 <applema...@163.com> wrote: > >>> >>> > > >>> >>> >> Hi, > >>> >>> >> > >>> >>> >> > >>> >>> >> does ffmpeg 4 still support ffserver? > >>> >>> >> > >>> >>> >> > >>> >>> >> > >>> >>> >> Regards > >>> >>> >> > >>> >>> >> > >>> >>> >> Andrew > >>> >>> >> _______________________________________________ > >>> >>> >> ffmpeg-user mailing list > >>> >>> >> ffmpeg-user@ffmpeg.org > >>> >>> >> https://ffmpeg.org/mailman/listinfo/ffmpeg-user > >>> >>> >> > >>> >>> >> To unsubscribe, visit link above, or email > >>> >>> >> ffmpeg-user-requ...@ffmpeg.org with subject "unsubscribe". > >>> >>> >_______________________________________________ > >>> >>> >ffmpeg-user mailing list > >>> >>> >ffmpeg-user@ffmpeg.org > >>> >>> >https://ffmpeg.org/mailman/listinfo/ffmpeg-user > >>> >>> > > >>> >>> >To unsubscribe, visit link above, or email > >>> >>> >ffmpeg-user-requ...@ffmpeg.org with subject "unsubscribe". > >>> >>> _______________________________________________ > >>> >>> ffmpeg-user mailing list > >>> >>> ffmpeg-user@ffmpeg.org > >>> >>> https://ffmpeg.org/mailman/listinfo/ffmpeg-user > >>> >>> > >>> >>> To unsubscribe, visit link above, or email > >>> >>> ffmpeg-user-requ...@ffmpeg.org with subject "unsubscribe". > >>> >> > >>> >> > >>> >_______________________________________________ > >>> >ffmpeg-user mailing list > >>> >ffmpeg-user@ffmpeg.org > >>> >https://ffmpeg.org/mailman/listinfo/ffmpeg-user > >>> > > >>> >To unsubscribe, visit link above, or email > >>> >ffmpeg-user-requ...@ffmpeg.org with subject "unsubscribe". > >>> _______________________________________________ > >>> ffmpeg-user mailing list > >>> ffmpeg-user@ffmpeg.org > >>> https://ffmpeg.org/mailman/listinfo/ffmpeg-user > >>> > >>> To unsubscribe, visit link above, or email > >>> ffmpeg-user-requ...@ffmpeg.org with subject "unsubscribe". > >> > >> > >_______________________________________________ > >ffmpeg-user mailing list > >ffmpeg-user@ffmpeg.org > >https://ffmpeg.org/mailman/listinfo/ffmpeg-user > > > >To unsubscribe, visit link above, or email > >ffmpeg-user-requ...@ffmpeg.org with subject "unsubscribe". > _______________________________________________ > ffmpeg-user mailing list > ffmpeg-user@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-user > > To unsubscribe, visit link above, or email > ffmpeg-user-requ...@ffmpeg.org with subject "unsubscribe". _______________________________________________ ffmpeg-user mailing list ffmpeg-user@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-user To unsubscribe, visit link above, or email ffmpeg-user-requ...@ffmpeg.org with subject "unsubscribe".