Skip to content

Commit

Permalink
rtmp: Support Opus writes from internal stream.
Browse files Browse the repository at this point in the history
  • Loading branch information
j0sh committed Jan 17, 2025
1 parent e6b83c2 commit ffcdd28
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
20 changes: 19 additions & 1 deletion internal/protocols/rtmp/from_stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
)

var errNoSupportedCodecsFrom = errors.New(
"the stream doesn't contain any supported codec, which are currently H264, MPEG-4 Audio, MPEG-1/2 Audio")
"the stream doesn't contain any supported codec, which are currently H264, MPEG-4 Audio, MPEG-1/2 Audio, Opus")

func multiplyAndDivide2(v, m, d time.Duration) time.Duration {
secs := v / d
Expand Down Expand Up @@ -179,6 +179,24 @@ func setupAudio(
return audioFormatMPEG1
}

var audioFormatOpus *format.Opus
audioMedia = strea.Desc().FindFormat(&audioFormatOpus)
if audioMedia != nil {
strea.AddReader(
reader,
audioMedia,
audioFormatOpus,
func(u unit.Unit) error {
tunit := u.(*unit.Opus)
if tunit.Packets == nil {
return nil
}
nconn.SetWriteDeadline(time.Now().Add(writeTimeout))
return (*w).WriteOpus(timestampToDuration(tunit.PTS, audioFormatOpus.ClockRate()), tunit.Packets)
})
return audioFormatOpus
}

return nil
}

Expand Down
34 changes: 34 additions & 0 deletions internal/protocols/rtmp/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ func (w *Writer) writeTracks(videoTrack format.Format, audioTrack format.Format)
case *format.MPEG4Audio:
return message.CodecMPEG4Audio

case *format.Opus:
return float64(message.FourCCOpus)

default:
return 0
}
Expand Down Expand Up @@ -162,6 +165,21 @@ func (w *Writer) writeTracks(videoTrack format.Format, audioTrack format.Format)
}
}

if track, ok := audioTrack.(*format.Opus); ok {
err = w.conn.Write(&message.AudioExSequenceStart{
ChunkStreamID: message.AudioChunkStreamID,
MessageStreamID: 0x1000000,
FourCC: message.FourCCOpus,
OpusHeader: &message.OpusIDHeader{
ChannelCount: uint8(track.ChannelCount),
PreSkip: 3840,
},
})
if err != nil {
return err
}
}

return nil
}

Expand Down Expand Up @@ -212,3 +230,19 @@ func (w *Writer) WriteMPEG1Audio(pts time.Duration, h *mpeg1audio.FrameHeader, f
DTS: pts,
})
}

func (w *Writer) WriteOpus(pts time.Duration, packets [][]byte) error {
// only write one packet for now
// additional packets will require self-delimiting framing
// see Appendix B of RFC 6716
for _, packet := range packets {
return w.conn.Write(&message.AudioExCodedFrames{
ChunkStreamID: message.AudioChunkStreamID,
MessageStreamID: 0x1000000,
DTS: pts,
FourCC: message.FourCCOpus,
Payload: packet,
})
}
return nil
}

0 comments on commit ffcdd28

Please sign in to comment.