github.com/cnotch/ipchub@v1.1.0/av/format/flv/audiodata.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 "errors"
     8  
     9  // SoundFormat UB [4]
    10  // Format of SoundData. The following values are defined:
    11  //     0 = Linear PCM, platform endian
    12  //     1 = ADPCM
    13  //     2 = MP3
    14  //     3 = Linear PCM, little endian
    15  //     4 = Nellymoser 16 kHz mono
    16  //     5 = Nellymoser 8 kHz mono
    17  //     6 = Nellymoser
    18  //     7 = G.711 A-law logarithmic PCM
    19  //     8 = G.711 mu-law logarithmic PCM
    20  //     9 = reserved
    21  //     10 = AAC
    22  //     11 = Speex
    23  //     14 = MP3 8 kHz
    24  //     15 = Device-specific sound
    25  // Formats 7, 8, 14, and 15 are reserved.
    26  // AAC is supported in Flash Player 9,0,115,0 and higher.
    27  // Speex is supported in Flash Player 10 and higher.
    28  const (
    29  	SoundFormatLinearPCMPlatformEndian         = 0
    30  	SoundFormatADPCM                           = 1
    31  	SoundFormatMP3                             = 2
    32  	SoundFormatLinearPCMLittleEndian           = 3
    33  	SoundFormatNellymoser16kHzMono             = 4
    34  	SoundFormatNellymoser8kHzMono              = 5
    35  	SoundFormatNellymoser                      = 6
    36  	SoundFormatReservedG711AlawLogarithmicPCM  = 7
    37  	SoundFormatReservedG711MuLawLogarithmicPCM = 8
    38  	SoundFormatReserved                        = 9
    39  	SoundFormatAAC                             = 10
    40  	SoundFormatSpeex                           = 11
    41  	SoundFormatReservedMP3Of8kHz               = 14
    42  	SoundFormatReservedDeviceSpecificSound     = 15
    43  	SoundFormatReserved1                       = 16
    44  )
    45  
    46  // SoundFormatName 音频格式名称
    47  func SoundFormatName(codec int32) string {
    48  	switch codec {
    49  	case SoundFormatLinearPCMPlatformEndian:
    50  		return "LinearPCMPlatformEndian"
    51  	case SoundFormatADPCM:
    52  		return "ADPCM"
    53  	case SoundFormatLinearPCMLittleEndian:
    54  		return "LinearPCMLittleEndian"
    55  	case SoundFormatNellymoser16kHzMono:
    56  		return "Nellymoser16kHzMono"
    57  	case SoundFormatNellymoser8kHzMono:
    58  		return "Nellymoser8kHzMono"
    59  	case SoundFormatNellymoser:
    60  		return "Nellymoser"
    61  	case SoundFormatAAC:
    62  		return "AAC"
    63  	case SoundFormatSpeex:
    64  		return "Speex"
    65  	default:
    66  		return ""
    67  	}
    68  }
    69  
    70  // the FLV/RTMP supported audio sample rate.
    71  // Sampling rate. The following values are defined:
    72  // 0 = 5.5 kHz = 5512 Hz
    73  // 1 = 11 kHz = 11025 Hz
    74  // 2 = 22 kHz = 22050 Hz
    75  // 3 = 44 kHz = 44100 Hz
    76  const (
    77  	SoundRate5512     = 0
    78  	SoundRate11025    = 1
    79  	SoundRate22050    = 2
    80  	SoundRate44100    = 3
    81  	SoundRateReserved = 4
    82  )
    83  
    84  // the FLV/RTMP supported audio sample size.
    85  // Size of each audio sample. This parameter only pertains to
    86  // uncompressed formats. Compressed formats always decode
    87  // to 16 bits internally.
    88  // 0 = 8-bit samples
    89  // 1 = 16-bit samples
    90  const (
    91  	SoundeSize8bit     = 0
    92  	SoundeSize16bit    = 1
    93  	SoundeSizeReserved = 2
    94  )
    95  
    96  // the FLV/RTMP supported audio sound type/channel.
    97  // Mono or stereo sound
    98  // 0 = Mono sound
    99  // 1 = Stereo sound
   100  const (
   101  	SoundTypeMono     = 0
   102  	SoundTypeStereo   = 1
   103  	SoundTypeReserved = 2
   104  )
   105  
   106  // flv format
   107  // AACPacketType IF SoundFormat == 10 UI8
   108  // The following values are defined:
   109  //     0 = AAC sequence header
   110  //     1 = AAC raw
   111  const (
   112  	AACPacketTypeSequenceHeader = 0 // 序列头
   113  	AACPacketTypeRawData        = 1 // 原始数据
   114  	AACPacketTypeReserved       = 2
   115  )
   116  
   117  // AudioData flv Tag 中的的音频数据
   118  //
   119  // 对于 SoundFormat == SoundFormatAAC,Body 值:
   120  // IF AACPacketType == AACPacketTypeSequenceHeader
   121  //  AudioSpecificConfig 参考 AAC.RawSPS
   122  // ELSE
   123  //  Raw AAC frame data
   124  type AudioData struct {
   125  	SoundFormat   byte   // 4 bits; 音频编码格式
   126  	SoundRate     byte   // 2 bits; 音频采样率
   127  	SoundSize     byte   // 1 bits; 音频采用大小
   128  	SoundType     byte   // 1 bits; 音频通道类型
   129  	AACPacketType byte   // 8 bits; AAC 编码音频的包类型,仅但 SoundFormat 为 AAC 有效
   130  	Body          []byte // 原始音频
   131  }
   132  
   133  var _ TagData = &AudioData{}
   134  
   135  // Unmarshal .
   136  // Note: Unmarshal not copy the data
   137  func (audioData *AudioData) Unmarshal(data []byte) error {
   138  	if len(data) < 2 {
   139  		return errors.New("data.length < 2")
   140  	}
   141  
   142  	offset := 0
   143  	audioData.SoundFormat = data[offset] >> 4
   144  	audioData.SoundRate = (data[offset] >> 2) & 0x03
   145  	audioData.SoundSize = (data[offset] >> 1) & 0x01
   146  	audioData.SoundType = data[offset] & 0x01
   147  
   148  	offset++
   149  	if audioData.SoundFormat == SoundFormatAAC {
   150  		audioData.AACPacketType = data[offset]
   151  		offset++
   152  	}
   153  	audioData.Body = data[offset:]
   154  
   155  	return nil
   156  }
   157  
   158  // MarshalSize .
   159  func (audioData *AudioData) MarshalSize() int {
   160  	return 2 + len(audioData.Body)
   161  }
   162  
   163  // Marshal .
   164  func (audioData *AudioData) Marshal() ([]byte, error) {
   165  	buff := make([]byte, audioData.MarshalSize())
   166  	offset := 0
   167  	buff[offset] = (audioData.SoundFormat << 4) |
   168  		((audioData.SoundRate & 0x03) << 2) |
   169  		((audioData.SoundSize & 0x01) << 1) |
   170  		(audioData.SoundType & 0x01)
   171  
   172  	offset++
   173  	if audioData.SoundFormat == SoundFormatAAC {
   174  		buff[offset] = audioData.AACPacketType
   175  		offset++
   176  	}
   177  
   178  	offset += copy(buff[offset:], audioData.Body)
   179  
   180  	return buff[:offset], nil
   181  }