From c0c239074838451df6483069d19209fabe22469f Mon Sep 17 00:00:00 2001 From: aler9 <46489434+aler9@users.noreply.github.com> Date: Sat, 21 Nov 2020 12:30:40 +0100 Subject: [PATCH] add new examples --- README.md | 3 + examples/client-publish-options.go | 82 +++++++++++++++++++++++++ examples/client-publish-pause.go | 97 ++++++++++++++++++++++++++++++ examples/client-publish.go | 2 +- examples/client-read-options.go | 44 ++++++++++++++ examples/client-read-pause.go | 6 +- examples/client-read.go | 6 +- 7 files changed, 233 insertions(+), 7 deletions(-) create mode 100644 examples/client-publish-options.go create mode 100644 examples/client-publish-pause.go create mode 100644 examples/client-read-options.go diff --git a/README.md b/README.md index 843135d5..f64367b3 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,11 @@ Features: * [client-query](examples/client-query.go) * [client-read](examples/client-read.go) +* [client-read-options](examples/client-read-options.go) * [client-read-pause](examples/client-read-pause.go) * [client-publish](examples/client-publish.go) +* [client-publish-options](examples/client-publish-options.go) +* [client-publish-pause](examples/client-publish-pause.go) ## Documentation diff --git a/examples/client-publish-options.go b/examples/client-publish-options.go new file mode 100644 index 00000000..04a9b1c0 --- /dev/null +++ b/examples/client-publish-options.go @@ -0,0 +1,82 @@ +// +build ignore + +package main + +import ( + "fmt" + "net" + "time" + + "github.com/aler9/gortsplib" + "github.com/aler9/gortsplib/pkg/rtph264" +) + +// This example shows how to +// * generate RTP/H264 frames from a file with Gstreamer +// * connect to a RTSP server, announce a H264 track +// * write the frames of the track + +func main() { + // open a listener to receive RTP/H264 frames + pc, err := net.ListenPacket("udp4", "127.0.0.1:9000") + if err != nil { + panic(err) + } + defer pc.Close() + + fmt.Println("Waiting for a rtp/h264 stream on port 9000 - you can send one with gstreamer:\n" + + "gst-launch-1.0 filesrc location=video.mp4 ! qtdemux ! video/x-h264" + + " ! h264parse config-interval=1 ! rtph264pay ! udpsink host=127.0.0.1 port=9000") + + // wait for RTP/H264 frames + decoder := rtph264.NewDecoderFromPacketConn(pc) + sps, pps, err := decoder.ReadSPSPPS() + if err != nil { + panic(err) + } + fmt.Println("stream connected") + + // create a H264 track + track, err := gortsplib.NewTrackH264(0, sps, pps) + if err != nil { + panic(err) + } + + // Dialer allows to set additional options + dialer := gortsplib.Dialer{ + // the stream protocol + StreamProtocol: gortsplib.StreamProtocolUDP, + // timeout of read operations + ReadTimeout: 10 * time.Second, + // timeout of write operations + WriteTimeout: 10 * time.Second, + // read buffer count. + // If greater than 1, allows to pass buffers to routines different than the one + // that is reading frames + ReadBufferCount: 1, + } + + // connect to the server and start publishing the track + conn, err := dialer.DialPublish("rtsp://localhost:8554/mystream", + gortsplib.Tracks{track}) + if err != nil { + panic(err) + } + defer conn.Close() + + buf := make([]byte, 2048) + for { + // read frames from the source + n, _, err := pc.ReadFrom(buf) + if err != nil { + break + } + + // write frames to the server + err = conn.WriteFrame(track.Id, gortsplib.StreamTypeRtp, buf[:n]) + if err != nil { + fmt.Printf("connection is closed (%s)\n", err) + break + } + } +} diff --git a/examples/client-publish-pause.go b/examples/client-publish-pause.go new file mode 100644 index 00000000..d206d224 --- /dev/null +++ b/examples/client-publish-pause.go @@ -0,0 +1,97 @@ +// +build ignore + +package main + +import ( + "fmt" + "net" + "time" + + "github.com/aler9/gortsplib" + "github.com/aler9/gortsplib/pkg/rtph264" +) + +// This example shows how to +// * generate RTP/H264 frames from a file with Gstreamer +// * connect to a RTSP server, announce a H264 track +// * write the frames of the track for 5 seconds +// * pause for 5 seconds +// * repeat + +func main() { + // open a listener to receive RTP/H264 frames + pc, err := net.ListenPacket("udp4", "127.0.0.1:9000") + if err != nil { + panic(err) + } + defer pc.Close() + + fmt.Println("Waiting for a rtp/h264 stream on port 9000 - you can send one with gstreamer:\n" + + "gst-launch-1.0 filesrc location=video.mp4 ! qtdemux ! video/x-h264" + + " ! h264parse config-interval=1 ! rtph264pay ! udpsink host=127.0.0.1 port=9000") + + // wait for RTP/H264 frames + decoder := rtph264.NewDecoderFromPacketConn(pc) + sps, pps, err := decoder.ReadSPSPPS() + if err != nil { + panic(err) + } + fmt.Println("stream connected") + + // create a H264 track + track, err := gortsplib.NewTrackH264(0, sps, pps) + if err != nil { + panic(err) + } + + // connect to the server and start publishing the track + conn, err := gortsplib.DialPublish("rtsp://localhost:8554/mystream", + gortsplib.Tracks{track}) + if err != nil { + panic(err) + } + defer conn.Close() + + for { + writerDone := make(chan struct{}) + go func() { + defer close(writerDone) + + buf := make([]byte, 2048) + for { + // read frames from the source + n, _, err := pc.ReadFrom(buf) + if err != nil { + break + } + + // write frames to the server + err = conn.WriteFrame(track.Id, gortsplib.StreamTypeRtp, buf[:n]) + if err != nil { + break + } + } + }() + + // wait + time.Sleep(5 * time.Second) + + // pause + _, err := conn.Pause() + if err != nil { + panic(err) + } + + // join writer + <-writerDone + + // wait + time.Sleep(5 * time.Second) + + // record again + _, err = conn.Record() + if err != nil { + panic(err) + } + } +} diff --git a/examples/client-publish.go b/examples/client-publish.go index cc68050a..2bddb389 100644 --- a/examples/client-publish.go +++ b/examples/client-publish.go @@ -13,7 +13,7 @@ import ( // This example shows how to // * generate RTP/H264 frames from a file with Gstreamer // * connect to a RTSP server, announce a H264 track -// * write the frames with the UDP protocol +// * write the frames of the track func main() { // open a listener to receive RTP/H264 frames diff --git a/examples/client-read-options.go b/examples/client-read-options.go new file mode 100644 index 00000000..3e17f189 --- /dev/null +++ b/examples/client-read-options.go @@ -0,0 +1,44 @@ +// +build ignore + +package main + +import ( + "fmt" + "time" + + "github.com/aler9/gortsplib" +) + +// This example shows how to +// * connect to a RTSP server +// * read all tracks on a path + +func main() { + // Dialer allows to set additional options + dialer := gortsplib.Dialer{ + // the stream protocol + StreamProtocol: gortsplib.StreamProtocolUDP, + // timeout of read operations + ReadTimeout: 10 * time.Second, + // timeout of write operations + WriteTimeout: 10 * time.Second, + // read buffer count. + // If greater than 1, allows to pass buffers to routines different than the one + // that is reading frames + ReadBufferCount: 1, + } + + // connect to the server and start reading all tracks + conn, err := dialer.DialRead("rtsp://localhost:8554/mystream") + if err != nil { + panic(err) + } + defer conn.Close() + + // read frames from the server + readerDone := conn.OnFrame(func(id int, typ gortsplib.StreamType, buf []byte) { + fmt.Printf("frame from track %d, type %v: %v\n", id, typ, buf) + }) + + <-readerDone +} diff --git a/examples/client-read-pause.go b/examples/client-read-pause.go index f8db4ecb..32d3e2ad 100644 --- a/examples/client-read-pause.go +++ b/examples/client-read-pause.go @@ -11,7 +11,7 @@ import ( // This example shows how to // * connect to a RTSP server -// * read all tracks with the UDP protocol for 5 seconds +// * read all tracks for 5 seconds // * pause for 5 seconds // * repeat @@ -25,7 +25,7 @@ func main() { for { // read frames from the server - done := conn.OnFrame(func(id int, typ gortsplib.StreamType, buf []byte) { + readerDone := conn.OnFrame(func(id int, typ gortsplib.StreamType, buf []byte) { fmt.Printf("frame from track %d, type %v: %v\n", id, typ, buf) }) @@ -39,7 +39,7 @@ func main() { } // join reader - <-done + <-readerDone // wait time.Sleep(5 * time.Second) diff --git a/examples/client-read.go b/examples/client-read.go index 90c09658..b2700093 100644 --- a/examples/client-read.go +++ b/examples/client-read.go @@ -10,7 +10,7 @@ import ( // This example shows how to // * connect to a RTSP server -// * read all tracks with the UDP protocol +// * read all tracks on a path func main() { // connect to the server and start reading all tracks @@ -21,9 +21,9 @@ func main() { defer conn.Close() // read frames from the server - done := conn.OnFrame(func(id int, typ gortsplib.StreamType, buf []byte) { + readerDone := conn.OnFrame(func(id int, typ gortsplib.StreamType, buf []byte) { fmt.Printf("frame from track %d, type %v: %v\n", id, typ, buf) }) - <-done + <-readerDone }