opus.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. package track
  2. import (
  3. "github.com/pkg/errors"
  4. "m7s.live/engine/v4/codec"
  5. . "m7s.live/engine/v4/common"
  6. "m7s.live/engine/v4/util"
  7. )
  8. var _ SpesificTrack = (*Opus)(nil)
  9. func NewOpus(stream IStream, stuff ...any) (opus *Opus) {
  10. opus = &Opus{}
  11. opus.CodecID = codec.CodecID_OPUS
  12. opus.SampleSize = 16
  13. opus.Channels = 2
  14. opus.AVCCHead = []byte{(byte(opus.CodecID) << 4) | (1 << 1)}
  15. opus.SetStuff("opus", uint32(48000), byte(111), opus, stuff, stream)
  16. if opus.BytesPool == nil {
  17. opus.BytesPool = make(util.BytesPool, 17)
  18. }
  19. go opus.Attach()
  20. return
  21. }
  22. type Opus struct {
  23. Audio
  24. }
  25. func (opus *Opus) WriteAVCC(ts uint32, frame *util.BLL) error {
  26. return errors.New("opus not support WriteAVCC")
  27. }
  28. func (opus *Opus) WriteRTPFrame(rtpItem *util.ListItem[RTPFrame]) {
  29. frame := &rtpItem.Value
  30. opus.Value.RTP.Push(rtpItem)
  31. if opus.SampleRate != 90000 {
  32. opus.generateTimestamp(uint32(uint64(frame.Timestamp) * 90000 / uint64(opus.SampleRate)))
  33. }
  34. opus.AppendAuBytes(frame.Payload)
  35. opus.Flush()
  36. }
  37. func (opus *Opus) CompleteRTP(value *AVFrame) {
  38. if value.AUList.ByteLength > RTPMTU {
  39. var packets [][][]byte
  40. r := value.AUList.Next.Value.NewReader()
  41. for bufs := r.ReadN(RTPMTU); len(bufs) > 0; bufs = r.ReadN(RTPMTU) {
  42. packets = append(packets, bufs)
  43. }
  44. opus.PacketizeRTP(packets...)
  45. } else {
  46. opus.Audio.CompleteRTP(value)
  47. }
  48. }