github.com/cnotch/ipchub@v1.1.0/av/format/flv/aac_packetizer.go (about)

     1  // Copyright (c) 2019,CAOHONGJU All rights reserved.
     2  // Use of this source code is governed by a MIT-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package flv
     6  
     7  import (
     8  	"time"
     9  
    10  	"github.com/cnotch/ipchub/av/codec"
    11  )
    12  
    13  // in ms, for aac flush the audio
    14  const aacDelay = 100
    15  
    16  type aacPacketizer struct {
    17  	meta         *codec.AudioMeta
    18  	dataTemplate *AudioData
    19  	tagWriter    TagWriter
    20  }
    21  
    22  func NewAacPacketizer(meta *codec.AudioMeta, tagWriter TagWriter) Packetizer {
    23  	ap := &aacPacketizer{
    24  		meta:      meta,
    25  		tagWriter: tagWriter,
    26  	}
    27  	ap.prepareTemplate()
    28  	return ap
    29  }
    30  
    31  func (ap *aacPacketizer) prepareTemplate() {
    32  	audioData := &AudioData{
    33  		SoundFormat:   SoundFormatAAC,
    34  		AACPacketType: AACPacketTypeRawData,
    35  		Body:          nil,
    36  	}
    37  
    38  	switch ap.meta.SampleRate {
    39  	case 5512:
    40  		audioData.SoundRate = SoundRate5512
    41  	case 11025:
    42  		audioData.SoundRate = SoundRate11025
    43  	case 22050:
    44  		audioData.SoundRate = SoundRate22050
    45  	case 44100:
    46  		audioData.SoundRate = SoundRate44100
    47  	default:
    48  		audioData.SoundRate = SoundRate44100
    49  	}
    50  
    51  	if ap.meta.SampleSize == 8 {
    52  		audioData.SoundSize = SoundeSize8bit
    53  	} else {
    54  		audioData.SoundSize = SoundeSize16bit
    55  	}
    56  
    57  	if ap.meta.Channels > 1 {
    58  		audioData.SoundType = SoundTypeStereo
    59  	} else {
    60  		audioData.SoundType = SoundTypeMono
    61  	}
    62  
    63  	ap.dataTemplate = audioData
    64  }
    65  
    66  func (ap *aacPacketizer) PacketizeSequenceHeader() error {
    67  	audioData := *ap.dataTemplate
    68  	audioData.AACPacketType = AACPacketTypeSequenceHeader
    69  	audioData.Body = ap.meta.Sps
    70  	data, _ := audioData.Marshal()
    71  
    72  	tag := &Tag{
    73  		TagType:   TagTypeAudio,
    74  		DataSize:  uint32(len(data)),
    75  		Timestamp: 0,
    76  		StreamID:  0,
    77  		Data:      data,
    78  	}
    79  	return ap.tagWriter.WriteFlvTag(tag)
    80  }
    81  
    82  func (ap *aacPacketizer) Packetize(frame *codec.Frame) error {
    83  	audioData := *ap.dataTemplate
    84  	audioData.Body = frame.Payload
    85  	data, _ := audioData.Marshal()
    86  	pts := frame.Pts / int64(time.Millisecond)
    87  
    88  	tag := &Tag{
    89  		TagType:   TagTypeAudio,
    90  		DataSize:  uint32(len(data)),
    91  		Timestamp: uint32(pts),
    92  		StreamID:  0,
    93  		Data:      data,
    94  	}
    95  	return ap.tagWriter.WriteFlvTag(tag)
    96  }