@@ -27,6 +27,7 @@ import (
2727 "errors"
2828 "github.com/ossrs/go-oryx-lib/aac"
2929 "io"
30+ "strings"
3031)
3132
3233// FLV Tag Type is the type of tag,
@@ -225,12 +226,33 @@ func (v *muxer) Close() error {
225226type AudioFrameTrait uint8
226227
227228const (
228- AudioFrameTraitSequenceHeader AudioFrameTrait = iota // 0 = AAC sequence header
229- AudioFrameTraitRaw // 1 = AAC raw
230- AudioFrameTraitForbidden
229+ // For AAC, the frame trait.
230+ AudioFrameTraitSequenceHeader AudioFrameTrait = 0 // 0 = AAC sequence header
231+ AudioFrameTraitRaw AudioFrameTrait = 1 // 1 = AAC raw
232+
233+ // For Opus, the frame trait, may has more than one traits.
234+ AudioFrameTraitOpusRaw AudioFrameTrait = 0x02 // 2, Has RAW Opus data.
235+ AudioFrameTraitOpusSamplingRate AudioFrameTrait = 0x04 // 4, Has Opus SamplingRate.
236+ AudioFrameTraitOpusAudioLevel AudioFrameTrait = 0x08 // 8, Has audio level data, 16bits.
237+
238+ AudioFrameTraitForbidden AudioFrameTrait = 0xff
231239)
232240
233241func (v AudioFrameTrait ) String () string {
242+ if v > AudioFrameTraitRaw && v < AudioFrameTraitForbidden {
243+ var s []string
244+ if (v & AudioFrameTraitOpusRaw ) == AudioFrameTraitOpusRaw {
245+ s = append (s , "RAW" )
246+ }
247+ if (v & AudioFrameTraitOpusSamplingRate ) == AudioFrameTraitOpusSamplingRate {
248+ s = append (s , "SR" )
249+ }
250+ if (v & AudioFrameTraitOpusAudioLevel ) == AudioFrameTraitOpusAudioLevel {
251+ s = append (s , "AL" )
252+ }
253+ return strings .Join (s , "|" )
254+ }
255+
234256 switch v {
235257 case AudioFrameTraitSequenceHeader :
236258 return "SequenceHeader"
@@ -462,6 +484,7 @@ type AudioFrame struct {
462484 SoundSize AudioSampleBits
463485 SoundType AudioChannels
464486 Trait AudioFrameTrait
487+ AudioLevel uint16
465488 Raw []byte
466489}
467490
@@ -488,7 +511,7 @@ func (v *audioPackager) Encode(frame *AudioFrame) (tag []byte, err error) {
488511 byte (frame .SoundFormat )<< 4 | byte (frame .SoundRate )<< 2 | byte (frame .SoundSize )<< 1 | byte (frame .SoundType ),
489512 }
490513
491- // For Opus, we put the sampling rate after audio tag header ,
514+ // For Opus, we put the sampling rate after trait ,
492515 // so we set the sound rate in audio tag to 0.
493516 if frame .SoundFormat == AudioCodecOpus {
494517 audioTagHeader [0 ] &= 0xf3
@@ -497,7 +520,22 @@ func (v *audioPackager) Encode(frame *AudioFrame) (tag []byte, err error) {
497520 if frame .SoundFormat == AudioCodecAAC {
498521 return append (append (audioTagHeader , byte (frame .Trait )), frame .Raw ... ), nil
499522 } else if frame .SoundFormat == AudioCodecOpus {
500- return append (append (audioTagHeader , byte (frame .SoundRate )), frame .Raw ... ), nil
523+ var b bytes.Buffer
524+
525+ b .Write (audioTagHeader )
526+
527+ b .WriteByte (byte (frame .Trait ))
528+ if (frame .Trait & AudioFrameTraitOpusSamplingRate ) == AudioFrameTraitOpusSamplingRate {
529+ b .WriteByte (byte (frame .SoundRate ))
530+ }
531+ if (frame .Trait & AudioFrameTraitOpusAudioLevel ) == AudioFrameTraitOpusAudioLevel {
532+ b .WriteByte (byte (frame .AudioLevel >> 8 ))
533+ b .WriteByte (byte (frame .AudioLevel ))
534+ }
535+
536+ b .Write (frame .Raw )
537+
538+ return b .Bytes (), nil
501539 } else {
502540 return append (audioTagHeader , frame .Raw ... ), nil
503541 }
@@ -522,9 +560,28 @@ func (v *audioPackager) Decode(tag []byte) (frame *AudioFrame, err error) {
522560 frame .Trait = AudioFrameTrait (tag [1 ])
523561 frame .Raw = tag [2 :]
524562 } else if frame .SoundFormat == AudioCodecOpus {
525- // For Opus, the first UINT8 is sampling rate.
526- frame .SoundRate = AudioSamplingRate (tag [1 ])
527- frame .Raw = tag [2 :]
563+ frame .Trait = AudioFrameTrait (tag [1 ])
564+ p := tag [2 :]
565+
566+ // For Opus, we put sampling rate after trait.
567+ if (frame .Trait & AudioFrameTraitOpusSamplingRate ) == AudioFrameTraitOpusSamplingRate {
568+ if len (p ) < 1 {
569+ return nil , errDataNotEnough
570+ }
571+ frame .SoundRate = AudioSamplingRate (p [0 ])
572+ p = p [1 :]
573+ }
574+
575+ // For Opus, we put audio level after trait.
576+ if (frame .Trait & AudioFrameTraitOpusAudioLevel ) == AudioFrameTraitOpusAudioLevel {
577+ if len (p ) < 2 {
578+ return nil , errDataNotEnough
579+ }
580+ frame .AudioLevel = uint16 (p [0 ])<< 8 | uint16 (p [1 ])
581+ p = p [2 :]
582+ }
583+
584+ frame .Raw = p
528585 } else {
529586 frame .Raw = tag [1 :]
530587 }
0 commit comments