Skip to content

Commit 7a6665d

Browse files
committed
Opus support audio-level
1 parent d70f922 commit 7a6665d

File tree

1 file changed

+65
-8
lines changed

1 file changed

+65
-8
lines changed

flv/flv.go

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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 {
225226
type AudioFrameTrait uint8
226227

227228
const (
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

233241
func (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

Comments
 (0)