meetecho / simple-whip-client Goto Github PK
View Code? Open in Web Editor NEWSimple WHIP Client (based on GStreamer's webrtcbin)
License: GNU General Public License v3.0
Simple WHIP Client (based on GStreamer's webrtcbin)
License: GNU General Public License v3.0
I have the same issue in whep client.
I built it with
docker build -t simple-whip-client .
frhb64652ds simple-whip-client # docker run -it --rm -e "URL=https://fr.xxx.com/api/whip?stream=ff_mur_test?token=9a58a1a2-f953-4904-97a6-35b3354c8ae2" simple-whip-client
WHIP endpoint: https://fr.xxx.com/api/whip?stream=ff_mur_test?token=9a58a1a2-f953-4904-97a6-35b3354c8ae2
Bearer Token: (none)
Trickle ICE: yes (HTTP PATCH)
Auto STUN/TURN: no
STUN server: stun://stun.l.google.com:19302
TURN server: (none)
Audio pipeline: audiotestsrc is-live=true wave=red-noise ! audioconvert ! audioresample ! queue ! opusenc ! rtpopuspay pt=100 ssrc=1 ! queue ! application/x-rtp,media=audio,encoding-name=OPUS,payload=100
Video pipeline: videotestsrc is-live=true pattern=ball ! videoconvert ! queue ! vp8enc deadline=1 ! rtpvp8pay pt=96 ssrc=2 ! queue ! application/x-rtp,media=video,encoding-name=VP8,payload=96
[WHIP] Initializing the GStreamer pipeline:
webrtcbin name=sendonly bundle-policy=3 stun-server=stun://stun.l.google.com:19302 videotestsrc is-live=true pattern=ball ! videoconvert ! queue ! vp8enc deadline=1 ! rtpvp8pay pt=96 ssrc=2 ! queue ! application/x-rtp,media=video,encoding-name=VP8,payload=96 ! sendonly. audiotestsrc is-live=true wave=red-noise ! audioconvert ! audioresample ! queue ! opusenc ! rtpopuspay pt=100 ssrc=1 ! queue ! application/x-rtp,media=audio,encoding-name=OPUS,payload=100 ! sendonly.
(whip-client:7): libsoup-ERROR **: 03:14:03.702: libsoup2 symbols detected. Using libsoup2 and libsoup3 in the same process is not supported.
Trace/breakpoint trap (core dumped)
--
It would be great if I could test WHIP / WHEP with Gstreamer standalone (using Rust plugins such as whipsink) but I can't get it to work. I was hoping I could use simple-whip-client but due to the changes in packages, it doesn't seem to be working for me :(
This is what I get when I run make:
src/whip-client.c:19:10: fatal error: gst/gst.h: No such file or directory
19 | #include <gst/gst.h>
| ^~~~~~~~~~~
compilation terminated.
make: *** [Makefile:11: src/whip-client.o] Error 1
I get this inside the logs when I start a WHIP client:
** (whip-client:13762): WARNING **: 12:40:24.775: Failed to GET http://192.168.68.1:1900/cjllo/rootDesc.xml: Connection terminated unexpectedly, retrying in 10 seconds
I am trying to graduate beyond the ball example but the pipeline seems stuck and does not start. What am I doing wrong?
./whip-client -u http://serverexample.com:7080/whip/endpoint/drone -t veryverysecret -V "multifilesrc location=drone.mp4 loop=true ! qtdemux ! h264parse ! rtph264pay ! application/x-rtp,media=video,encoding-name=H264,payload=96" -S stun://stun.l.google.com:19302
--------------------
Simple WHIP client
------------------
WHIP endpoint: http://serverexample.com:7080/whip/endpoint/drone
Bearer Token: veryverysecret
Trickle ICE: yes (HTTP PATCH)
Auto STUN/TURN: no
STUN server: stun://stun.l.google.com:19302
TURN server: (none)
Audio pipeline: (none)
Video pipeline: multifilesrc location=drone.mp4 loop=true ! qtdemux ! h264parse ! rtph264pay ! application/x-rtp,media=video,encoding-name=H264,payload=96
[WHIP] Initializing the GStreamer pipeline:
webrtcbin name=sendonly bundle-policy=0 stun-server=stun://stun.l.google.com:19302 multifilesrc location=drone.mp4 loop=true ! qtdemux ! h264parse ! rtph264pay ! application/x-rtp,media=video,encoding-name=H264,payload=96 ! sendonly.
[WHIP] Starting the GStreamer pipeline
I've tried vp8, vp9 and h264 with no luck, see:
https://www.reddit.com/r/WebRTC/comments/12nc5md/twitchtv_now_supports_webrtc_ingestion_via_whip/
cc @Sean-Der
By contrast, https://github.com/ggarber/whip-go does work with twitch.tv.
Hi,
I'm using simple-whip-client to broadcast to Dolby. I found that this error Error creating GUPnP context: Failed to bind socketError binding to address 10.10.10.122:1990: Cannot assign requested address
always occur after running for around 1-2 hours. During this time nothing was changed. And there are not much debug information for this. What might be the cause of this problem? Any help would be appreciated.
Thank you!
You can already manually change the code to remove colours but you can't do it from the command line.
Also, if you turn off colours in the codebase, the [WHIP]
prefix still has colors.
Hi
We tried to publish an RTSP stream using the simple-whip-client towards Millicast.
It works, at least it publishes video to Millicast, but the playback is not smooth, a lot of framedrops, no smooth image, ...
When trying the 'old' method, publishing using RMTP, playback is smooth (given the 3sec delay).
WHIP command:
docker run -it --rm -e "U=https://director.millicast.com/api/whip/STREAM" -e "T=TOKEN" -e "V=rtspsrc location=rtsp://192.168.30.3/Streaming/Channels/1 latency=0 name=rtsp ! rtph264depay ! rtph264pay config-interval=-1 ! application/x-rtp,media=video,encoding-name=H264" simple-whip-client
I ran the simple-whip-client on both RPI4 and on a X86 Mac OS, both using docker.
The DockerFile entrypoint was changed a bit to be able to pass the TOKEN
ENV U=http://localhost:3000/whip/foo
ENV T=
ENV A="audiotestsrc is-live=true wave=red-noise ! audioconvert ! audioresample ! queue ! opusenc ! rtpopuspay pt=100 ssrc=1 ! queue ! application/x-rtp,media=audio,encoding-name=OPUS,payload=100"
ENV V="videotestsrc is-live=true pattern=ball ! videoconvert ! queue ! vp8enc deadline=1 ! rtpvp8pay pt=96 ssrc=2 ! queue ! application/x-rtp,media=video,encoding-name=VP8,payload=96"
ENTRYPOINT ./whip-client -l 7 -u $U -t $T -V "$V" -A "$A" -S stun://stun.l.google.com:19302
GStreamer command
gst-launch-1.0 \
rtspsrc location=rtsp://192.168.30.3/Streaming/Channels/1 latency=0 ! rtph264depay ! flvmux name=mux ! queue ! rtmpsink location="rtmp://live-rtmp-pub.millicast.com:1935/v2/pub/STREAM?token=TOKEN live=1"
The new version of the WHIP draft adds support for an automatic configuration of STUN/TURN servers to use in WHIP clients:
https://www.ietf.org/archive/id/draft-ietf-wish-whip-01.html#name-stun-turn-server-configurat
The way it works is that WHIP servers can return a series of STUN/TURN servers (and credentials, if needed) in Link
headers in the 201
in response to the HTTP POST (or optionally in response to the OPTIONS too), e.g.:
Link: stun:stun.example.net; rel="ice-server";
Link: turn:turn.example.net?transport=udp; rel="ice-server"; username="user"; credential: "myPassword"; credential-type: "password";
Link: turn:turn.example.net?transport=tcp; rel="ice-server"; username="user"; credential: "myPassword"; credential-type: "password";
Link: turns:turn.example.net?transport=tcp; rel="ice-server"; username="user"; credential: "myPassword"; credential-type: "password";
The WHIP client can then parse those Link
values and add the STUN/TURN servers to its own stack for gathering.
Unfortunately, this seems not to work as expected with GStreamer's webrtcbin. While there is, for instance, an add-turn-server signal that can be used to add a TURN server dynamically (which is what we now use for adding TURN servers at startup too, as implemented in #2), that doesn't seem to have any effect after the pipeline has been started. I tried delaying the set-local-description
call to after we set the servers, and that didn't help.
Checking the code:
add-turn-server
calls gst_webrtc_bin_add_turn_server
, which in turn calls gst_webrtc_ice_add_turn_server
;gst_webrtc_ice_add_turn_server
just adds the new server to a hashtable, ice->turn_servers
.The internal method that actually adds the TURN server to the libnice stack via nice_agent_set_relay_info
, though, is _add_turn_server
, which is only called by gst_webrtc_ice_add_stream
. Since we add a stream when we first create our pipeline, and so always before we prepare an offer, trying to add a STUN/TURN server after that will not work.
The WHIP draft does have some text about this:
There are some webrtc implementations that do not support updating the ICE server configuration after the local offer has been created. In order to support these clients, the WHIP endpoint MAY also include the ICE server configuration on the responses to an authenticated OPTIONS request sent to the WHIP endpoint URL sent before the POST requests.
As such, I'll try to modify the WHIP server to also return a set of STUN/TURN servers in response to an OPTIONS on the endpoint URL, rather than just to the POST as I do now. This way, I can issue an OPTIONS request from the WHIP client before we create the pipeline, which should give us access to STUN/TURN servers we can actually use.
I'm currently running Janus in an EC2 instance and I have the demo video room test running fine. I have on that instance the simple-whip-server PoC. Both are connected to my SSL cert and appear to be working fine. When I run the whip client in docker I'm getting the following output
docker run -it --rm -e "URL=https://janus.rapidsos.tools:7080/whip/endpoint/test" simple-whip-client
--------------------
Simple WHIP client
------------------
WHIP endpoint: https://janus.mydomain.com:7080/whip/endpoint/test
Bearer Token: (none)
Trickle ICE: yes (HTTP PATCH)
Auto STUN/TURN: no
STUN server: stun://stun.l.google.com:19302
TURN server: (none)
Audio pipeline: audiotestsrc is-live=true wave=red-noise ! audioconvert ! audioresample ! queue ! opusenc ! rtpopuspay pt=100 ssrc=1 ! queue ! application/x-rtp,media=audio,encoding-name=OPUS,payload=100
Video pipeline: videotestsrc is-live=true pattern=ball ! videoconvert ! queue ! vp8enc deadline=1 ! rtpvp8pay pt=96 ssrc=2 ! queue ! application/x-rtp,media=video,encoding-name=VP8,payload=96
[WHIP] Initializing the GStreamer pipeline:
webrtcbin name=sendonly bundle-policy=3 stun-server=stun://stun.l.google.com:19302 videotestsrc is-live=true pattern=ball ! videoconvert ! queue ! vp8enc deadline=1 ! rtpvp8pay pt=96 ssrc=2 ! queue ! application/x-rtp,media=video,encoding-name=VP8,payload=96 ! sendonly. audiotestsrc is-live=true wave=red-noise ! audioconvert ! audioresample ! queue ! opusenc ! rtpopuspay pt=100 ssrc=1 ! queue ! application/x-rtp,media=audio,encoding-name=OPUS,payload=100 ! sendonly.
[WHIP] Configured jitter-buffer size (latency) for PeerConnection to 200ms
[WHIP] Starting the GStreamer pipeline
[WHIP] Creating offer
[WHIP] Offer created
[WHIP] Setting local description
[WHIP] Sending SDP offer (1167 bytes)
[WHIP] Resource URL: https://janus.mydomain.com:7080/whip/resource/CTz8kBP22jb57DJT
[WHIP] Received SDP answer (1102 bytes)
[WHIP] Setting remote description
[WHIP] ICE gathering started...
[WHIP] ICE connecting...
[WHIP] PeerConnection connecting...
[WHIP] ICE gathering completed
[WHIP] [ERR] [src/whip-client.c:whip_ice_connection_state:629] ICE failed
[WHIP] Disconnecting from server (ICE failed)
[WHIP] [ERR] [src/whip-client.c:whip_connection_state:575] PeerConnection failed
[WHIP] DTLS connection closed
[WHIP] GStreamer pipeline stopped
Bye!
I'm getting ICE failed, but I'm not getting any significant errors from Janus, here's my output from there
[Tue Dec 12 19:34:40 2023] Creating new handle in session 4668403263767977: 6128063846331052; 0x7f05d00294b0 0x7f05d000dba0
[Tue Dec 12 19:34:40 2023] [6128063846331052] Creating ICE agent (ICE Full mode, controlled)
[Tue Dec 12 19:34:49 2023] Detaching handle from JANUS VideoRoom plugin; 0x7f05d000dba0 0x7f05d00244d0 0x7f05d000dba0 0x7f05d000c5b0
[Tue Dec 12 19:34:49 2023] [janus.plugin.videoroom-0x7f05d00244d0] No WebRTC media anymore; 0x7f05d000dba0 0x7f05d000c5b0
[Tue Dec 12 19:34:49 2023] [6128063846331052] WebRTC resources freed; 0x7f05d000dba0 0x7f05d00294b0
[Tue Dec 12 19:34:49 2023] [6128063846331052] Handle and related resources freed; 0x7f05d000dba0 0x7f05d00294b0
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.