Skip to content

Commit

Permalink
[feat! apps/stream-whip]: Audio (+Video as well) streaming
Browse files Browse the repository at this point in the history
  • Loading branch information
dehwyy committed Jan 21, 2025
1 parent 25d09fd commit 4cf3724
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 19 deletions.
1 change: 1 addition & 0 deletions apps/stream_whip/cmd/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ <h3> ICE Connection States </h3>

window.doWHEP = () => {
peerConnection.addTransceiver('video', { direction: 'recvonly' })
peerConnection.addTransceiver('audio', { direction: 'recvonly' })

peerConnection.ontrack = function (event) {
document.getElementById('videoPlayer').srcObject = event.streams[0]
Expand Down
76 changes: 57 additions & 19 deletions apps/stream_whip/internal/server/routers/whip-whep.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import (

"github.com/dehwyy/mugen/libraries/go/logg"
"github.com/gin-gonic/gin"
"github.com/pion/interceptor"
"github.com/pion/interceptor/pkg/intervalpli"
"github.com/pion/webrtc/v4"
)

Expand All @@ -19,6 +17,7 @@ const (

var (
videoTrack *webrtc.TrackLocalStaticRTP
audioTrack *webrtc.TrackLocalStaticRTP

peerConnectionConfiguration = webrtc.Configuration{
ICEServers: []webrtc.ICEServer{
Expand All @@ -43,6 +42,12 @@ func (r *WhipWhepRouter) RegisterRoutes(baseRouter *gin.RouterGroup) {
}, "video", "pion"); err != nil {
panic(err)
}

if audioTrack, err = webrtc.NewTrackLocalStaticRTP(webrtc.RTPCodecCapability{
MimeType: webrtc.MimeTypeOpus,
}, "audio", "pion"); err != nil {
panic(err)
}
}

func (r *WhipWhepRouter) handleWhip(ctx *gin.Context) {

Check failure on line 53 in apps/stream_whip/internal/server/routers/whip-whep.go

View workflow job for this annotation

GitHub Actions / golangci-lint (/home/runner/work/mugen/mugen/apps/stream_whip)

empty-lines: extra empty line at the end of a block (revive)
Expand All @@ -62,39 +67,56 @@ func (r *WhipWhepRouter) handleWhip(ctx *gin.Context) {
panic(err)
}

interceptorRegistry := &interceptor.Registry{}
r.log.Info().Msg(string(offer))

intervalPliFactory, err := intervalpli.NewReceiverInterceptor()
if err != nil {
panic(err)
}
interceptorRegistry.Add(intervalPliFactory)

if err = webrtc.RegisterDefaultInterceptors(mediaEngine, interceptorRegistry); err != nil {
if err = mediaEngine.RegisterCodec(webrtc.RTPCodecParameters{
RTPCodecCapability: webrtc.RTPCodecCapability{
MimeType: webrtc.MimeTypeOpus, ClockRate: 48000, Channels: 2, SDPFmtpLine: "", RTCPFeedback: nil,
},
PayloadType: 111,
}, webrtc.RTPCodecTypeAudio); err != nil {
panic(err)
}

api := webrtc.NewAPI(webrtc.WithMediaEngine(mediaEngine), webrtc.WithInterceptorRegistry(interceptorRegistry))
api := webrtc.NewAPI(webrtc.WithMediaEngine(mediaEngine))

peerConnection, err := api.NewPeerConnection(peerConnectionConfiguration)
if err != nil {
panic(err)
}

// Allow us to receive 1 video trac
if _, err = peerConnection.AddTransceiverFromKind(webrtc.RTPCodecTypeVideo); err != nil {
panic(err)
}

if _, err = peerConnection.AddTransceiverFromKind(webrtc.RTPCodecTypeAudio); err != nil {
panic(err)
}

peerConnection.OnTrack(func(track *webrtc.TrackRemote, receiver *webrtc.RTPReceiver) { //nolint: revive
for {

Check failure on line 98 in apps/stream_whip/internal/server/routers/whip-whep.go

View workflow job for this annotation

GitHub Actions / golangci-lint (/home/runner/work/mugen/mugen/apps/stream_whip)

empty-lines: extra empty line at the end of a block (revive)
// r.log.Debug().Msgf("track: %+v", track)
pkt, _, err := track.ReadRTP()

Check failure on line 100 in apps/stream_whip/internal/server/routers/whip-whep.go

View workflow job for this annotation

GitHub Actions / golangci-lint (/home/runner/work/mugen/mugen/apps/stream_whip)

shadow: declaration of "err" shadows declaration at line 54 (govet)
if err != nil {
panic(err)
}

if err = videoTrack.WriteRTP(pkt); err != nil {
panic(err)
switch pkt.PayloadType {
// video
case 96:

if err = videoTrack.WriteRTP(pkt); err != nil {
panic(err)
}

case 111:

if err = audioTrack.WriteRTP(pkt); err != nil {
panic(err)
}
}

}

Check failure on line 120 in apps/stream_whip/internal/server/routers/whip-whep.go

View workflow job for this annotation

GitHub Actions / golangci-lint (/home/runner/work/mugen/mugen/apps/stream_whip)

unnecessary trailing newline (whitespace)
})
// !
Expand All @@ -112,6 +134,7 @@ func (r *WhipWhepRouter) handleWhip(ctx *gin.Context) {
panic(err)
}

// Create channel that is blocked until ICE Gathering is complete
gatherComplete := webrtc.GatheringCompletePromise(peerConnection)

// Create answer
Expand All @@ -125,8 +148,8 @@ func (r *WhipWhepRouter) handleWhip(ctx *gin.Context) {
<-gatherComplete

ctx.Header("Location", "/whip")
ctx.Status(http.StatusCreated)
fmt.Fprintf(ctx.Writer, peerConnection.LocalDescription().SDP)
ctx.String(http.StatusCreated, "%s", peerConnection.LocalDescription().SDP)

}

Check failure on line 153 in apps/stream_whip/internal/server/routers/whip-whep.go

View workflow job for this annotation

GitHub Actions / golangci-lint (/home/runner/work/mugen/mugen/apps/stream_whip)

unnecessary trailing newline (whitespace)

func (r *WhipWhepRouter) handleWhep(ctx *gin.Context) {

Check failure on line 155 in apps/stream_whip/internal/server/routers/whip-whep.go

View workflow job for this annotation

GitHub Actions / golangci-lint (/home/runner/work/mugen/mugen/apps/stream_whip)

empty-lines: extra empty line at the end of a block (revive)
Expand All @@ -142,15 +165,29 @@ func (r *WhipWhepRouter) handleWhep(ctx *gin.Context) {
}

// Add Video Track that is being written to from WHIP Session
rtpSender, err := peerConnection.AddTrack(videoTrack)
rtpVideoSender, err := peerConnection.AddTrack(videoTrack)
if err != nil {
panic(err)
}

go func() {
rtcpBuf := make([]byte, 1500)
for {
if _, _, rtcpErr := rtpVideoSender.Read(rtcpBuf); rtcpErr != nil {
return
}
}
}()

rtpAudioSender, err := peerConnection.AddTrack(audioTrack)
if err != nil {
panic(err)
}

go func() {
rtcpBuf := make([]byte, 1500)
for {
if _, _, rtcpErr := rtpSender.Read(rtcpBuf); rtcpErr != nil {
if _, _, rtcpErr := rtpAudioSender.Read(rtcpBuf); rtcpErr != nil {
return
}
}
Expand All @@ -172,6 +209,7 @@ func (r *WhipWhepRouter) handleWhep(ctx *gin.Context) {

gatherComplete := webrtc.GatheringCompletePromise(peerConnection)

// Create answer
answer, err := peerConnection.CreateAnswer(nil)
if err != nil {
panic(err)
Expand All @@ -182,6 +220,6 @@ func (r *WhipWhepRouter) handleWhep(ctx *gin.Context) {
<-gatherComplete

ctx.Header("Location", "/whep")
ctx.Status(http.StatusCreated)
fmt.Fprintf(ctx.Writer, peerConnection.LocalDescription().SDP)
ctx.String(http.StatusAccepted, "%s", peerConnection.LocalDescription().SDP)

}

Check failure on line 225 in apps/stream_whip/internal/server/routers/whip-whep.go

View workflow job for this annotation

GitHub Actions / golangci-lint (/home/runner/work/mugen/mugen/apps/stream_whip)

unnecessary trailing newline (whitespace)

0 comments on commit 4cf3724

Please sign in to comment.