mirror of
https://gitlab.crans.org/nounous/ghostream.git
synced 2025-02-15 11:01:16 +00:00
Compare commits
3 Commits
9e7e1ec0b8
...
f394af9257
Author | SHA1 | Date | |
---|---|---|---|
|
f394af9257 | ||
|
5b40aa886f | ||
|
9fc3d37e72 |
2
go.mod
2
go.mod
@ -5,7 +5,7 @@ go 1.13
|
|||||||
require (
|
require (
|
||||||
github.com/go-ldap/ldap/v3 v3.2.3
|
github.com/go-ldap/ldap/v3 v3.2.3
|
||||||
github.com/gorilla/websocket v1.4.0
|
github.com/gorilla/websocket v1.4.0
|
||||||
github.com/haivision/srtgo v0.0.0-20200731151239-e00427ae473a
|
github.com/haivision/srtgo v0.0.0-20201025191851-67964e8f497a
|
||||||
github.com/markbates/pkger v0.17.1
|
github.com/markbates/pkger v0.17.1
|
||||||
github.com/pion/rtp v1.6.0
|
github.com/pion/rtp v1.6.0
|
||||||
github.com/pion/webrtc/v3 v3.0.0-beta.5
|
github.com/pion/webrtc/v3 v3.0.0-beta.5
|
||||||
|
4
go.sum
4
go.sum
@ -122,6 +122,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpg
|
|||||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
github.com/haivision/srtgo v0.0.0-20200731151239-e00427ae473a h1:JliMkv/mAqM5+QzG6Hkw1XcVl1crU8yIQGnhppMv7s0=
|
github.com/haivision/srtgo v0.0.0-20200731151239-e00427ae473a h1:JliMkv/mAqM5+QzG6Hkw1XcVl1crU8yIQGnhppMv7s0=
|
||||||
github.com/haivision/srtgo v0.0.0-20200731151239-e00427ae473a/go.mod h1:yVZ4oACfcnUAcxrh+0b6IuIWfkHLK3IAQ99tuuhRx54=
|
github.com/haivision/srtgo v0.0.0-20200731151239-e00427ae473a/go.mod h1:yVZ4oACfcnUAcxrh+0b6IuIWfkHLK3IAQ99tuuhRx54=
|
||||||
|
github.com/haivision/srtgo v0.0.0-20201025191851-67964e8f497a h1:54abJQezjMoiP+xMQ3ZQbcDXFjqytAYm/n0EVqrYeXg=
|
||||||
|
github.com/haivision/srtgo v0.0.0-20201025191851-67964e8f497a/go.mod h1:7izzTiCO3zc9ZIVTFMjxUiYL+kgryFP9rl3bsweqdmc=
|
||||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
@ -416,6 +418,8 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20200610111108-226ff32320da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200610111108-226ff32320da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80=
|
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80=
|
||||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c h1:38q6VNPWR010vN82/SB121GujZNIfAUb4YttE2rhGuc=
|
||||||
|
golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
// Package srt serves a SRT server
|
// Package srt serves a SRT server
|
||||||
package srt
|
package srt
|
||||||
|
|
||||||
// #include <srt/srt.h>
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
@ -62,7 +59,7 @@ func Serve(streams *messaging.Streams, authBackend auth.Backend, cfg *Options) {
|
|||||||
|
|
||||||
for {
|
for {
|
||||||
// Wait for new connection
|
// Wait for new connection
|
||||||
s, err := sck.Accept()
|
s, _, err := sck.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Something wrong happened
|
// Something wrong happened
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
@ -73,7 +70,7 @@ func Serve(streams *messaging.Streams, authBackend auth.Backend, cfg *Options) {
|
|||||||
// Without this, the SRT buffer might get full before reading it
|
// Without this, the SRT buffer might get full before reading it
|
||||||
|
|
||||||
// streamid can be "name:password" for streamer or "name" for viewer
|
// streamid can be "name:password" for streamer or "name" for viewer
|
||||||
streamID, err := s.GetSockOptString(C.SRTO_STREAMID)
|
streamID, err := s.GetSockOptString(srtgo.SRTO_STREAMID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print("Failed to get socket streamid")
|
log.Print("Failed to get socket streamid")
|
||||||
continue
|
continue
|
||||||
|
@ -3,7 +3,9 @@ package webrtc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
||||||
@ -17,20 +19,23 @@ func ingest(name string, q *messaging.Quality) {
|
|||||||
videoInput := make(chan []byte, 1024)
|
videoInput := make(chan []byte, 1024)
|
||||||
q.Register(videoInput)
|
q.Register(videoInput)
|
||||||
|
|
||||||
// Open a UDP Listener for RTP Packets on port 5004
|
// FIXME Mux into RTP without having multiple UDP listeners
|
||||||
audioListener, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 5004})
|
firstPort := int(rand.Int31n(63535)) + 2000
|
||||||
|
|
||||||
|
// Open UDP listeners for RTP Packets
|
||||||
|
audioListener, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: firstPort})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Faited to open UDP listener %s", err)
|
log.Printf("Faited to open UDP listener %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
videoListener, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 5005})
|
videoListener, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: firstPort + 1})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Faited to open UDP listener %s", err)
|
log.Printf("Faited to open UDP listener %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start ffmpag to convert videoInput to video and audio UDP
|
// Start ffmpag to convert videoInput to video and audio UDP
|
||||||
ffmpeg, err := startFFmpeg(videoInput)
|
ffmpeg, err := startFFmpeg(videoInput, firstPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error while starting ffmpeg: %s", err)
|
log.Printf("Error while starting ffmpeg: %s", err)
|
||||||
return
|
return
|
||||||
@ -115,14 +120,14 @@ func ingest(name string, q *messaging.Quality) {
|
|||||||
q.Unregister(videoInput)
|
q.Unregister(videoInput)
|
||||||
}
|
}
|
||||||
|
|
||||||
func startFFmpeg(in <-chan []byte) (ffmpeg *exec.Cmd, err error) {
|
func startFFmpeg(in <-chan []byte, listeningPort int) (ffmpeg *exec.Cmd, err error) {
|
||||||
ffmpegArgs := []string{"-hide_banner", "-loglevel", "error", "-i", "pipe:0",
|
ffmpegArgs := []string{"-hide_banner", "-loglevel", "error", "-i", "pipe:0",
|
||||||
// Audio
|
// Audio
|
||||||
"-vn", "-c:a", "libopus", "-b:a", "160k",
|
"-vn", "-c:a", "libopus", "-b:a", "160k",
|
||||||
"-f", "rtp", "rtp://127.0.0.1:5004",
|
"-f", "rtp", fmt.Sprintf("rtp://127.0.0.1:%d", listeningPort),
|
||||||
// Source
|
// Source
|
||||||
"-an", "-c:v", "copy", "-b:v", "3000k", "-maxrate", "5000k", "-bufsize", "5000k",
|
"-an", "-c:v", "copy", "-b:v", "3000k", "-maxrate", "5000k", "-bufsize", "5000k",
|
||||||
"-f", "rtp", "rtp://127.0.0.1:5005"}
|
"-f", "rtp", fmt.Sprintf("rtp://127.0.0.1:%d", listeningPort+1)}
|
||||||
ffmpeg = exec.Command("ffmpeg", ffmpegArgs...)
|
ffmpeg = exec.Command("ffmpeg", ffmpegArgs...)
|
||||||
|
|
||||||
// Handle errors output
|
// Handle errors output
|
||||||
|
@ -21,11 +21,7 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<b>Serveur :</b>
|
<b>Serveur :</b>
|
||||||
<code>srt://{{.Cfg.Hostname}}:{{.Cfg.SRTServerPort}}</code>,
|
<code>srt://{{.Cfg.Hostname}}:{{.Cfg.SRTServerPort}}?IDENTIFIANT:MOT_DE_PASS</code>,
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<b>Clé de stream :</b>
|
|
||||||
<code>IDENTIFIANT:MOT_DE_PASSE</code>
|
|
||||||
avec <code>IDENTIFIANT</code> et <code>MOT_DE_PASSE</code>
|
avec <code>IDENTIFIANT</code> et <code>MOT_DE_PASSE</code>
|
||||||
vos identifiants.
|
vos identifiants.
|
||||||
</li>
|
</li>
|
||||||
@ -52,6 +48,81 @@
|
|||||||
</code>
|
</code>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h2>Comment lire un flux depuis un lecteur externe ?</h2>
|
||||||
|
<p>
|
||||||
|
À l'heure actuelle, la plupart des lecteurs vidéos ne supportent
|
||||||
|
pas le protocole SRT, ou le supportent mal. Un travail est en
|
||||||
|
cours pour les rendre un maximum compatibles. Liste non exhaustive
|
||||||
|
des lecteurs vidéos testés :
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>FFPlay</h3>
|
||||||
|
<p>
|
||||||
|
Si FFMpeg est installé sur votre machine, il est accompagné d'un
|
||||||
|
lecteur vidéo nommé <code>ffplay</code>. Si FFMpeg est compilé
|
||||||
|
avec le support de SRT (c'est le cas sur la plupart des distributions,
|
||||||
|
sauf cas ci-dessous), il vous suffira d'exécuter :
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<code>
|
||||||
|
ffplay -fflags nobuffer srt://{{.Cfg.Hostname}}:{{.Cfg.SRTServerPort}}?streamid=IDENTIFIANT
|
||||||
|
</code>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>MPV</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
MPV supporte officiellement SRT depuis le 16 octobre 2020.
|
||||||
|
Néanmoins, la version stable de MPV est beaucoup plus vieille.
|
||||||
|
Vous devez alors utiliser une version de développement pour
|
||||||
|
pouvoir lire un flux SRT depuis MPV. L'installation se fait
|
||||||
|
depuis <a href="https://mpv.io/installation/"> cette page</a>.
|
||||||
|
Sous Arch Linux, il vous suffit de récupérer le paquet
|
||||||
|
<code>mpv-git</code> dans l'AUR. Pour lire le flux, il suffit
|
||||||
|
d'exécuter :
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<code>
|
||||||
|
mpv srt://{{.Cfg.Hostname}}:{{.Cfg.SRTServerPort}}?streamid=IDENTIFIANT
|
||||||
|
</code>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>VLC Media Player</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Bien que VLC supporte officiellement le protocole SRT,
|
||||||
|
toutes les options ne sont pas encore implémentées,
|
||||||
|
notamment l'option pour choisir son stream.
|
||||||
|
<a href="https://patches.videolan.org/patch/30299/">Un patch</a>
|
||||||
|
a été soumis et est en attente d'acceptation.
|
||||||
|
Une fois le patch accepté, il sera appliqué dans les versions
|
||||||
|
de développement de VLC. Sous Arch Linux, il suffit de récupérer
|
||||||
|
le paquet <code>vlc-git</code> de l'AUR. Avec un VLC à jour,
|
||||||
|
il suffit d'exécuter :
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<code>
|
||||||
|
vlc srt://{{.Cfg.Hostname}}:{{.Cfg.SRTServerPort}}?streamid=IDENTIFIANT
|
||||||
|
</code>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Ou bien d'aller dans Média -> Ouvrir un flux réseau et d'entrer l'URL
|
||||||
|
<code>srt://{{.Cfg.Hostname}}:{{.Cfg.SRTServerPort}}?streamid=IDENTIFIANT</code>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Le protocole n'existe pas ou n'est pas supporté.</h3>
|
||||||
|
<p>
|
||||||
|
La technologie SRT est très récente et n'est pas supportée par
|
||||||
|
les dépôts stables. Ainsi, si vous avez Ubuntu ≤ 20.04 ou
|
||||||
|
Debian ≤ Buster, vous ne pourrez pas utiliser de lecteur vidéo
|
||||||
|
ni même diffuser avec votre machine. Vous devrez vous mettre à
|
||||||
|
jour vers Ubuntu 20.10 ou Debian Bullseye.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2>Mentions légales</h2>
|
<h2>Mentions légales</h2>
|
||||||
<p>
|
<p>
|
||||||
Le service de diffusion vidéo du Crans est un service d'hébergement
|
Le service de diffusion vidéo du Crans est un service d'hébergement
|
||||||
|
Loading…
x
Reference in New Issue
Block a user