Recherche avancée

Médias (1)

Mot : - Tags -/MediaSPIP

Autres articles (28)

  • List of compatible distributions

    26 avril 2011, par

    The table below is the list of Linux distributions compatible with the automated installation script of MediaSPIP. Distribution nameVersion nameVersion number Debian Squeeze 6.x.x Debian Weezy 7.x.x Debian Jessie 8.x.x Ubuntu The Precise Pangolin 12.04 LTS Ubuntu The Trusty Tahr 14.04
    If you want to help us improve this list, you can provide us access to a machine whose distribution is not mentioned above or send the necessary fixes to add (...)

  • Use, discuss, criticize

    13 avril 2011, par

    Talk to people directly involved in MediaSPIP’s development, or to people around you who could use MediaSPIP to share, enhance or develop their creative projects.
    The bigger the community, the more MediaSPIP’s potential will be explored and the faster the software will evolve.
    A discussion list is available for all exchanges between users.

  • Automated installation script of MediaSPIP

    25 avril 2011, par

    To overcome the difficulties mainly due to the installation of server side software dependencies, an "all-in-one" installation script written in bash was created to facilitate this step on a server with a compatible Linux distribution.
    You must have access to your server via SSH and a root account to use it, which will install the dependencies. Contact your provider if you do not have that.
    The documentation of the use of this installation script is available here.
    The code of this (...)

Sur d’autres sites (6438)

  • KLV data in RTP stream

    18 septembre 2013, par Ardoramor

    I have implemented RFC6597 to stream KLV is RTP SMPTE336M packets. Currently, my SDP looks like this :

    v=2
    o=- 0 0 IN IP4 127.0.0.1
    s=Unnamed
    i=N/A
    c=IN IP4 192.168.1.6
    t=0 0
    a=recvonly
    m=video 8202 RTP/AVP 96
    a=rtpmap:96 H264/90000
    a=fmtp:96 packetization-mode=1;profile-level-id=428028;sprop-parameter-sets=Z0KAKJWgKA9E,aM48gA==;
    a=control:trackID=0
    m=application 8206 RTP/AVP 97
    a=rtpmap:97 smpte336m/1000
    a=control:trackID=1

    I try to remux the RTP stream with FFmpeg like so :

    ffmpeg.exe -i test.sdp -map 0:0 -map 0:1 -c:v copy -c:d copy test.m2ts

    I get the following output with FFmpeg :

    ffmpeg version 1.2 Copyright (c) 2000-2013 the FFmpeg developers
     built on Mar 28 2013 00:34:08 with gcc 4.8.0 (GCC)
     configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
     libavutil      52. 18.100 / 52. 18.100
     libavcodec     54. 92.100 / 54. 92.100
     libavformat    54. 63.104 / 54. 63.104
     libavdevice    54.  3.103 / 54.  3.103
     libavfilter     3. 42.103 /  3. 42.103
     libswscale      2.  2.100 /  2.  2.100
     libswresample   0. 17.102 /  0. 17.102
     libpostproc    52.  2.100 / 52.  2.100
    [aac @ 0000000002137900] Sample rate index in program config element does not match the sample rate index configured by the container.
       Last message repeated 1 times
    [aac @ 0000000002137900] decode_pce: Input buffer exhausted before END element found
    [h264 @ 00000000002ce540] Missing reference picture, default is 0
    [h264 @ 00000000002ce540] decode_slice_header error
    [sdp @ 00000000002cfa80] Estimating duration from bitrate, this may be inaccurate
    Input #0, sdp, from 'C:\Users\dragan\Documents\Workspace\Android\uvlens\tests\test.sdp':
     Metadata:
       title           : Unnamed
       comment         : N/A
     Duration: N/A, start: 0.000000, bitrate: N/A
       Stream #0:0: Audio: aac, 32000 Hz, 58 channels, fltp
       Stream #0:1: Video: h264 (Baseline), yuv420p, 640x480, 14.83 tbr, 90k tbn, 180k tbc
       Stream #0:2: Data: none
    File 'C:\Users\dragan\Documents\Workspace\Android\uvlens\tests\test.m2ts' already exists. Overwrite ? [y/N] y
    Output #0, mpegts, to 'C:\Users\dragan\Documents\Workspace\Android\uvlens\tests\test.m2ts':
     Metadata:
       title           : Unnamed
       comment         : N/A
       encoder         : Lavf54.63.104
       Stream #0:0: Video: h264, yuv420p, 640x480, q=2-31, 90k tbn, 90k tbc
       Stream #0:1: Data: none
    Stream mapping:
     Stream #0:1 -> #0:0 (copy)
     Stream #0:2 -> #0:1 (copy)
    Press [q] to stop, [?] for help
    [mpegts @ 0000000002159940] Application provided invalid, non monotonically increasing dts to muxer in stream 1: 8583659665 >= 8583656110
    av_interleaved_write_frame(): Invalid argument

    The problem is that KLV stream packets do not contain have a DTS field. According to the RFC6597 STMPE336M, RTP packet structure is the same as a standard structure :

    4.1.  RTP Header Usage

    This payload format uses the RTP packet header fields as described in
    the table below:

    +-----------+-------------------------------------------------------+
    | Field     | Usage                                                 |
    +-----------+-------------------------------------------------------+
    | Timestamp | The RTP Timestamp encodes the instant along a         |
    |           | presentation timeline that the entire KLVunit encoded |
    |           | in the packet payload is to be presented.  When one   |
    |           | KLVunit is placed in multiple RTP packets, the RTP    |
    |           | timestamp of all packets comprising that KLVunit MUST |
    |           | be the same.  The timestamp clock frequency is        |
    |           | defined as a parameter to the payload format          |
    |           | (Section 6).                                          |
    |           |                                                       |
    | M-bit     | The RTP header marker bit (M) is used to demarcate    |
    |           | KLVunits.  Senders MUST set the marker bit to '1' for |
    |           | any RTP packet that contains the final byte of a      |
    |           | KLVunit.  For all other packets, senders MUST set the |
    |           | RTP header marker bit to '0'.  This allows receivers  |
    |           | to pass a KLVunit for parsing/decoding immediately    |
    |           | upon receipt of the last RTP packet comprising the    |
    |           | KLVunit.  Without this, a receiver would need to wait |
    |           | for the next RTP packet with a different timestamp to |
    |           | arrive, thus signaling the end of one KLVunit and the |
    |           | start of another.                                     |
    +-----------+-------------------------------------------------------+

    The remaining RTP header fields are used as specified in [RFC3550].

    Header from RFC3550 :

    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |V=2|P|X|  CC   |M|     PT      |       sequence number         |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                           timestamp                           |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |           synchronization source (SSRC) identifier            |
    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    |            contributing source (CSRC) identifiers             |
    |                             ....                              |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    RFC's note about placement of KLV data into RTP packet :

    KLVunits small enough to fit into a single RTP
    packet (RTP packet size is up to the implementation but should
    consider underlying transport/network factors such as MTU
    limitations) are placed directly into the payload of the RTP packet,
    with the first byte of the KLVunit (which is the first byte of a KLV
    Universal Label Key) being the first byte of the RTP packet payload.

    My question is where does FFmpeg keep looking for the DTS ?

    Does it interpret the Timestamp field of the RTP packet header as DTS ? If so, I've verified that the timestamps increase (although at different rates) but are not equal to what FFmpeg prints out :

    8583659665 >= 8583656110

  • ADD Image overlay to ffmpeg video stream

    1er juillet 2017, par Chris

    I am new to ffmpeg and want to add an HUD to the video stream, so a few questions.

    1. What file do I need to edit.
    2. What do I need to do to achieve this.

    Thanks in advance. Also I am VERY new to all of this, I will need instructions step by step

    I saw other questions saying to add this : ffmpeg -n -i video.mp4 -i logo.png -filter_complex "[0:v]setsar=sar=1[v];[v][1]blend=all_mode='overlay':all_opacity=0.7" -movflags +faststart tmb/video.mp4

    But I dont know where to put it, i entered it in the terminal and got this :

    pi@raspberrypi:~ $ ffmpeg -n -i video.mp4 -i logo.png -filter_complex "[0:v]setsar=sar=1[v];[v][1]blend=all_mode='overlay':all_opacity=0.7" -movflags +faststart tmb/video.mp4
    ffmpeg version N-86215-gb5228e4 Copyright (c) 2000-2017 the FFmpeg developers
     built with gcc 4.9.2 (Raspbian 4.9.2-10)
     configuration: --arch=armel --target-os=linux --enable-gpl --enable-libx264 --enable-nonfree --extra-libs=-ldl
     libavutil      55. 63.100 / 55. 63.100
     libavcodec     57. 96.101 / 57. 96.101
     libavformat    57. 72.101 / 57. 72.101
     libavdevice    57.  7.100 / 57.  7.100
     libavfilter     6. 90.100 /  6. 90.100
     libswscale      4.  7.101 /  4.  7.101
     libswresample   2.  8.100 /  2.  8.100
     libpostproc    54.  6.100 / 54.  6.100
    video.mp4: No such file or directory

    I dont understand what i am supposed to do with the video.mp4 ?

    HERE IS THE SCRIPT THAT SENDS THE VIDEO.

    import subprocess
    import shlex
    import re
    import os
    import time
    import urllib2
    import platform
    import json
    import sys
    import base64
    import random


    import argparse

    parser = argparse.ArgumentParser(description='robot control')
    parser.add_argument('camera_id')
    parser.add_argument('video_device_number', default=0, type=int)
    parser.add_argument('--kbps', default=450, type=int)
    parser.add_argument('--brightness', default=75, type=int, help='camera brightness')
    parser.add_argument('--contrast', default=75, type=int, help='camera contrast')
    parser.add_argument('--saturation', default=15, type=int, help='camera saturation')
    parser.add_argument('--rotate180', default=False, type=bool, help='rotate image 180 degrees')
    parser.add_argument('--env', default="prod")



    args = parser.parse_args()



    server = "runmyrobot.com"
    #server = "52.52.213.92"


    from socketIO_client import SocketIO, LoggingNamespace

    # enable raspicam driver in case a raspicam is being used
    os.system("sudo modprobe bcm2835-v4l2")


    if args.env == "dev":
       print "using dev port 8122"
       port = 8122
    elif args.env == "prod":
       print "using prod port 8022"
       port = 8022
    else:
       print "invalid environment"
       sys.exit(0)


    print "initializing socket io"
    print "server:", server
    print "port:", port
    socketIO = SocketIO(server, port, LoggingNamespace)
    print "finished initializing socket io"

    #ffmpeg -f qtkit -i 0 -f mpeg1video -b 400k -r 30 -s 320x240 http://52.8.81.124:8082/hello/320/240/


    def onHandleCameraCommand(*args):
       #thread.start_new_thread(handle_command, args)
       print args


    socketIO.on('command_to_camera', onHandleCameraCommand)


    def onHandleTakeSnapshotCommand(*args):
       print "taking snapshot"
       inputDeviceID = streamProcessDict['device_answer']
       snapShot(platform.system(), inputDeviceID)
       with open ("snapshot.jpg", 'rb') as f:
           data = f.read()
       print "emit"

       socketIO.emit('snapshot', {'image':base64.b64encode(data)})

    socketIO.on('take_snapshot_command', onHandleTakeSnapshotCommand)


    def randomSleep():
       """A short wait is good for quick recovery, but sometimes a longer delay is needed or it will just keep trying and failing short intervals, like because the system thinks the port is still in use and every retry makes the system think it's still in use. So, this has a high likelihood of picking a short interval, but will pick a long one sometimes."""

       timeToWait = random.choice((0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 5))
       print "sleeping", timeToWait
       time.sleep(timeToWait)



    def getVideoPort():


       url = 'http://%s/get_video_port/%s' % (server, cameraIDAnswer)


       for retryNumber in range(2000):
           try:
               print "GET", url
               response = urllib2.urlopen(url).read()
               break
           except:
               print "could not open url ", url
               time.sleep(2)

       return json.loads(response)['mpeg_stream_port']

    def getAudioPort():


       url = 'http://%s/get_audio_port/%s' % (server, cameraIDAnswer)


       for retryNumber in range(2000):
           try:
               print "GET", url
               response = urllib2.urlopen(url).read()
               break
           except:
               print "could not open url ", url
               time.sleep(2)

       return json.loads(response)['audio_stream_port']



    def runFfmpeg(commandLine):

       print commandLine
       ffmpegProcess = subprocess.Popen(shlex.split(commandLine))
       print "command started"

       return ffmpegProcess



    def handleDarwin(deviceNumber, videoPort, audioPort):


       p = subprocess.Popen(["ffmpeg", "-list_devices", "true", "-f", "qtkit", "-i", "dummy"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

       out, err = p.communicate()

       print err

       deviceAnswer = raw_input("Enter the number of the camera device for your robot from the list above: ")
       commandLine = 'ffmpeg -f qtkit -i %s -f mpeg1video -b 400k -r 30 -s 320x240 http://%s:%s/hello/320/240/' % (deviceAnswer, server, videoPort)

       process = runFfmpeg(commandLine)

       return {'process': process, 'device_answer': deviceAnswer}


    def handleLinux(deviceNumber, videoPort, audioPort):

       print "sleeping to give the camera time to start working"
       randomSleep()
       print "finished sleeping"


       #p = subprocess.Popen(["ffmpeg", "-list_devices", "true", "-f", "qtkit", "-i", "dummy"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
       #out, err = p.communicate()
       #print err


       os.system("v4l2-ctl -c brightness={brightness} -c contrast={contrast} -c saturation={saturation}".format(brightness=args.brightness,
                                                                                                                contrast=args.contrast,
                                                                                                                saturation=args.saturation))


       if deviceNumber is None:
           deviceAnswer = raw_input("Enter the number of the camera device for your robot: ")
       else:
           deviceAnswer = str(deviceNumber)


       #commandLine = '/usr/local/bin/ffmpeg -s 320x240 -f video4linux2 -i /dev/video%s -f mpeg1video -b 1k -r 20 http://runmyrobot.com:%s/hello/320/240/' % (deviceAnswer, videoPort)
       #commandLine = '/usr/local/bin/ffmpeg -s 640x480 -f video4linux2 -i /dev/video%s -f mpeg1video -b 150k -r 20 http://%s:%s/hello/640/480/' % (deviceAnswer, server, videoPort)
       # For new JSMpeg
       #commandLine = '/usr/local/bin/ffmpeg -f v4l2 -framerate 25 -video_size 640x480 -i /dev/video%s -f mpegts -codec:v mpeg1video -s 640x480 -b:v 250k -bf 0 http://%s:%s/hello/640/480/' % (deviceAnswer, server, videoPort) # ClawDaddy
       #commandLine = '/usr/local/bin/ffmpeg -s 1280x720 -f video4linux2 -i /dev/video%s -f mpeg1video -b 1k -r 20 http://runmyrobot.com:%s/hello/1280/720/' % (deviceAnswer, videoPort)


       if args.rotate180:
           rotationOption = "-vf transpose=2,transpose=2"
       else:
           rotationOption = ""

       # video with audio
       videoCommandLine = '/usr/local/bin/ffmpeg -f v4l2 -framerate 25 -video_size 640x480 -i /dev/video%s %s -f mpegts -codec:v mpeg1video -s 640x480 -b:v %dk -bf 0 -muxdelay 0.001 http://%s:%s/hello/640/480/' % (deviceAnswer, rotationOption, args.kbps, server, videoPort)
       audioCommandLine = '/usr/local/bin/ffmpeg -f alsa -ar 44100 -ac 1 -i hw:1 -f mpegts -codec:a mp2 -b:a 32k -muxdelay 0.001 http://%s:%s/hello/640/480/' % (server, audioPort)


       print videoCommandLine
       print audioCommandLine

       videoProcess = runFfmpeg(videoCommandLine)
       audioProcess = runFfmpeg(audioCommandLine)

       return {'video_process': videoProcess, 'audioProcess': audioProcess, 'device_answer': deviceAnswer}



    def handleWindows(deviceNumber, videoPort):

       p = subprocess.Popen(["ffmpeg", "-list_devices", "true", "-f", "dshow", "-i", "dummy"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)


       out, err = p.communicate()
       lines = err.split('\n')

       count = 0

       devices = []

       for line in lines:

           #if "]  \"" in line:
           #    print "line:", line

           m = re.search('.*\\"(.*)\\"', line)
           if m != None:
               #print line
               if m.group(1)[0:1] != '@':
                   print count, m.group(1)
                   devices.append(m.group(1))
                   count += 1


       if deviceNumber is None:
           deviceAnswer = raw_input("Enter the number of the camera device for your robot from the list above: ")
       else:
           deviceAnswer = str(deviceNumber)

       device = devices[int(deviceAnswer)]
       commandLine = 'ffmpeg -s 640x480 -f dshow -i video="%s" -f mpegts -codec:v mpeg1video -b 200k -r 20 http://%s:%s/hello/640/480/' % (device, server, videoPort)


       process = runFfmpeg(commandLine)

       return {'process': process, 'device_answer': device}



    def handleWindowsScreenCapture(deviceNumber, videoPort):

       p = subprocess.Popen(["ffmpeg", "-list_devices", "true", "-f", "dshow", "-i", "dummy"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)


       out, err = p.communicate()

       lines = err.split('\n')

       count = 0

       devices = []

       for line in lines:

           #if "]  \"" in line:
           #    print "line:", line

           m = re.search('.*\\"(.*)\\"', line)
           if m != None:
               #print line
               if m.group(1)[0:1] != '@':
                   print count, m.group(1)
                   devices.append(m.group(1))
                   count += 1


       if deviceNumber is None:
           deviceAnswer = raw_input("Enter the number of the camera device for your robot from the list above: ")
       else:
           deviceAnswer = str(deviceNumber)



       device = devices[int(deviceAnswer)]
       commandLine = 'ffmpeg -f dshow -i video="screen-capture-recorder" -vf "scale=640:480" -f mpeg1video -b 50k -r 20 http://%s:%s/hello/640/480/' % (server, videoPort)

       print "command line:", commandLine

       process = runFfmpeg(commandLine)

       return {'process': process, 'device_answer': device}




    def snapShot(operatingSystem, inputDeviceID, filename="snapshot.jpg"):    

       try:
           os.remove('snapshot.jpg')
       except:
           print "did not remove file"

       commandLineDict = {
           'Darwin': 'ffmpeg -y -f qtkit -i %s -vframes 1 %s' % (inputDeviceID, filename),
           'Linux': '/usr/local/bin/ffmpeg -y -f video4linux2 -i /dev/video%s -vframes 1 -q:v 1000 -vf scale=320:240 %s' % (inputDeviceID, filename),
           'Windows': 'ffmpeg -y -s 320x240 -f dshow -i video="%s" -vframes 1 %s' % (inputDeviceID, filename)}

       print commandLineDict[operatingSystem]
       os.system(commandLineDict[operatingSystem])



    def startVideoCapture():

       videoPort = getVideoPort()
       audioPort = getAudioPort()
       print "video port:", videoPort
       print "audio port:", audioPort

       #if len(sys.argv) >= 3:
       #    deviceNumber = sys.argv[2]
       #else:
       #    deviceNumber = None
       deviceNumber = args.video_device_number

       result = None
       if platform.system() == 'Darwin':
           result = handleDarwin(deviceNumber, videoPort, audioPort)
       elif platform.system() == 'Linux':
           result = handleLinux(deviceNumber, videoPort, audioPort)
       elif platform.system() == 'Windows':
           #result = handleWindowsScreenCapture(deviceNumber, videoPort)
           result = handleWindows(deviceNumber, videoPort, audioPort)
       else:
           print "unknown platform", platform.system()

       return result


    def timeInMilliseconds():
       return int(round(time.time() * 1000))



    def main():

       print "main"

       streamProcessDict = None


       twitterSnapCount = 0

       while True:



           socketIO.emit('send_video_status', {'send_video_process_exists': True,
                                               'camera_id':cameraIDAnswer})


           if streamProcessDict is not None:
               print "stopping previously running ffmpeg (needs to happen if this is not the first iteration)"
               streamProcessDict['process'].kill()

           print "starting process just to get device result" # this should be a separate function so you don't have to do this
           streamProcessDict = startVideoCapture()
           inputDeviceID = streamProcessDict['device_answer']
           print "stopping video capture"
           streamProcessDict['process'].kill()

           #print "sleeping"
           #time.sleep(3)
           #frameCount = int(round(time.time() * 1000))

           videoWithSnapshots = False
           while videoWithSnapshots:

               frameCount = timeInMilliseconds()

               print "taking single frame image"
               snapShot(platform.system(), inputDeviceID, filename="single_frame_image.jpg")

               with open ("single_frame_image.jpg", 'rb') as f:

                   # every so many frames, post a snapshot to twitter
                   #if frameCount % 450 == 0:
                   if frameCount % 6000 == 0:
                           data = f.read()
                           print "emit"
                           socketIO.emit('snapshot', {'frame_count':frameCount, 'image':base64.b64encode(data)})
                   data = f.read()

               print "emit"
               socketIO.emit('single_frame_image', {'frame_count':frameCount, 'image':base64.b64encode(data)})
               time.sleep(0)

               #frameCount += 1


           if False:
            if platform.system() != 'Windows':
               print "taking snapshot"
               snapShot(platform.system(), inputDeviceID)
               with open ("snapshot.jpg", 'rb') as f:
                   data = f.read()
               print "emit"

               # skip sending the first image because it's mostly black, maybe completely black
               #todo: should find out why this black image happens
               if twitterSnapCount > 0:
                   socketIO.emit('snapshot', {'image':base64.b64encode(data)})




           print "starting video capture"
           streamProcessDict = startVideoCapture()


           # This loop counts out a delay that occurs between twitter snapshots.
           # Every 50 seconds, it kills and restarts ffmpeg.
           # Every 40 seconds, it sends a signal to the server indicating status of processes.
           period = 2*60*60 # period in seconds between snaps
           for count in range(period):
               time.sleep(1)

               if count % 20 == 0:
                   socketIO.emit('send_video_status', {'send_video_process_exists': True,
                                                       'camera_id':cameraIDAnswer})

               if count % 40 == 30:
                   print "stopping video capture just in case it has reached a state where it's looping forever, not sending video, and not dying as a process, which can happen"
                   streamProcessDict['video_process'].kill()
                   streamProcessDict['audio_process'].kill()
                   time.sleep(1)

               if count % 80 == 75:
                   print "send status about this process and its child process ffmpeg"
                   ffmpegProcessExists = streamProcessDict['process'].poll() is None
                   socketIO.emit('send_video_status', {'send_video_process_exists': True,
                                                       'ffmpeg_process_exists': ffmpegProcessExists,
                                                       'camera_id':cameraIDAnswer})

               #if count % 190 == 180:
               #    print "reboot system in case the webcam is not working"
               #    os.system("sudo reboot")

               # if the video stream process dies, restart it
               if streamProcessDict['video_process'].poll() is not None or streamProcessDict['audio_process'].poll():
                   # wait before trying to start ffmpeg
                   print "ffmpeg process is dead, waiting before trying to restart"
                   randomSleep()
                   streamProcessDict = startVideoCapture()

           twitterSnapCount += 1

    if __name__ == "__main__":


       #if len(sys.argv) > 1:
       #    cameraIDAnswer = sys.argv[1]
       #else:
       #    cameraIDAnswer = raw_input("Enter the Camera ID for your robot, you can get it by pointing a browser to the runmyrobot server %s: " % server)

       cameraIDAnswer = args.camera_id


       main()

    ERROR :

    ffmpeg -n -f mpegts -i http://54.183.232.63:12221 -i logo.png -filter_complex "[0:v]setsar=sar=1[v];[v][1]blend=all_mode='overlay':all_opacity=0.7" -movflags +faststart tmb/video.mp4
    ffmpeg version N-86215-gb5228e4 Copyright (c) 2000-2017 the FFmpeg developers
     built with gcc 4.9.2 (Raspbian 4.9.2-10)
     configuration: --arch=armel --target-os=linux --enable-gpl --enable-libx264 --enable-nonfree --extra-libs=-ldl
     libavutil      55. 63.100 / 55. 63.100
     libavcodec     57. 96.101 / 57. 96.101
     libavformat    57. 72.101 / 57. 72.101
     libavdevice    57.  7.100 / 57.  7.100
     libavfilter     6. 90.100 /  6. 90.100
     libswscale      4.  7.101 /  4.  7.101
     libswresample   2.  8.100 /  2.  8.100
     libpostproc    54.  6.100 / 54.  6.100
    [mpegts @ 0x1a57390] Could not detect TS packet size, defaulting to non-FEC/DVHS
    http://54.183.232.63:12221: could not find codec parameters
  • Using ffmpeg and ffserver to create a 2x1 live stream fails with unconnected output error

    31 janvier 2021, par weevilknievel

    I want to combine 2 RTSP streams (CCTV cameras) into a horizontal 2x1 strip and convert to webm for use in a HTML5 webpage.

    



    I am able to convert the streams into an mpeg or avi file easily, but as soon as I try to post it to ffserver ffm feed, I hit a wall.

    



    Here is my working ffmpeg command which writes out to a file :

    



    ffmpeg -rtsp_transport tcp -thread_queue_size 12 -i "rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=1&stream=1.sdp" -i "rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=2&stream=1.sdp" -filter_complex "[0:v][1:v] hstack=inputs=2 [v]" -map "[v]" -r 30 output.mpg


    



    It seems the ffmpeg process is outputting two streams and one of them is MPEG ? In the above command I had to put a frame rate "-r 30" into the command otherwise I got an error which said that MPEG 1/2 did not support a framerate of 5/1 ??

    



    As soon as I try and stream to ffserver, I get an error :

    



    ffmpeg -rtsp_transport tcp -thread_queue_size 12 -i "rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=1&stream=1.sdp" -i "rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=2&stream=1.sdp" -filter_complex "[0:v][1:v] hstack=inputs=2 [v]" -map "[v]" -r 30 http://localhost:8090/feed5.ffm


    



    The error I get is "Filter hstack has an unconnected output" :

    



    ffmpeg version N-86111-ga441aa90e8-static http://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 5.4.1 (Debian 5.4.1-8) 20170304
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-5 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gray --enable-libass --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg
  libavutil      55. 63.100 / 55. 63.100
  libavcodec     57. 96.101 / 57. 96.101
  libavformat    57. 72.101 / 57. 72.101
  libavdevice    57.  7.100 / 57.  7.100
  libavfilter     6. 89.101 /  6. 89.101
  libswscale      4.  7.101 /  4.  7.101
  libswresample   2.  8.100 /  2.  8.100
  libpostproc    54.  6.100 / 54.  6.100
Input #0, rtsp, from 'rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=1&stream=1.sdp':
  Duration: N/A, start: 0.166667, bitrate: N/A
    Stream #0:0: Video: h264 (High), yuv420p(progressive), 352x288, 6 fps, 6 tbr, 90k tbn, 180k tbc
Input #1, rtsp, from 'rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=2&stream=1.sdp':
  Duration: N/A, start: 0.166667, bitrate: N/A
    Stream #1:0: Video: h264 (High), yuv420p(progressive), 352x288, 6 fps, 6 tbr, 90k tbn, 180k tbc
Filter hstack has an unconnected output


    



    My ffserver conf is very basic :

    



    HTTPPort 8090&#xA;HTTPBindAddress 0.0.0.0&#xA;MaxHTTPConnections 2000&#xA;MaxClients 1000&#xA;MaxBandwidth 100000&#xA;CustomLog -&#xA;&#xA;<feed>&#xA;File /mnt/ramdisk/feed5.ffm&#xA;Truncate&#xA;FileMaxSize 5M&#xA;ACL allow 127.0.0.1&#xA;</feed>&#xA;&#xA;<stream>&#xA;     Format webm&#xA;     Feed feed5.ffm&#xA;     VideoCodec libvpx&#xA;     VideoSize 640x360&#xA;     NoAudio&#xA;   AVOptionVideo quality realtime&#xA;   StartSendOnKey&#xA;   VideoBitRate 140&#xA;</stream>&#xA;&#xA;<stream>&#xA;Format status&#xA;ACL allow localhost&#xA;ACL allow 192.168.0.0 192.168.255.255&#xA;</stream>&#xA;<redirect>&#xA;URL http://www.ffmpeg.org/&#xA;</redirect>&#xA;

    &#xA;&#xA;

    Edit :

    &#xA;&#xA;

    Here is the debug output from the ffmpeg command above :

    &#xA;&#xA;

    ffmpeg -v debug -rtsp_transport tcp -thread_queue_size 12 -i "rtsp://192.168.1.132:554/user=admin&amp;password=mypassword&amp;channel=1&amp;stream=1.sdp" -i "rtsp://192.168.1.132:554/user=admin&amp;password=mypassword&amp;channel=2&amp;stream=1.sdp" -filter_complex "[0:v][1:v] hstack=inputs=2 [v]" -map "[v]" -r 30 http://localhost:8090/feed5.ffm&#xA;ffmpeg version N-86111-ga441aa90e8-static http://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2017 the FFmpeg developers&#xA;  built with gcc 5.4.1 (Debian 5.4.1-8) 20170304&#xA;  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-5 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gray --enable-libass --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg&#xA;  libavutil      55. 63.100 / 55. 63.100&#xA;  libavcodec     57. 96.101 / 57. 96.101&#xA;  libavformat    57. 72.101 / 57. 72.101&#xA;  libavdevice    57.  7.100 / 57.  7.100&#xA;  libavfilter     6. 89.101 /  6. 89.101&#xA;  libswscale      4.  7.101 /  4.  7.101&#xA;  libswresample   2.  8.100 /  2.  8.100&#xA;  libpostproc    54.  6.100 / 54.  6.100&#xA;Splitting the commandline.&#xA;Reading option &#x27;-v&#x27; ... matched as option &#x27;v&#x27; (set logging level) with argument &#x27;debug&#x27;.&#xA;Reading option &#x27;-rtsp_transport&#x27; ... matched as AVOption &#x27;rtsp_transport&#x27; with argument &#x27;tcp&#x27;.&#xA;Reading option &#x27;-thread_queue_size&#x27; ... matched as option &#x27;thread_queue_size&#x27; (set the maximum number of queued packets from the demuxer) with argument &#x27;12&#x27;.&#xA;Reading option &#x27;-i&#x27; ... matched as input url with argument &#x27;rtsp://192.168.1.132:554/user=admin&amp;password=mypassword&amp;channel=1&amp;stream=1.sdp&#x27;.&#xA;Reading option &#x27;-i&#x27; ... matched as input url with argument &#x27;rtsp://192.168.1.132:554/user=admin&amp;password=mypassword&amp;channel=2&amp;stream=1.sdp&#x27;.&#xA;Reading option &#x27;-filter_complex&#x27; ... matched as option &#x27;filter_complex&#x27; (create a complex filtergraph) with argument &#x27;[0:v][1:v] hstack=inputs=2 [v]&#x27;.&#xA;Reading option &#x27;-map&#x27; ... matched as option &#x27;map&#x27; (set input stream mapping) with argument &#x27;[v]&#x27;.&#xA;Reading option &#x27;-r&#x27; ... matched as option &#x27;r&#x27; (set frame rate (Hz value, fraction or abbreviation)) with argument &#x27;30&#x27;.&#xA;Reading option &#x27;http://localhost:8090/feed5.ffm&#x27; ... matched as output url.&#xA;Finished splitting the commandline.&#xA;Parsing a group of options: global .&#xA;Applying option v (set logging level) with argument debug.&#xA;Applying option filter_complex (create a complex filtergraph) with argument [0:v][1:v] hstack=inputs=2 [v].&#xA;Successfully parsed a group of options.&#xA;Parsing a group of options: input url rtsp://192.168.1.132:554/user=admin&amp;password=mypassword&amp;channel=1&amp;stream=1.sdp.&#xA;Applying option thread_queue_size (set the maximum number of queued packets from the demuxer) with argument 12.&#xA;Successfully parsed a group of options.&#xA;Opening an input file: rtsp://192.168.1.132:554/user=admin&amp;password=mypassword&amp;channel=1&amp;stream=1.sdp.&#xA;[tcp @ 0x58fb5e0] No default whitelist set&#xA;[rtsp @ 0x58f9700] SDP:&#xA;v=0&#xA;o=- 38990265062388 38990265062388 IN IP4 192.168.1.132&#xA;a=range:npt=0-&#xA;m=video 0 RTP/AVP 96&#xA;c=IN IP4 0.0.0.0&#xA;a=rtpmap:96 H264/90000&#xA;a=framerate:0S&#xA;a=fmtp:96 profile-level-id=640014; packetization-mode=1; sprop-parameter-sets=Z2QAFK2EAQwgCGEAQwgCGEAQwgCEK1CwSyA=,aO48sA==&#xA;a=control:trackID=3&#xA;&#xA;Failed to parse interval end specification &#x27;&#x27;&#xA;[rtsp @ 0x58f9700] video codec set to: h264&#xA;[rtsp @ 0x58f9700] RTP Profile IDC: 64 Profile IOP: 0 Level: 14&#xA;[rtsp @ 0x58f9700] RTP Packetization Mode: 1&#xA;[rtsp @ 0x58f9700] Extradata set to 0x58fb940 (size: 38)&#xA;[rtsp @ 0x58f9700] setting jitter buffer size to 0&#xA;[rtsp @ 0x58f9700] hello state=0&#xA;[h264 @ 0x58fca00] nal_unit_type: 7, nal_ref_idc: 3&#xA;[h264 @ 0x58fca00] nal_unit_type: 8, nal_ref_idc: 3&#xA;[h264 @ 0x58fca00] nal_unit_type: 7, nal_ref_idc: 3&#xA;[h264 @ 0x58fca00] nal_unit_type: 8, nal_ref_idc: 3&#xA;[h264 @ 0x58fca00] unknown SEI type 229&#xA;[h264 @ 0x58fca00] nal_unit_type: 7, nal_ref_idc: 3&#xA;[h264 @ 0x58fca00] nal_unit_type: 8, nal_ref_idc: 3&#xA;[h264 @ 0x58fca00] nal_unit_type: 6, nal_ref_idc: 0&#xA;[h264 @ 0x58fca00] nal_unit_type: 5, nal_ref_idc: 3&#xA;[h264 @ 0x58fca00] unknown SEI type 229&#xA;[h264 @ 0x58fca00] Reinit context to 352x288, pix_fmt: yuv420p&#xA;[h264 @ 0x58fca00] nal_unit_type: 1, nal_ref_idc: 3&#xA;    Last message repeated 5 times&#xA;[h264 @ 0x58fca00] unknown SEI type 229&#xA;    Last message repeated 1 times&#xA;[rtsp @ 0x58f9700] All info found&#xA;[rtsp @ 0x58f9700] Setting avg frame rate based on r frame rate&#xA;Input #0, rtsp, from &#x27;rtsp://192.168.1.132:554/user=admin&amp;password=mypassword&amp;channel=1&amp;stream=1.sdp&#x27;:&#xA;  Duration: N/A, start: 0.166667, bitrate: N/A&#xA;    Stream #0:0, 28, 1/90000: Video: h264 (High), 1 reference frame, yuv420p(progressive, left), 352x288, 0/1, 6 fps, 6 tbr, 90k tbn, 180k tbc&#xA;Successfully opened the file.&#xA;Parsing a group of options: input url rtsp://192.168.1.132:554/user=admin&amp;password=mypassword&amp;channel=2&amp;stream=1.sdp.&#xA;Successfully parsed a group of options.&#xA;Opening an input file: rtsp://192.168.1.132:554/user=admin&amp;password=mypassword&amp;channel=2&amp;stream=1.sdp.&#xA;[tcp @ 0x59f4280] No default whitelist set&#xA;[rtsp @ 0x59f7620] SDP:&#xA;v=0&#xA;o=- 38990265062388 38990265062388 IN IP4 192.168.1.132&#xA;a=range:npt=0-&#xA;m=video 0 RTP/AVP 96&#xA;c=IN IP4 0.0.0.0&#xA;a=rtpmap:96 H264/90000&#xA;a=framerate:0S&#xA;a=fmtp:96 profile-level-id=640014; packetization-mode=1; sprop-parameter-sets=Z2QAFK2EAQwgCGEAQwgCGEAQwgCEK1CwSyA=,aO48sA==&#xA;a=control:trackID=3&#xA;&#xA;Failed to parse interval end specification &#x27;&#x27;&#xA;[rtsp @ 0x59f7620] video codec set to: h264&#xA;[rtsp @ 0x59f7620] RTP Profile IDC: 64 Profile IOP: 0 Level: 14&#xA;[rtsp @ 0x59f7620] RTP Packetization Mode: 1&#xA;[rtsp @ 0x59f7620] Extradata set to 0x59f3670 (size: 38)&#xA;[rtp @ 0x59f62a0] No default whitelist set&#xA;[udp @ 0x58fb6a0] No default whitelist set&#xA;[udp @ 0x58fb6a0] end receive buffer size reported is 131072&#xA;[udp @ 0x591b940] No default whitelist set&#xA;[udp @ 0x591b940] end receive buffer size reported is 131072&#xA;[rtsp @ 0x59f7620] setting jitter buffer size to 500&#xA;[rtsp @ 0x59f7620] hello state=0&#xA;[h264 @ 0x59e4b20] nal_unit_type: 7, nal_ref_idc: 3&#xA;[h264 @ 0x59e4b20] nal_unit_type: 8, nal_ref_idc: 3&#xA;[h264 @ 0x59e4b20] nal_unit_type: 7, nal_ref_idc: 3&#xA;[h264 @ 0x59e4b20] nal_unit_type: 8, nal_ref_idc: 3&#xA;[h264 @ 0x59e4b20] unknown SEI type 229&#xA;[h264 @ 0x59e4b20] nal_unit_type: 7, nal_ref_idc: 3&#xA;[h264 @ 0x59e4b20] nal_unit_type: 8, nal_ref_idc: 3&#xA;[h264 @ 0x59e4b20] nal_unit_type: 6, nal_ref_idc: 0&#xA;[h264 @ 0x59e4b20] nal_unit_type: 5, nal_ref_idc: 3&#xA;[h264 @ 0x59e4b20] unknown SEI type 229&#xA;[h264 @ 0x59e4b20] Reinit context to 352x288, pix_fmt: yuv420p&#xA;[h264 @ 0x59e4b20] nal_unit_type: 1, nal_ref_idc: 3&#xA;    Last message repeated 5 times&#xA;[h264 @ 0x59e4b20] unknown SEI type 229&#xA;    Last message repeated 1 times&#xA;[rtsp @ 0x59f7620] All info found&#xA;[rtsp @ 0x59f7620] Setting avg frame rate based on r frame rate&#xA;Input #1, rtsp, from &#x27;rtsp://192.168.1.132:554/user=admin&amp;password=mypassword&amp;channel=2&amp;stream=1.sdp&#x27;:&#xA;  Duration: N/A, start: 0.166667, bitrate: N/A&#xA;    Stream #1:0, 28, 1/90000: Video: h264 (High), 1 reference frame, yuv420p(progressive, left), 352x288, 0/1, 6 fps, 6 tbr, 90k tbn, 180k tbc&#xA;Successfully opened the file.&#xA;detected 2 logical cores&#xA;[Parsed_hstack_0 @ 0x59f7cc0] Setting &#x27;inputs&#x27; to value &#x27;2&#x27;&#xA;Parsing a group of options: output url http://localhost:8090/feed5.ffm.&#xA;Applying option map (set input stream mapping) with argument [v].&#xA;Applying option r (set frame rate (Hz value, fraction or abbreviation)) with argument 30.&#xA;Successfully parsed a group of options.&#xA;Opening an output file: http://localhost:8090/feed5.ffm.&#xA;[http @ 0x59aa700] Setting default whitelist &#x27;http,https,tls,rtp,tcp,udp,crypto,httpproxy&#x27;&#xA;[http @ 0x59aa700] request: GET /feed5.ffm HTTP/1.1&#xA;User-Agent: Lavf/57.72.101&#xA;Accept: */*&#xA;Range: bytes=0-&#xA;Connection: close&#xA;Host: localhost:8090&#xA;Icy-MetaData: 1&#xA;&#xA;&#xA;[ffm @ 0x5917d00] Format ffm probed with size=2048 and score=101&#xA;[NULL @ 0x5bce3e0] Setting entry with key &#x27;video_size&#x27; to value &#x27;640x360&#x27;&#xA;[NULL @ 0x5bce3e0] Setting entry with key &#x27;b&#x27; to value &#x27;140000&#x27;&#xA;[NULL @ 0x5bce3e0] Setting entry with key &#x27;time_base&#x27; to value &#x27;1/5&#x27;&#xA;[NULL @ 0x5bce3e0] Setting entry with key &#x27;bt&#x27; to value &#x27;35000&#x27;&#xA;[NULL @ 0x5bce3e0] Setting entry with key &#x27;rc_eq&#x27; to value &#x27;tex^qComp&#x27;&#xA;[NULL @ 0x5bce3e0] Setting entry with key &#x27;maxrate&#x27; to value &#x27;280000&#x27;&#xA;[NULL @ 0x5bce3e0] Setting entry with key &#x27;bufsize&#x27; to value &#x27;280000&#x27;&#xA;[AVIOContext @ 0x5915b80] Statistics: 4096 bytes read, 0 seeks&#xA;[http @ 0x5915f00] Setting default whitelist &#x27;http,https,tls,rtp,tcp,udp,crypto,httpproxy&#x27;&#xA;[http @ 0x5915f00] request: POST /feed5.ffm HTTP/1.1&#xA;Transfer-Encoding: chunked&#xA;User-Agent: Lavf/57.72.101&#xA;Accept: */*&#xA;Connection: close&#xA;Host: localhost:8090&#xA;Icy-MetaData: 1&#xA;&#xA;&#xA;Successfully opened the file.&#xA;Filter hstack has an unconnected output&#xA;[AVIOContext @ 0x59ab080] Statistics: 0 seeks, 0 writeouts&#xA;

    &#xA;&#xA;

    I am stumped - any clues ?

    &#xA;&#xA;

    Thanks in advance.

    &#xA;