Git Product home page Git Product logo

Comments (9)

AlexxIT avatar AlexxIT commented on June 18, 2024

There's a lot of confusion in your post:

  • tcp://192.168.0.5:50000 (port and IP)
  • where SDP came from?
  • m=audio 5000 (port) m=video 5002 (port)
  • speex/8000/1 - not supported codec
  • tcp://192.168.0.20:50000 (port and IP)

from go2rtc.

slyoldfox avatar slyoldfox commented on June 18, 2024
  • tcp://192.168.0.5:50000 and tcp://192.168.0.20:50000 were both the same. It's a simple TCP socket that writes a (fixed) SDP. I succesfully use it with the command ffmpeg -f sdp -i tcp://192.168.0.5:5000 ... and transcode the speex codec there to PCMA. The usage of the SDP is mandatory for ffmpeg because you can't use ffmpeg -f rtp -i videoinput -f rtp -i audioinput form the command line.
  • This intercom sends RTP packets on port 5000 for the audio and 5002 for video - the codecs and ports are fixed on the intercom side
  • I understand that speex is not supported, but the #audio=pcma option works as expected so it is not really relevant to the issue

The only issue I'm seeing is that the reconnect from the gortc worker doesn't seem to close in time, which causes the ffmpeg process to still be running when the intercom stops sending packets and the go2rtc reconnects.
Since ffmpeg will bind() to the UDP ports 5000 and 5002 taken from the SDP - it will fail because the previous ffmpeg is still bound to these ports.

I was looking if pkg/magic/producer.go could support SDP detection from the TCP socket natively, I suppose it might fit in at some point by checking if the first 4 bytes are "v=0", but that's another story :-)

from go2rtc.

AlexxIT avatar AlexxIT commented on June 18, 2024

It didn't get any better.

  • 192.168.0.5 and 192.168.0.20 - different IPs, they're definitely not same
  • 50000 and 5000 - different ports

I still don't understand the whole data flow.

PS. SDP over TCP it's really another story. It doesn't meet any standards.

from go2rtc.

slyoldfox avatar slyoldfox commented on June 18, 2024

I am sorry if the flow is confusing, I admit that this bticino intercom is quite exotic in its setup.

192.168.0.20 is the IP address of the intercom and exposes the SDP via a normal socket call on TCP port 50000.
192.168.0.5 is my development computer, where I also have a TCP socket running on port 50000 for debugging, ignore this IP, I have changed the initial comment).

Everything starts out with a receiver calling TCP port 50000 on the intercom IP (192.168.0.20). The intercom will return the SDP above in the reply on the socket. Internally, the intercom will setup a SIP call between itself and the outdoor camera unit, it is not really relevant to you, but the TCP socket on port 50000 triggers the SIP call internally.

Once the SIP call is established internally, it will (re)stream the RTP UDP packets on port 5000 (for audio) and RDP UDP packets on port 5002 (for video) - as provided in the SDP by the TCP socket on port 50000 - towards the receiver.

The receiver binds on UDP ports 5000 and 5002 to receive these packets and process them (ffmpeg does this internally after having parsed the SDP).

So to summarize - hopefully a little more clear:

  1. receiver starts ffmpeg with -f sdp -i tcp://192.168.0.20:50000
  2. intercom is listening on TCP port 50000 and returns the SDP which specifies that audio and video will be sent on UDP ports 5000 and 5002 respectively, the intercom starts sending these packets to the IP address to the receiver. These packets are RTP packets over UDP.
  3. ffmpeg on the receiver parses this SDP and binds to UDP ports 5000 and 5002 to process the RTP packets.

from go2rtc.

AlexxIT avatar AlexxIT commented on June 18, 2024
  1. Where does intercom get the IP-address to send UDP? Will this be the same address where the TCP request to port 50000 came from or is this configurable separately?
  2. What software is this 50000 port even made for? Does anything other than ffmpeg know how to receive SDP over TCP?
  3. It doesn't make sense for magic/producer.go to support SDP because go2rtc doesn't manage to open random ports to receive UDP data. Also because of your problem - we can't specify the ports ourselves and they may be busy.

OK. I'll try to reproduce your situation about reconnecting issue.

from go2rtc.

slyoldfox avatar slyoldfox commented on June 18, 2024

Thank you! If it's any help, this is the command I use to simulate packets sent from the intercom to the receiver:

ffmpeg -re -f lavfi -i "color=red:size=688x480:rate=15" -f lavfi -i "sine=frequency=1000:b=4" -profile:v baseline -preset ultrafast -g 15 -vcodec libx264 -an -tune zerolatency -f rtp "rtp://GO2RTCIP:5002" -vn -ar 8000 -acodec speex -f rtp -payload_type 110 "rtp://GO2RTCIP:5000"

Replace GO2RTCIP with the IP of your local receiver of course.

You will see that ffmpeg spits out an SDP which matches the SDP that gets returned by the socket server on port 50000.

In theory ffmpeg doesn't care if the SDP is provided from a local file (with -i /local/test.sdp) or over a socket (with -i tcp://IP:50000). In some way it is smart enough to detect that the format is SDP and thus providing -f sdp is not really required on the receiver side.

The following snippet runs the socket server on nodejs to simulate the SDP serving on port 50000.

const net = require("net");
const server = new net.createServer(); 

const sdp = `v=0
m=audio 5000 RTP/AVP 110
c=IN IP4 127.0.0.1
a=rtpmap:110 speex/8000/1
m=video 5002 RTP/AVP 96
c=IN IP4 127.0.0.1
a=rtpmap:96 H264/90000`
server.on("connection", client => {
    client.on('close', () => {
        console.log("Socket DISCONNECTED");
    })

    client.on("data", function (data) {
        console.log("Server received data: " + data);
    });
    console.log("Wrote sdp: " + sdp)
    client.write(sdp)
    client.destroy()

});
server.on("listening", () => {
    console.log(`SDP server listening on ${server.address().address}:${server.address().port}`)
})

server.listen(50000, "0.0.0.0");

from go2rtc.

AlexxIT avatar AlexxIT commented on June 18, 2024

I can't confirm your problem. Reconnection works fine. Only one ffmpeg active.
I'm testing latest master branch in Windows.
Maybe problem with go2rtc v1.9.0 or your Mac or something else.

import socket
import subprocess

sdp = b"""v=0
m=audio 5000 RTP/AVP 110
c=IN IP4 127.0.0.1
a=rtpmap:110 speex/8000/1
m=video 5002 RTP/AVP 96
c=IN IP4 127.0.0.1
a=rtpmap:96 H264/90000
"""
exec = "ffmpeg -re -i bbb.mp4 -an -c:v libx264 -g 50 -profile:v high -level:v 4.1 -preset:v superfast -tune:v zerolatency -f rtp rtp://127.0.0.1:5002 -vn -c:a speex -ar:a 8000 -ac:a 1 -f rtp -payload_type 110 rtp://127.0.0.1:5000"

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("127.0.0.1", 50000))
s.listen()
while True:
    conn, addr = s.accept()
    conn.send(sdp)
    conn.close()
    subprocess.call(exec.split(" "))
streams:
  issue-1084: ffmpeg:tcp://127.0.0.1:50000#video=copy#audio=pcma

from go2rtc.

slyoldfox avatar slyoldfox commented on June 18, 2024

Hi, thank you for taking the time to look at this.

I'm not sure what differs, might indeed be OS related (different timeout levels on the socket level?).

At the moment I worked around the issue by randomizing the two ports (5000 and 5002) which are in the SDP, in this case the client never has to bind to the same port and the issue becomes less relevant.

You can close this for now if you'd like, thanks again!

from go2rtc.

AlexxIT avatar AlexxIT commented on June 18, 2024

There is a known issue that FFmpeg won't close. It's old. I can't replicate it either. Maybe this is the same problem. Related to some kind of environment.

from go2rtc.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.